PDA

View Full Version : Simple ToggleField example



karieanis
13 Dec 2010, 7:28 PM
Hi all,

Just wrote a toggle form field class for one of the projects i'm working on and thought i'd share the love. Here's the code for the togglefield base class, and a locking class extended from it to demonstrate how it can be used.



Ext.namespace('Ext.ux');

/**
* @class Ext.ux.ToggleField
* @extends Ext.form.Field
* @author Jeremy Rayner
*
* ToggleField class definition. Specific types of togglable fields should extend from this
* class.
*
* @constructor
* Create a new toggle field
* @param {Object} config Configuration options
* @xtype togglefield
*/
Ext.ux.ToggleField = Ext.extend(Ext.form.Field,
{
// private
defaultAutoCreate: {tag: 'input', type: 'hidden', autocomplete: 'off'},
/**
* @cfg {String} field1Class First css class which is used when toggling
*/
/**
* @cfg {String} field2Class Second css class which is used when toggling
*/
// private
initComponent: function()
{
Ext.ux.ToggleField.superclass.initComponent.call(this);
this.addEvents(
/**
* @event beforetoggle
* Fires before toggling occurs. Return false to prevent toggling.
* @param {Ext.ux.ToggleField} field This togglefield
* @param {String} oldCls The css class being toggled from
* @param {String} newCls The css class which is being toggled to
*/
'beforetoggle',
/**
* @event toggle
* Fires when it is okay to toggle. Child classes should handle changes in the UI as
* required.
* @param {Ext.Element} icon The icon element
* @param {String} oldCls The css class being toggled from
*/
'toggle'
);
},
// private
onRender: function(ct, position)
{
Ext.ux.ToggleField.superclass.onRender.call(this, ct, position);

this.wrap = this.el.wrap({tag: 'span', cls: 'x-form-field-wrap'});
var icon = Ext.DomHelper.append(this.wrap, {
tag: 'img',
src: Ext.BLANK_IMAGE_URL,
cls: this.getIconCls(this.value)
});

this.icon = Ext.get(icon);
this.icon.on('click', this.toggle, this);
},
/**
* Determine which class is the old class, and which class is the new class. After determining this,
* fire the appropriate events to allow child classes to handle UI changes.
* @param {Ext.EventObject} e
* @param {Html} target
* @param {Object} o
*/
toggle: function(e, target, o)
{
var icon = this.icon,
oldCls,
newCls;

if(icon.hasClass(this.field1Class)){
oldCls = this.field1Class;
newCls = this.field2Class;
}
else if(icon.hasClass(this.field2Class)){
oldCls = this.field2Class;
newCls = this.field1Class;
}

if(this.fireEvent('beforetoggle', this, oldCls, newCls) !== false)
{
this.fireEvent('toggle', this.icon, oldCls);
}
},
// private
beforeDestroy: function()
{
Ext.ux.ToggleField.superclass.beforeDestroy.apply(this, arguments);
Ext.destroy(this.wrap, this.icon);
},
/**
* Abstract function to be implemented in child classes
*/
getIconCls: Ext.emptyFn
});

Ext.reg('togglefield', Ext.ux.ToggleField);

/**
* @class Ext.ux.LockField
* @extends Ext.ux.ToggleField
* @author Jeremy Rayner
*
* Create a new lock field.
*
* @constructor
* Create a new LockField
* @param {Object} config Configuration options
* @xtype lockfield
*/
Ext.ux.LockField = Ext.extend(Iedex.Components.ToggleField, function()
{
// private
var LOCKED = 1,
UNLOCKED = 0,
LOCKED_TIP = "This item is locked",
UNLOCKED_TIP = "This item is not locked";

// private
function getTooltip(value)
{
if(value == UNLOCKED) {
return UNLOCKED_TIP;
}
else if(value == LOCKED) {
return LOCKED_TIP;
}
}

// public methods
return {
value: UNLOCKED,
field1Class: 'x-icon-locked',
field2Class: 'x-icon-unlocked',
// private
initComponent: function()
{
Ext.ux.LockField.superclass.initComponent.call(this);
this.addEvents(
/**
* @event locked
* Fires when this field is toggle to locked
* @param {Ext.ux.LockField} field
*/
'locked',
/**
* @event unlocked
* Fired when this field is toggled to unlocked
* @param {Ext.ux.LockField} field
*/
'unlocked'
);
},
onRender: function(ct, position)
{
Ext.ux.LockField.superclass.onRender.call(this, ct, position);

this.icon.addClass('x-form-lockfield');
this.icon.dom.qtip = getTooltip(this.value);
this.on('toggle', this.toggleLock, this);
},
/**
* @param {Ext.Element} toggleEl The icon element
* @param {String} oldCls The css class which is being toggled from
*/
toggleLock: function(toggleEl, oldCls)
{
var newValue,
event;

if(oldCls == this.field1Class) {
newValue = UNLOCKED,
event = 'unlocked';
}
else if(oldCls == this.field2Class) {
newValue = LOCKED,
event = 'locked';
}

this.setValue(newValue);
this.fireEvent(event, this);

toggleEl.replaceClass(oldCls, this.getIconCls(newValue));
toggleEl.dom.qtip = getTooltip(newValue);
},
/**
* Get the css class for the passed value
* @param {Number} value
* @return {String} cls The css class associated with the value
*/
getIconCls: function(value)
{
if(value == UNLOCKED) {
return this.field2Class;
}
else if(value == LOCKED) {
return this.field1Class;
}
},
beforeDestroy: function()
{
this.removeListener('toggle', this.toggleLock, this);
Ext.ux.LockField.superclass.beforeDestroy.apply(this, arguments);
}
};
}());

