yhwh
31 Mar 2010, 1:08 AM
Hello,
I was using the Ext.ux.ToolbarReorderer for fun on extjs 3.1 (it works!). And I see that there is no support for removing buttons dynamically.
First reorderer.js
/*!
* Ext JS Library 3.2.0
* Copyright(c) 2006-2010 Ext JS, LLC
* licensing@extjs.com
* http://www.extjs.com/license
*/
/**
* @class Ext.ux.Reorderer
* @extends Object
* Generic base class for handling reordering of items. This base class must be extended to provide the
* actual reordering functionality - the base class just sets up events and abstract logic functions.
* It will fire events and set defaults, deferring the actual reordering to a doReorder implementation.
* See Ext.ux.TabReorderer for an example.
*/
Ext.ux.Reorderer = Ext.extend(Object, {
/**
* @property defaults
* @type Object
* Object containing default values for plugin configuration details. These can be overridden when
* constructing the plugin
*/
defaults: {
/**
* @cfg animate
* @type Boolean
* If set to true, the rearranging of the toolbar items is animated
*/
animate: true,
/**
* @cfg animationDuration
* @type Number
* The duration of the animation used to move other toolbar items out of the way
*/
animationDuration: 0.2,
/**
* @cfg defaultReorderable
* @type Boolean
* True to make every toolbar draggable unless reorderable is specifically set to false.
* This defaults to false
*/
defaultReorderable: false
},
/**
* Creates the plugin instance, applies defaults
* @constructor
* @param {Object} config Optional config object
*/
constructor: function(config) {
Ext.apply(this, config || {}, this.defaults);
},
/**
* Initializes the plugin, stores a reference to the target
* @param {Mixed} target The target component which contains the reorderable items
*/
init: function(target) {
/**
* @property target
* @type Ext.Component
* Reference to the target component which contains the reorderable items
*/
this.target = target;
this.initEvents();
var items = this.getItems();
for (var i=0; i < items.length; i++) {
this.createIfReorderable(items[i]);
}
},
/**
* Reorders the items in the target component according to the given mapping object. Example:
* this.reorder({
* 1: 5,
* 3: 2
* });
* Would move the item at index 1 to index 5, and the item at index 3 to index 2
* @param {Object} mappings Object containing current item index as key and new index as property
*/
reorder: function(mappings) {
var target = this.target;
if (target.fireEvent('before-reorder', mappings, target, this) !== false) {
this.doReorder(mappings);
target.fireEvent('reorder', mappings, target, this);
}
},
/**
* Abstract function to perform the actual reordering. This MUST be overridden in a subclass
* @param {Object} mappings Mappings of the old item indexes to new item indexes
*/
doReorder: function(paramName) {
throw new Error("doReorder must be implemented in the Ext.ux.Reorderer subclass");
},
/**
* Should create and return an Ext.dd.DD for the given item. This MUST be overridden in a subclass
* @param {Mixed} item The item to create a DD for. This could be a TabPanel tab, a Toolbar button, etc
* @return {Ext.dd.DD} The DD for the given item
*/
createItemDD: function(item) {
throw new Error("createItemDD must be implemented in the Ext.ux.Reorderer subclass");
},
/**
* Sets up the given Toolbar item as a draggable
* @param {Mixed} button The item to make draggable (usually an Ext.Button instance)
*/
createItemDD: function(button) {
var el = button.getEl(),
id = el.id,
tbar = this.target,
me = this;
button.dd = new Ext.dd.DD(el, undefined, {
isTarget: false
});
button.dd.constrainTo(tbar.getEl());
button.dd.setYConstraint(0, 0, 0);
Ext.apply(button.dd, {
b4StartDrag: function() {
this.startPosition = el.getXY();
//bump up the z index of the button being dragged but keep a reference to the original
this.startZIndex = el.getStyle('zIndex');
el.setStyle('zIndex', 10000);
button.suspendEvents();
},
onDrag: function(e) {
//calculate the button's index within the toolbar and its current midpoint
var buttonX = el.getXY()[0],
deltaX = buttonX - this.startPosition[0],
items = tbar.items.items,
oldIndex = items.indexOf(button),
newIndex;
//find which item in the toolbar the midpoint is currently over
for (var index = 0; index < items.length; index++) {
var item = items[index];
if (item.reorderable && item.id != button.id) {
//find the midpoint of the button
var box = item.getEl().getBox(),
midpoint = (me.buttonXCache[item.id] || box.x) + (box.width / 2),
movedLeft = oldIndex > index && deltaX < 0 && buttonX < midpoint,
movedRight = oldIndex < index && deltaX > 0 && (buttonX + el.getWidth()) > midpoint;
if (movedLeft || movedRight) {
me[movedLeft ? 'onMovedLeft' : 'onMovedRight'](button, index, oldIndex);
break;
}
}
}
},
/**
* After the drag has been completed, make sure the button being dragged makes it back to
* the correct location and resets its z index
*/
endDrag: function() {
//we need to update the cache here for cases where the button was dragged but its
//position in the toolbar did not change
me.updateButtonXCache();
el.moveTo(me.buttonXCache[button.id], undefined, {
duration: me.animationDuration,
scope : this,
callback: function() {
button.resumeEvents();
tbar.fireEvent('reordered', button, tbar);
}
});
el.setStyle('zIndex', this.startZIndex);
}
});
},
/**
* @private
* Creates a DD instance for a given item if it is reorderable
* @param {Mixed} item The item
*/
createIfReorderable: function(item) {
if (this.defaultReorderable && item.reorderable == undefined) item.reorderable = true;
if (item.reorderable) {
if (item.rendered) {
this.createItemDD(item);
} else {
item.on('render', this.createItemDD.createDelegate(this, [item]), this, {single: true});
}
}
},
/**
* Returns an array of items which will be made draggable. This defaults to the contents of this.target.items,
* but can be overridden - e.g. for TabPanels
* @return {Array} The array of items which will be made draggable
*/
getItems: function() {
/* override */
return this.target.items ? this.target.items.items:[];
/* end of override */
},
/**
* Adds before-reorder and reorder events to the target component
*/
initEvents: function() {
this.target.addEvents(
/**
* @event before-reorder
* Fires before a reorder occurs. Return false to cancel
* @param {Object} mappings Mappings of the old item indexes to new item indexes
* @param {Mixed} component The target component
* @param {Ext.ux.TabReorderer} this The plugin instance
*/
'before-reorder',
/**
* @event reorder
* Fires after a reorder has occured.
* @param {Object} mappings Mappings of the old item indexes to the new item indexes
* @param {Mixed} component The target component
* @param {Ext.ux.TabReorderer} this The plugin instance
*/
'reorder'
);
}
});
The only diff is there, and it allows to use empty toolbars.
getItems: function() {
/* override */
return this.target.items ? this.target.items.items:[];
/* end of override */
},
Then toolbar_reorderer.js.
/*!
* Ext JS Library 3.2.0
* Copyright(c) 2006-2010 Ext JS, LLC
* licensing@extjs.com
* http://www.extjs.com/license
*/
/**
* @class Ext.ux.ToolbarReorderer
* @extends Ext.ux.Reorderer
* Plugin which can be attached to any Ext.Toolbar instance. Provides ability to reorder toolbar items
* with drag and drop. Example:
* <pre>
* new Ext.Toolbar({
* plugins: [
* new Ext.ux.ToolbarReorderer({
* defaultReorderable: true
* })
* ],
* items: [
* {text: 'Button 1', reorderable: false},
* {text: 'Button 2'},
* {text: 'Button 3'}
* ]
* });
* </pre>
* In the example above, buttons 2 and 3 will be reorderable via drag and drop. An event named 'reordered'
* is added to the Toolbar, and is fired whenever a reorder has been completed.
*/
Ext.ux.ToolbarReorderer = Ext.extend(Ext.ux.Reorderer, {
/**
* Initializes the plugin, decorates the toolbar with additional functionality
*/
init: function(toolbar) {
/**
* This is used to store the correct x value of each button in the array. We need to use this
* instead of the button's reported x co-ordinate because the buttons are animated when they move -
* if another onDrag is fired while the button is still moving, the comparison x value will be incorrect
*/
this.buttonXCache = {};
toolbar.on({
scope: this,
add : function(toolbar, item) {
this.createIfReorderable(item);
},
/* override */
afterlayout: this.reOrderAfterRemove
/* end of override */
});
//super sets a reference to the toolbar in this.target
Ext.ux.ToolbarReorderer.superclass.init.apply(this, arguments);
},
/**
* Sets up the given Toolbar item as a draggable
* @param {Mixed} button The item to make draggable (usually an Ext.Button instance)
*/
createItemDD: function(button) {
if (button.dd != undefined) return;
var el = button.getEl(),
id = el.id,
tbar = this.target,
me = this;
button.dd = new Ext.dd.DD(el, undefined, {
isTarget: false
});
//if a button has a menu, it is disabled while dragging with this function
var menuDisabler = function() {
return false;
};
Ext.apply(button.dd, {
b4StartDrag: function() {
this.startPosition = el.getXY();
//bump up the z index of the button being dragged but keep a reference to the original
this.startZIndex = el.getStyle('zIndex');
el.setStyle('zIndex', 10000);
button.suspendEvents();
if (button.menu) {
button.menu.on('beforeshow', menuDisabler, me);
}
},
startDrag: function() {
this.constrainTo(tbar.getEl());
this.setYConstraint(0, 0, 0);
},
onDrag: function(e) {
//calculate the button's index within the toolbar and its current midpoint
var buttonX = el.getXY()[0],
deltaX = buttonX - this.startPosition[0],
items = tbar.items.items,
oldIndex = items.indexOf(button),
newIndex;
//find which item in the toolbar the midpoint is currently over
for (var index = 0; index < items.length; index++) {
var item = items[index];
if (item.reorderable && item.id != button.id) {
//find the midpoint of the button
var box = item.getEl().getBox(),
midpoint = (me.buttonXCache[item.id] || box.x) + (box.width / 2),
movedLeft = oldIndex > index && deltaX < 0 && buttonX < midpoint,
movedRight = oldIndex < index && deltaX > 0 && (buttonX + el.getWidth()) > midpoint;
if (movedLeft || movedRight) {
me[movedLeft ? 'onMovedLeft' : 'onMovedRight'](button, index, oldIndex);
break;
}
}
}
},
/**
* After the drag has been completed, make sure the button being dragged makes it back to
* the correct location and resets its z index
*/
endDrag: function() {
//we need to update the cache here for cases where the button was dragged but its
//position in the toolbar did not change
me.updateButtonXCache();
el.moveTo(me.buttonXCache[button.id], el.getY(), {
duration: me.animationDuration,
scope : this,
callback: function() {
button.resumeEvents();
if (button.menu) {
button.menu.un('beforeshow', menuDisabler, me);
}
tbar.fireEvent('reordered', button, tbar);
}
});
el.setStyle('zIndex', this.startZIndex);
}
});
},
onMovedLeft: function(item, newIndex, oldIndex) {
var tbar = this.target,
items = tbar.items.items;
if (newIndex != undefined && newIndex != oldIndex) {
//move the button currently under drag to its new location
tbar.remove(item, false);
tbar.insert(newIndex, item);
//set the correct x location of each item in the toolbar
this.updateButtonXCache();
for (var index = 0; index < items.length; index++) {
var obj = items[index],
newX = this.buttonXCache[obj.id];
if (item == obj) {
item.dd.startPosition[0] = newX;
} else {
var el = obj.getEl();
el.moveTo(newX, el.getY(), {duration: this.animationDuration});
}
}
}
},
onMovedRight: function(item, newIndex, oldIndex) {
this.onMovedLeft.apply(this, arguments);
},
/**
* @private
* Reorder buttons after a remove
*/
reOrderAfterRemove: function(toolbar) {
var newX, oldX;
toolbar.items.each(function(item){
this.updateButtonXCache();
newX = this.buttonXCache[item.id];
oldX = item.el.getX();
if ( newX !== oldX ){
item.el.moveTo(newX, item.el.getY(), {duration: this.animationDuration});
}
},this);
},
/**
* @private
* Updates the internal cache of button X locations.
*/
updateButtonXCache: function() {
var tbar = this.target,
items = tbar.items,
totalX = tbar.getEl().getBox(true).x;
items.each(function(item) {
this.buttonXCache[item.id] = totalX;
totalX += item.getEl().getWidth();
}, this);
}
});
I listen on toolbar afterlayout event and i reorder the toolbar buttons.
/**
* @private
* Reorder buttons after a remove
*/
reOrderAfterRemove: function(toolbar) {
var newX, oldX;
toolbar.items.each(function(item){
this.updateButtonXCache();
newX = this.buttonXCache[item.id];
oldX = item.el.getX();
if ( newX !== oldX ){
item.el.moveTo(newX, item.el.getY(), {duration: this.animationDuration});
}
},this);
},
Ps: Little code change after edit (a bug was found)
I was using the Ext.ux.ToolbarReorderer for fun on extjs 3.1 (it works!). And I see that there is no support for removing buttons dynamically.
First reorderer.js
/*!
* Ext JS Library 3.2.0
* Copyright(c) 2006-2010 Ext JS, LLC
* licensing@extjs.com
* http://www.extjs.com/license
*/
/**
* @class Ext.ux.Reorderer
* @extends Object
* Generic base class for handling reordering of items. This base class must be extended to provide the
* actual reordering functionality - the base class just sets up events and abstract logic functions.
* It will fire events and set defaults, deferring the actual reordering to a doReorder implementation.
* See Ext.ux.TabReorderer for an example.
*/
Ext.ux.Reorderer = Ext.extend(Object, {
/**
* @property defaults
* @type Object
* Object containing default values for plugin configuration details. These can be overridden when
* constructing the plugin
*/
defaults: {
/**
* @cfg animate
* @type Boolean
* If set to true, the rearranging of the toolbar items is animated
*/
animate: true,
/**
* @cfg animationDuration
* @type Number
* The duration of the animation used to move other toolbar items out of the way
*/
animationDuration: 0.2,
/**
* @cfg defaultReorderable
* @type Boolean
* True to make every toolbar draggable unless reorderable is specifically set to false.
* This defaults to false
*/
defaultReorderable: false
},
/**
* Creates the plugin instance, applies defaults
* @constructor
* @param {Object} config Optional config object
*/
constructor: function(config) {
Ext.apply(this, config || {}, this.defaults);
},
/**
* Initializes the plugin, stores a reference to the target
* @param {Mixed} target The target component which contains the reorderable items
*/
init: function(target) {
/**
* @property target
* @type Ext.Component
* Reference to the target component which contains the reorderable items
*/
this.target = target;
this.initEvents();
var items = this.getItems();
for (var i=0; i < items.length; i++) {
this.createIfReorderable(items[i]);
}
},
/**
* Reorders the items in the target component according to the given mapping object. Example:
* this.reorder({
* 1: 5,
* 3: 2
* });
* Would move the item at index 1 to index 5, and the item at index 3 to index 2
* @param {Object} mappings Object containing current item index as key and new index as property
*/
reorder: function(mappings) {
var target = this.target;
if (target.fireEvent('before-reorder', mappings, target, this) !== false) {
this.doReorder(mappings);
target.fireEvent('reorder', mappings, target, this);
}
},
/**
* Abstract function to perform the actual reordering. This MUST be overridden in a subclass
* @param {Object} mappings Mappings of the old item indexes to new item indexes
*/
doReorder: function(paramName) {
throw new Error("doReorder must be implemented in the Ext.ux.Reorderer subclass");
},
/**
* Should create and return an Ext.dd.DD for the given item. This MUST be overridden in a subclass
* @param {Mixed} item The item to create a DD for. This could be a TabPanel tab, a Toolbar button, etc
* @return {Ext.dd.DD} The DD for the given item
*/
createItemDD: function(item) {
throw new Error("createItemDD must be implemented in the Ext.ux.Reorderer subclass");
},
/**
* Sets up the given Toolbar item as a draggable
* @param {Mixed} button The item to make draggable (usually an Ext.Button instance)
*/
createItemDD: function(button) {
var el = button.getEl(),
id = el.id,
tbar = this.target,
me = this;
button.dd = new Ext.dd.DD(el, undefined, {
isTarget: false
});
button.dd.constrainTo(tbar.getEl());
button.dd.setYConstraint(0, 0, 0);
Ext.apply(button.dd, {
b4StartDrag: function() {
this.startPosition = el.getXY();
//bump up the z index of the button being dragged but keep a reference to the original
this.startZIndex = el.getStyle('zIndex');
el.setStyle('zIndex', 10000);
button.suspendEvents();
},
onDrag: function(e) {
//calculate the button's index within the toolbar and its current midpoint
var buttonX = el.getXY()[0],
deltaX = buttonX - this.startPosition[0],
items = tbar.items.items,
oldIndex = items.indexOf(button),
newIndex;
//find which item in the toolbar the midpoint is currently over
for (var index = 0; index < items.length; index++) {
var item = items[index];
if (item.reorderable && item.id != button.id) {
//find the midpoint of the button
var box = item.getEl().getBox(),
midpoint = (me.buttonXCache[item.id] || box.x) + (box.width / 2),
movedLeft = oldIndex > index && deltaX < 0 && buttonX < midpoint,
movedRight = oldIndex < index && deltaX > 0 && (buttonX + el.getWidth()) > midpoint;
if (movedLeft || movedRight) {
me[movedLeft ? 'onMovedLeft' : 'onMovedRight'](button, index, oldIndex);
break;
}
}
}
},
/**
* After the drag has been completed, make sure the button being dragged makes it back to
* the correct location and resets its z index
*/
endDrag: function() {
//we need to update the cache here for cases where the button was dragged but its
//position in the toolbar did not change
me.updateButtonXCache();
el.moveTo(me.buttonXCache[button.id], undefined, {
duration: me.animationDuration,
scope : this,
callback: function() {
button.resumeEvents();
tbar.fireEvent('reordered', button, tbar);
}
});
el.setStyle('zIndex', this.startZIndex);
}
});
},
/**
* @private
* Creates a DD instance for a given item if it is reorderable
* @param {Mixed} item The item
*/
createIfReorderable: function(item) {
if (this.defaultReorderable && item.reorderable == undefined) item.reorderable = true;
if (item.reorderable) {
if (item.rendered) {
this.createItemDD(item);
} else {
item.on('render', this.createItemDD.createDelegate(this, [item]), this, {single: true});
}
}
},
/**
* Returns an array of items which will be made draggable. This defaults to the contents of this.target.items,
* but can be overridden - e.g. for TabPanels
* @return {Array} The array of items which will be made draggable
*/
getItems: function() {
/* override */
return this.target.items ? this.target.items.items:[];
/* end of override */
},
/**
* Adds before-reorder and reorder events to the target component
*/
initEvents: function() {
this.target.addEvents(
/**
* @event before-reorder
* Fires before a reorder occurs. Return false to cancel
* @param {Object} mappings Mappings of the old item indexes to new item indexes
* @param {Mixed} component The target component
* @param {Ext.ux.TabReorderer} this The plugin instance
*/
'before-reorder',
/**
* @event reorder
* Fires after a reorder has occured.
* @param {Object} mappings Mappings of the old item indexes to the new item indexes
* @param {Mixed} component The target component
* @param {Ext.ux.TabReorderer} this The plugin instance
*/
'reorder'
);
}
});
The only diff is there, and it allows to use empty toolbars.
getItems: function() {
/* override */
return this.target.items ? this.target.items.items:[];
/* end of override */
},
Then toolbar_reorderer.js.
/*!
* Ext JS Library 3.2.0
* Copyright(c) 2006-2010 Ext JS, LLC
* licensing@extjs.com
* http://www.extjs.com/license
*/
/**
* @class Ext.ux.ToolbarReorderer
* @extends Ext.ux.Reorderer
* Plugin which can be attached to any Ext.Toolbar instance. Provides ability to reorder toolbar items
* with drag and drop. Example:
* <pre>
* new Ext.Toolbar({
* plugins: [
* new Ext.ux.ToolbarReorderer({
* defaultReorderable: true
* })
* ],
* items: [
* {text: 'Button 1', reorderable: false},
* {text: 'Button 2'},
* {text: 'Button 3'}
* ]
* });
* </pre>
* In the example above, buttons 2 and 3 will be reorderable via drag and drop. An event named 'reordered'
* is added to the Toolbar, and is fired whenever a reorder has been completed.
*/
Ext.ux.ToolbarReorderer = Ext.extend(Ext.ux.Reorderer, {
/**
* Initializes the plugin, decorates the toolbar with additional functionality
*/
init: function(toolbar) {
/**
* This is used to store the correct x value of each button in the array. We need to use this
* instead of the button's reported x co-ordinate because the buttons are animated when they move -
* if another onDrag is fired while the button is still moving, the comparison x value will be incorrect
*/
this.buttonXCache = {};
toolbar.on({
scope: this,
add : function(toolbar, item) {
this.createIfReorderable(item);
},
/* override */
afterlayout: this.reOrderAfterRemove
/* end of override */
});
//super sets a reference to the toolbar in this.target
Ext.ux.ToolbarReorderer.superclass.init.apply(this, arguments);
},
/**
* Sets up the given Toolbar item as a draggable
* @param {Mixed} button The item to make draggable (usually an Ext.Button instance)
*/
createItemDD: function(button) {
if (button.dd != undefined) return;
var el = button.getEl(),
id = el.id,
tbar = this.target,
me = this;
button.dd = new Ext.dd.DD(el, undefined, {
isTarget: false
});
//if a button has a menu, it is disabled while dragging with this function
var menuDisabler = function() {
return false;
};
Ext.apply(button.dd, {
b4StartDrag: function() {
this.startPosition = el.getXY();
//bump up the z index of the button being dragged but keep a reference to the original
this.startZIndex = el.getStyle('zIndex');
el.setStyle('zIndex', 10000);
button.suspendEvents();
if (button.menu) {
button.menu.on('beforeshow', menuDisabler, me);
}
},
startDrag: function() {
this.constrainTo(tbar.getEl());
this.setYConstraint(0, 0, 0);
},
onDrag: function(e) {
//calculate the button's index within the toolbar and its current midpoint
var buttonX = el.getXY()[0],
deltaX = buttonX - this.startPosition[0],
items = tbar.items.items,
oldIndex = items.indexOf(button),
newIndex;
//find which item in the toolbar the midpoint is currently over
for (var index = 0; index < items.length; index++) {
var item = items[index];
if (item.reorderable && item.id != button.id) {
//find the midpoint of the button
var box = item.getEl().getBox(),
midpoint = (me.buttonXCache[item.id] || box.x) + (box.width / 2),
movedLeft = oldIndex > index && deltaX < 0 && buttonX < midpoint,
movedRight = oldIndex < index && deltaX > 0 && (buttonX + el.getWidth()) > midpoint;
if (movedLeft || movedRight) {
me[movedLeft ? 'onMovedLeft' : 'onMovedRight'](button, index, oldIndex);
break;
}
}
}
},
/**
* After the drag has been completed, make sure the button being dragged makes it back to
* the correct location and resets its z index
*/
endDrag: function() {
//we need to update the cache here for cases where the button was dragged but its
//position in the toolbar did not change
me.updateButtonXCache();
el.moveTo(me.buttonXCache[button.id], el.getY(), {
duration: me.animationDuration,
scope : this,
callback: function() {
button.resumeEvents();
if (button.menu) {
button.menu.un('beforeshow', menuDisabler, me);
}
tbar.fireEvent('reordered', button, tbar);
}
});
el.setStyle('zIndex', this.startZIndex);
}
});
},
onMovedLeft: function(item, newIndex, oldIndex) {
var tbar = this.target,
items = tbar.items.items;
if (newIndex != undefined && newIndex != oldIndex) {
//move the button currently under drag to its new location
tbar.remove(item, false);
tbar.insert(newIndex, item);
//set the correct x location of each item in the toolbar
this.updateButtonXCache();
for (var index = 0; index < items.length; index++) {
var obj = items[index],
newX = this.buttonXCache[obj.id];
if (item == obj) {
item.dd.startPosition[0] = newX;
} else {
var el = obj.getEl();
el.moveTo(newX, el.getY(), {duration: this.animationDuration});
}
}
}
},
onMovedRight: function(item, newIndex, oldIndex) {
this.onMovedLeft.apply(this, arguments);
},
/**
* @private
* Reorder buttons after a remove
*/
reOrderAfterRemove: function(toolbar) {
var newX, oldX;
toolbar.items.each(function(item){
this.updateButtonXCache();
newX = this.buttonXCache[item.id];
oldX = item.el.getX();
if ( newX !== oldX ){
item.el.moveTo(newX, item.el.getY(), {duration: this.animationDuration});
}
},this);
},
/**
* @private
* Updates the internal cache of button X locations.
*/
updateButtonXCache: function() {
var tbar = this.target,
items = tbar.items,
totalX = tbar.getEl().getBox(true).x;
items.each(function(item) {
this.buttonXCache[item.id] = totalX;
totalX += item.getEl().getWidth();
}, this);
}
});
I listen on toolbar afterlayout event and i reorder the toolbar buttons.
/**
* @private
* Reorder buttons after a remove
*/
reOrderAfterRemove: function(toolbar) {
var newX, oldX;
toolbar.items.each(function(item){
this.updateButtonXCache();
newX = this.buttonXCache[item.id];
oldX = item.el.getX();
if ( newX !== oldX ){
item.el.moveTo(newX, item.el.getY(), {duration: this.animationDuration});
}
},this);
},
Ps: Little code change after edit (a bug was found)