PDA

View Full Version : Ordered Multi Select



vtswingkid
16 Jul 2007, 1:21 PM
EDIT: Well, I decided to push forward with it after all.

This form object allows you to drag available items from the right box to the left box.
1 option allows you to preserve and change order in the left box.
Another option allows you to drag the same item into the box multiple times.
The grid header tool bars are accessable.
The clear button can be disabled.

Here is the code:


/**
* @author rbw
*/
Ext.ux.DragSelect = function(config){
this.height=140;
this.width=300;
this.legend='Select';
this.enableDragDrop=true;
this.enableClear=true;
this.preserveOrder=false;
this.allowSelectionReuse=false;
Ext.ux.DragSelect.superclass.constructor.call(this, config);
this.addEvents({
change:true,
rowdblclick:true
});
}
Ext.extend(Ext.ux.DragSelect, Ext.form.FieldSet, {
// private
onRender : function(ct, position){
Ext.ux.DragSelect.superclass.onRender.call(this, ct, position);
var c1=this.el.createChild(Ext.form.Column.prototype.defaultAutoCreate);
var cs=this.el.createChild(Ext.form.Column.prototype.defaultAutoCreate);
var c2=this.el.createChild(Ext.form.Column.prototype.defaultAutoCreate);
this.el.setWidth(this.width);
c1.setWidth((this.width-45)/2);
cs.setWidth(20);
c2.setWidth((this.width-45)/2);
c1.setHeight(this.height-30);
cs.setHeight(this.height-30);
c2.setHeight(this.height-30);
var ds1=new Ext.data.SimpleStore({fields: ['data'], data:[['empty']]});
var ds2=new Ext.data.SimpleStore({fields: ['data'], data:[['empty']]});
var cm1 = new Ext.grid.ColumnModel([{header: "Selected", dataIndex: 'data', width:((this.width-45)/2-20)}]);
var cm2 = new Ext.grid.ColumnModel([{header: "Available", dataIndex: 'data', width:((this.width-45)/2-20)}]);
cm1.defaultSortable = true;
cm2.defaultSortable = true;
var grid1 = new Ext.grid.Grid(c1, {ds: ds1, cm: cm1,
selModel: new Ext.grid.RowSelectionModel(),
enableColLock:true,
enableDragDrop:this.enableDragDrop,
listeners:{
scope:this,
'rowdblclick':function(g,i){this.fireEvent("rowdblclick", g, i);},
'mouseup':{scope:this.grid1, fn:function(e, t){
var row;
if((row = this.view.findRowIndex(t)) !== false)this.rowMouseUp=row;
else this.rowMouseUp=false;
}}
}
});
var drop1 = new Ext.dd.DropTarget(grid1.container, {
ddGroup : 'GridDD',
notifyDrop : function(dd, e, data){
if(data.grid==grid2){
if(grid1.rowMouseUp===false){
for(var i=0;i<data.selections.length;i++){
ds1.add(new Ext.data.Record({data:data.selections[i].data.data}));
}
}else{
for(var i=0;i<data.selections.length;i++){
ds1.insert(grid1.rowMouseUp+i, new Ext.data.Record({data:data.selections[i].data.data}));
}
}
if(!this.parent.preserveOrder)ds1.sort('data','ASC');
if(!this.parent.allowSelectionReuse){
for(var i=0;i<data.selections.length;i++){
data.grid.dataSource.remove(data.selections[i]);
}
}
this.parent.fireEvent("change", this.parent);
return true;
}
if(this.parent.preserveOrder && data.grid==grid1){
if(grid1.rowMouseUp===false){
for(var i=0;i<data.selections.length;i++){
ds1.add(new Ext.data.Record({data:data.selections[i].data.data}));
}
}else{
for(var i=0;i<data.selections.length;i++){
ds1.insert(grid1.rowMouseUp+i, new Ext.data.Record({data:data.selections[i].data.data}));
}
}
for(var i=0;i<data.selections.length;i++){
ds1.remove(data.selections[i]);
}
this.parent.fireEvent("change", this.parent);
return true;
}
return false;
},
parent:this
});
grid1.render();
var tb1=new Ext.Toolbar(grid1.getView().getHeaderPanel(true));
tb1.addSeparator();
if(this.enableClear){
tb1.addButton({text:'Clear', tooltip:"Remove All Entries", scope:this, handler:function(){
var r=ds1.getRange();
ds1.removeAll();
if(!this.allowSelectionReuse){
ds2.add(r);
ds2.sort('data','ASC');
}
this.fireEvent("change", this);
}});
}
var grid2 = new Ext.grid.Grid(c2, {ds: ds2, cm: cm2,
selModel: new Ext.grid.RowSelectionModel(),
enableColLock:true,
enableDragDrop:this.enableDragDrop,
listeners:{'rowdblclick':function(g,i){this.fireEvent("rowdblclick", g, i);}, scope:this}
});
var drop2 = new Ext.dd.DropTarget(grid2.container, {
ddGroup : 'GridDD',
notifyDrop : function(dd, e, data){
if(data.grid!=grid1)return false;
var ds=data.grid.dataSource;
if(!this.parent.allowSelectionReuse){
ds2.add(data.selections);
ds2.sort('data','ASC');
}
for(var i=0;i<data.selections.length;i++){
ds.remove(data.selections[i]);
}
if(!this.parent.preserveOrder)ds.sort('data','ASC');
this.parent.fireEvent("change", this.parent);
return true;
},
parent:this
});
grid2.render();
var tb2=new Ext.Toolbar(grid2.getView().getHeaderPanel(true));
tb2.addSeparator();
grid1.autoSize();
grid2.autoSize();
this.ds2
this.ds1=ds1;
this.ds2=ds2;
this.grid1=grid1;
this.grid2=grid2;
this.tb1=tb1;
this.tb2=tb2;
},
populate:function(d1, d2){
this.ds1.removeAll();
this.ds2.removeAll();
if(d1){
for(var i=0;i<d1.length;i++){
this.ds1.add(new Ext.data.Record({data:d1[i]}));
}
if(!this.preserveOrder)this.ds1.sort('data','ASC');
}
if(d2){
for(var i=0;i<d2.length;i++){
this.ds2.add(new Ext.data.Record({data:d2[i]}));
}
this.ds2.sort('data','ASC');
}
},
destroy:function(){
this.grid1.destroy(true);
this.grid2.destroy(true);
Ext.ux.DragSelect.superclass.destroy.call(this);
},
getValues:function(){
var v=new Array();
var r=this.ds1.getRange();
for(var i=0;i<r.length;i++)v[i]=r[i].data.data;
return v;
},
refresh:function(){
this.grid1.view.refresh();
this.grid2.view.refresh();
}
});



Create this object first:


this.chainSelect = new Ext.ux.DragSelect({
legend:'Chained Events',
height:200, width:325,
enableDragDrop:true,
enableClear:true,
preserveOrder:true,
allowSelectionReuse:true,
listeners: {
'change':function(){submit.enable();},
scope:this
}
});


Add it to the form with form.add(this.chainSelect)

After rendering the form, the toolbars can be accessed with
this.chainSelect.tb1 for the left or this.chainSelect.tb2 for the right.

Populate the grids using
this.chainSelect.populate(d1,d2);
where d1 and d2 are arrays of strings

The results in the selected grid can be retrieved as an array of strings using
astr=this.chainSelect.getValues();
Or you can access the datasources directly using this.chainSelect.ds1 or ds2

This is a start. Features can easily be added to it.

vtswingkid
19 Jul 2007, 10:32 AM
First Post now contains new code for a [ordered] multi select form object.

galdaka
5 Aug 2007, 7:12 AM
I