Ext.reg('lockfield', Ext.ux.LockField);
CSS for Ext.ux.LockField...


.x-form-lockfield{background-repeat: no-repeat; height: 16px; width: 16px; cursor: pointer;}
.x-icon-locked{background: url('../images/icons/lock.png');}
.x-icon-unlocked{background: url('../images/icons/lock_open.png');}
Enjoy.

hitekshu
13 Dec 2010, 10:36 PM
Hi, i was trying your class but couldnt find this Iedex.Components.ToggleField. Do i need something more to implement this?

Thanks,
Hitekshu



Hi all,

Just wrote a toggle form field class for one of the projects i'm working on and thought i'd share the love. Here's the code for the togglefield base class, and a locking class extended from it to demonstrate how it can be used.



Ext.namespace('Ext.ux');

/**
* @class Ext.ux.ToggleField
* @extends Ext.form.Field
* @author Jeremy Rayner
*
* ToggleField class definition. Specific types of togglable fields should extend from this
* class.
*
* @constructor
* Create a new toggle field
* @param {Object} config Configuration options
* @xtype togglefield
*/
Ext.ux.ToggleField = Ext.extend(Ext.form.Field,
{
// private
defaultAutoCreate: {tag: 'input', type: 'hidden', autocomplete: 'off'},
/**
* @cfg {String} field1Class First css class which is used when toggling
*/
/**
* @cfg {String} field2Class Second css class which is used when toggling
*/
// private
initComponent: function()
{
Ext.ux.ToggleField.superclass.initComponent.call(this);
this.addEvents(
/**
* @event beforetoggle
* Fires before toggling occurs. Return false to prevent toggling.
* @param {Ext.ux.ToggleField} field This togglefield
* @param {String} oldCls The css class being toggled from
* @param {String} newCls The css class which is being toggled to
*/
'beforetoggle',
/**
* @event toggle
* Fires when it is okay to toggle. Child classes should handle changes in the UI as
* required.
* @param {Ext.Element} icon The icon element
* @param {String} oldCls The css class being toggled from
*/
'toggle'
);
},
// private
onRender: function(ct, position)
{
Ext.ux.ToggleField.superclass.onRender.call(this, ct, position);

this.wrap = this.el.wrap({tag: 'span', cls: 'x-form-field-wrap'});
var icon = Ext.DomHelper.append(this.wrap, {
tag: 'img',
src: Ext.BLANK_IMAGE_URL,
cls: this.getIconCls(this.value)
});

this.icon = Ext.get(icon);
this.icon.on('click', this.toggle, this);
},
/**
* Determine which class is the old class, and which class is the new class. After determining this,
* fire the appropriate events to allow child classes to handle UI changes.
* @param {Ext.EventObject} e
* @param {Html} target
* @param {Object} o
*/
toggle: function(e, target, o)
{
var icon = this.icon,
oldCls,
newCls;

if(icon.hasClass(this.field1Class)){
oldCls = this.field1Class;
newCls = this.field2Class;
}
else if(icon.hasClass(this.field2Class)){
oldCls = this.field2Class;
newCls = this.field1Class;
}

if(this.fireEvent('beforetoggle', this, oldCls, newCls) !== false)
{
this.fireEvent('toggle', this.icon, oldCls);
}
},
// private
beforeDestroy: function()
{
Ext.ux.ToggleField.superclass.beforeDestroy.apply(this, arguments);
Ext.destroy(this.wrap, this.icon);
},
/**
* Abstract function to be implemented in child classes
*/
getIconCls: Ext.emptyFn
});

