PDA

View Full Version : iPhone Switch



charleshimmer
18 Jun 2011, 9:21 AM
Hey guys. I had to build a form with lots of on and off switches and I liked the look of the iPhone's on / off switch so I extended the RadioGroup element to make an iPhoneSwitch.

Feel free to use it as you please. If you have any suggestions of how it can be improved let me know. I'm using CSS3 transitions for the animation of the switch.

Here is a picture of how it looks. Sorry, no live demo yet.

26629

Here is the CSS.



.x-iphone-switch img{background: url(../images/iphone_switch.png) no-repeat 0 0;width:94px;height:27px;cursor:pointer; -webkit-transition: background-position .25s linear;-moz-transition: background-position .25s linear;-o-transition: background-position .25s linear;transition: background-position .25s linear;}
.x-iphone-switch.off img{background-position: -53px 0;}
.x-iphone-switch-label{margin-top:2px;}


Here is the iphone_switch.png and the container image.
2663026631

Here is the actual plugin. I've only tested this in ExtJS 3.3.1. Should be easily portable to other versions.



// create namespace for plugins
Ext.namespace('Ext.ux.plugins');

/**
* Ext.ux.plugins.iPhoneSwitch plugin for Ext.form.Radio
*
* @author Chalres Himmer
* @stardate January 25, 2010
*
* @class Ext.ux.plugins.IphoneSwitch
* @extends Ext.form.RadioGroup
*/

Ext.ux.plugins.iPhoneSwitch = Ext.extend(Ext.form.RadioGroup, {

initComponent:function() {

this.addEvents(
'changed'
);

// private hard coded config
var config = {
items:[
{boxLabel: 'On', name: this.name + '-on', inputValue: true, hidden: true},
{boxLabel: 'Off', name: this.name + '-off', inputValue: false, hidden: true, checked: true}
]
};

Ext.apply(this, config);

// call parent initComponent
Ext.ux.plugins.iPhoneSwitch.superclass.initComponent.call(this);

}, // end of function initComponent

onRender: function(ct, position){

Ext.ux.plugins.iPhoneSwitch.superclass.onRender.call(this, ct, position);

var statusClass = (this.getValue().inputValue == 0) ? ' off':'on';

this.switch = new Ext.Element(Ext.DomHelper.append(this.el, {
tag: 'div',
cls: 'x-iphone-switch' + statusClass,
children:[{
tag: 'img',
src: 'static/images/iphone_switch_container.gif'
}]
}));

// add class to label so we can target it using css
this.switch.parent('div.x-form-element').prev('label').addClass('x-iphone-switch-label');

// add listener
this.switch.on('click', this.onClick, this, {delegate:'img'});
},

onClick: function(e, t){
e.stopEvent();

// change the value of the form
this.setValue('toggle');

// fire event
this.fireEvent("afterchange", this, this.value);
},

/**
* @param {string} val
*
* We are overriding the default behavior of the setValue method
* so we can use the form's bulk setValues method and just pass in
* either true, false, on, off, or toggle.
*/
setValue: function(val){

// see if we are toggling the switch's state
if(val === 'toggle'){
val = (this.getValue().inputValue) ? false:true;
}
// if val is 'on', true, or 1 turn this on the switch
else if([1,'true',true,'on'].indexOf(val) !== -1){
val = true;
console.log(this.switch);
}
// then we must be turning the switch off
else if([0,'false',false,'off'].indexOf(val) !== -1){
val = false;
this.switch.removeClass('on').addClass('off');
}
// unrecongized value
else{
console.log('Unknown value for iPhoneSwitch: ' + val);
}

// set the internal radio button's value
this.items.first().setValue(val);

// animate image
this.animateSwitch(val);
},

/**
* @param {string} - Possible values are true or false
*
* This animates the switching of the switch use CSS3 animations
*/
animateSwitch: function(status){

if(status){
this.switch.removeClass('off').addClass('on');
}else{
this.switch.removeClass('on').addClass('off');
}
}
});

// register xtype
Ext.reg('iphoneswitch', Ext.ux.plugins.iPhoneSwitch);

// end of file

Andrew Peacock
22 Jun 2011, 8:26 AM
Charles,
Thanks very much. I've just come across one of these UI components in Growl for Windows, and I thought I'd see if there was one for ExtJS. Excellent implementation.

Two things:
1) If you could provide some sample code for it in use, that would be great. I kept getting an error at the line:


this.switch.parent('div.x-form-element').prev('label').addClass('x-iphone-switch-label');

Something to do with the elements around the switch, but I've not used radio group before in ExtJS so i struggled to get it working. Eventually I took the radiogroup official example, and inserted the iphone switch as a new item in on one of the groups, and it worked fine.

2). Running on IE7 (corporate environment) I had to change this.switch to this.switcher globally, as switch I guess is a reserved word.

Great work though - thanks for saving me a lot of time.

Regards,
Andy

charleshimmer
22 Jun 2011, 9:20 AM
Glad you found it useful. I'll post a code example of how to use it once I get back to
my computer. That error sounds like it couldn't find the label. Did you define a fieldLabel? Also if you're using IE 7 you can use a JavaScript animation to get the same effect as the CSS3 transition. That's how I originally had it.

Andrew Peacock
22 Jun 2011, 12:35 PM
Hi Charles,
The lack of field label was exactly the problem, and that's the bit that took me a while to find out, due to my unfamiliarity with radio groups.
Regards,
Andy

charleshimmer
24 Jun 2011, 5:38 AM
So here is some sample code of how I use it. I'm using the xtype method. You just it just like you would a radiogroup.



var form = new Ext.form.FormPanel({
items:[{
xtype:'iphoneswitch',
fieldLabel: 'Video Thumbnails',
name:'videoThumbnailsEnabled'
}]
});

priya gupta
15 Dec 2011, 9:30 PM
how to use it in sencha touch. please help!!

charleshimmer
16 Dec 2011, 5:35 PM
I have yet to use Sencha touch so I unfortunately would not be able to help you here. Maybe someone with experience with Sencha Touch would be able to help you.

anandsivaji
24 Jun 2012, 5:26 AM
I am getting this error when I am using this iphone switch
this.switch.parent("div.x-form-element") is null

I have also attached the code

Ext.onReady(function() {

window.extViewport = new Ext.Viewport({
layout : "fit",
items : {
activeTab : 0,
xtype : 'tabpanel',
itemId : 'tabpanel',
cls : 'sub-tab-panel',
region : 'center',
items : [{
xtype : 'container',
itemId : 'redemptioncentercontainer',
title : 'Redemptions',
layout : {
type : 'hbox',
align : 'stretch'
},
items : [{
xtype:'sample.app.timeclock.TimeClock',
}]

},{
xtype : 'container',
itemId : 'switchcentercontainer',
title : 'Switch',
layout : {
type : 'hbox',
align : 'stretch'
},
items : [{
xtype:'iphoneswitch',
fieldLabel: 'Video Thumbnails',
name:'videoThumbnailsEnabled'
}]
}]
}
});
})

Please help me to get out of this

ttbgwt
4 Oct 2012, 2:02 PM
Do you have the code for the javascript animation to get the same effect as the CSS3 transition?


Glad you found it useful. I'll post a code example of how to use it once I get back to
my computer. That error sounds like it couldn't find the label. Did you define a fieldLabel? Also if you're using IE 7 you can use a JavaScript animation to get the same effect as the CSS3 transition. That's how I originally had it.

Manoj Solanki
5 Nov 2012, 4:21 AM
Hi,

Can u please post an small sample code for iPhone like switch. I got error "xtype not defined".