Ext.reg('togglefield', Ext.ux.ToggleField);

/**
* @class Ext.ux.LockField
* @extends Iedex.Components.ToggleField
* @author Jeremy Rayner
*
* Create a new lock field.
*
* @constructor
* Create a new LockField
* @param {Object} config Configuration options
* @xtype lockfield
*/
Ext.ux.LockField = Ext.extend(Iedex.Components.ToggleField, function()
{
// private
var LOCKED = 1,
UNLOCKED = 0,
LOCKED_TIP = "This item is locked",
UNLOCKED_TIP = "This item is not locked";

// private
function getTooltip(value)
{
if(value == UNLOCKED) {
return UNLOCKED_TIP;
}
else if(value == LOCKED) {
return LOCKED_TIP;
}
}

// public methods
return {
value: UNLOCKED,
field1Class: 'x-icon-locked',
field2Class: 'x-icon-unlocked',
// private
initComponent: function()
{
Ext.ux.LockField.superclass.call(this);
this.addEvents(
/**
* @event locked
* Fires when this field is toggle to locked
* @param {Ext.ux.LockField} field
*/
'locked',
/**
* @event unlocked
* Fired when this field is toggled to unlocked
* @param {Ext.ux.LockField} field
*/
'unlocked'
);
},
onRender: function(ct, position)
{
Ext.ux.LockField.superclass.onRender.call(this, ct, position);

this.icon.addClass('x-form-lockfield');
this.icon.dom.qtip = getTooltip(this.value);
this.on('toggle', this.toggleLock, this);
},
/**
* @param {Ext.Element} toggleEl The icon element
* @param {String} oldCls The css class which is being toggled from
*/
toggleLock: function(toggleEl, oldCls)
{
var newValue,
event;

if(oldCls == this.field1Class) {
newValue = UNLOCKED,
event = 'unlocked';
}
else if(oldCls == this.field2Class) {
newValue = LOCKED,
event = 'locked';
}

this.setValue(newValue);
this.fireEvent(event, this);

toggleEl.replaceClass(oldCls, this.getIconCls(newValue));
toggleEl.dom.qtip = getTooltip(newValue);
},
/**
* Get the css class for the passed value
* @param {Number} value
* @return {String} cls The css class associated with the value
*/
getIconCls: function(value)
{
if(value == UNLOCKED) {
return this.field2Class;
}
else if(value == LOCKED) {
return this.field1Class;
}
},
beforeDestroy: function()
{
this.removeListener('toggle', this.toggleLock, this);
Ext.ux.LockField.superclass.beforeDestroy.apply(this, arguments);
}
};
}());

Ext.reg('lockfield', Ext.ux.LockField);
CSS for Ext.ux.LockField...


.x-form-lockfield{background-repeat: no-repeat; height: 16px; width: 16px; cursor: pointer;}
.x-icon-locked{background: url('../images/icons/lock.png');}
.x-icon-unlocked{background: url('../images/icons/lock_open.png');}
Enjoy.

karieanis
14 Dec 2010, 4:05 AM
Iedex.Components is the namespace I use in the project i'm working on... I ran a search and replace to change them all to Ext.ux... must have missed one. LockField was also missing the chaining initComponent call to ToggleField. That'll teach me to do a search and replace and not check it after it's done :P

The code has been updated (I haven't tested it, as it's late here...) and should now be ok.

hitekshu
14 Dec 2010, 8:47 PM
Hi,

Thanks for clarifying it. Can you give an example of how to use it and how does it look?

Thanks,
Hitekshu



Iedex.Components is the namespace I use in the project i'm working on... I ran a search and replace to change them all to Ext.ux... must have missed one. LockField was also missing the chaining initComponent call to ToggleField. That'll teach me to do a search and replace and not check it after it's done :P

The code has been updated (I haven't tested it, as it's late here...) and should now be ok.

karieanis
15 Dec 2010, 5:02 PM
<span id="lockfield-target"></span>

<script type="text/javascript">
Ext.onReady(function()
{
new Iedex.Components.LockField({
name: 'lockfield',
value: 0,
renderTo: 'lockfield-target'
});
});
</script>Here's an image of how i'm using LockField:
23848

In this scenario, LockField is used to describe with the associated form items are editable or not to the end user. You could use events to affect immediate UI changes if you wanted.