I added initialValue functionality to Ext.ux.BoxSelect so that BoxSelect can be shown with intitial selection. Just add the value field to BoxSelect constructor config; it's value must be an array of objects having at minimum the fields specifyied in displayField and valueField
here is the code
Ext.ux.BoxSelect
Code:
Ext.namespace('Ext.ux.plugins');
Ext.ux.Box = Ext.extend(Ext.Component, {
initComponent : function(){
Ext.ux.Box.superclass.initComponent.call(this);
},
onRender: function(ct, position){
Ext.ux.Box.superclass.onRender.call(this, ct, this.maininput);
this.addEvents('remove');
this.addClass('bit-box');
this.el = ct.createChild({ tag: "li" }, this.maininput);
this.el.addClassOnOver('bit-hover');
Ext.apply(this.el, {
'focus': function(){
this.down('a.closebutton').focus();
},
'dispose': function(){
this.dispose()
}.createDelegate(this)
});
this.el.on('click', function(e){
this.focus()
}, this, {stopEvent:true});
this.el.update(this.caption);
this.lnk = this.el.createChild({
'tag': 'a',
'class': 'closebutton',
'href':'#'
});
this.lnk.on({
'click': function(e){
e.stopEvent();
this.fireEvent('remove', this);
this.dispose();
},
'focus': function(){
this.el.addClass("bit-box-focus");
},
'blur': function(){
this.el.removeClass("bit-box-focus");
},
scope: this
});
new Ext.KeyMap(this.lnk, [
{
key: [Ext.EventObject.BACKSPACE, Ext.EventObject.DELETE],
fn: function(){
this.dispose();
}.createDelegate(this)
},
{
key: Ext.EventObject.RIGHT,
fn: function(){
this.move('right');
}.createDelegate(this)
},
{
key: Ext.EventObject.LEFT,
fn: function(){
this.move('left');
}.createDelegate(this)
},
{
key: Ext.EventObject.TAB,
fn: function(){
}.createDelegate(this)
}
]).stopEvent = true;
},
move: function(direction) {
if(direction == 'left')
el = this.el.prev();
else
el = this.el.next();
if(el)
el.focus();
},
dispose: function() {
//if(el.prev() && this.retrieveData(el.prev(), 'small') ) el.prev().remove();
//if(this.current == el) this.focus(el.next());
//if(el.data['type'] == 'box') el.onBoxDispose(this);
Ext.fly(this.hidden).remove();
this.el.hide({
duration: .1,
callback: function(){
this.move('right');
this.destroy()
}.createDelegate(this)
});
return this;
}
});
Ext.ux.BoxSelect = Ext.extend(Ext.form.ComboBox, {
initComponent:function() {
Ext.apply(this, {
selectedValues: {},
boxElements: {},
current: false,
options: {
className: 'bit',
separator: ','
},
hideTrigger: true,
grow: false
});
Ext.ux.BoxSelect.superclass.initComponent.call(this);
},
onRender:function(ct, position) {
Ext.ux.BoxSelect.superclass.onRender.call(this, ct, position);
this.el.removeClass('x-form-text');
this.el.className = 'maininput';
this.el.dom.name = '';
this.el.setWidth(20);
this.el.dom.value = ''
this.holder = this.el.wrap({
'tag': 'ul',
'class':'holder x-form-text'
});
this.holder.on('click', function(e){
e.stopEvent();
if(this.maininput != this.current) this.focus(this.maininput);
}, this);
this.maininput = this.el.wrap({
'tag': 'li', 'class':'bit-input'
});
Ext.apply(this.maininput, {
'focus': function(){
this.focus();
}.createDelegate(this)
});
if(typeof this.displayFieldTpl === 'string')
this.displayFieldTpl = new Ext.XTemplate(this.displayFieldTpl)
if(this.value){
if(typeof this.value === 'string')
this.value = [this.value]
}
Ext.each(this.value, function(item){
if(this.displayFieldTpl)
caption = this.displayFieldTpl.apply(item);
else
caption = item[this.displayField]
this.addBox(item[this.valueField], caption);
}, this);
},
onResize : function( w, h, rw, rh ){
this._width = w;
Ext.ux.BoxSelect.superclass.onResize.call(this, w, h, rw, rh);
this.autoSize();
},
onKeyUp : function(e) {
if(this.editable !== false && !e.isSpecialKey()){
this.lastKey = e.getKey();
if(e.getKey() == e.BACKSPACE && this.el.dom.value.length == 0){
e.stopEvent();
this.collapse();
var el = this.maininput.prev();
if(el) el.focus();
return;
}
this.dqTask.delay(this.queryDelay);
}
this.autoSize();
Ext.ux.BoxSelect.superclass.onKeyUp.call(this, e);
},
onSelect: function(record, index) {
var val = record.data[this.valueField];
this.selectedValues[val] = val;
if(typeof this.displayFieldTpl === 'string')
this.displayFieldTpl = new Ext.XTemplate(this.displayFieldTpl)
if(!this.boxElements[val]){
var caption;
if(this.displayFieldTpl)
caption = this.displayFieldTpl.apply(record.data)
else if(this.displayField)
caption = record.data[this.displayField];
this.addBox(record.data[this.valueField], caption)
}
this.collapse();
this.setRawValue('');
this.lastSelectionText = '';
this.applyEmptyText();
this.autoSize();
},
addBox: function(id, caption){
var box = new Ext.ux.Box({
id: 'Box_' + id,
maininput: this.maininput,
renderTo: this.holder,
className: this.options['className'],
caption: caption,
'value': id,
listeners: {
'remove': function(box){
this.selectedValues[box.value] = null;
},
scope: this
}
});
box.render();
box.hidden = this.el.insertSibling({
'tag':'input',
'type':'hidden',
'value': id,
'name': (this.hiddenName || this.name)
},'before', true);
},
autoSize : function(){
if(!this.rendered){
return;
}
if(!this.metrics){
this.metrics = Ext.util.TextMetrics.createInstance(this.el);
}
var el = this.el;
var v = el.dom.value;
var d = document.createElement('div');
d.appendChild(document.createTextNode(v));
v = d.innerHTML;
d = null;
v += "*";
var w = Math.min(this._width, Math.max(this.metrics.getWidth(v) + 10, 10));
this.el.setWidth(w);
},
getValues: function(){
var ret = [];
for(var k in this.selectedValues){
if(this.selectedValues[k])
ret.push(this.selectedValues[k]);
}
return ret.join(this.options['separator']);
}
});
Ext.reg('boxselect', Ext.ux.BoxSelect);
Sample
HTML Code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>BoxSelect</title>
<meta content='text/html; charset=UTF-8' http-equiv='Content-Type' />
<link href="../../resources/css/ext-all.css" media="screen" rel="Stylesheet" type="text/css" />
<link href="../../examples/examples.css" media="screen" rel="Stylesheet" type="text/css" />
<script src="../../adapter/ext/ext-base.js" type="text/javascript"></script>
<script src="../../ext-all-debug.js" type="text/javascript"></script>
<script src="../states.js" type="text/javascript"></script>
<script type="text/javascript" src="Ext.ux.plugins.BoxSelect.js"></script>
<link href="boxselect.css" media="screen" rel="Stylesheet" type="text/css" />
<script type="text/javascript">
Ext.onReady(function() {
Ext.QuickTips.init();
var states = new Ext.data.SimpleStore({
fields: ['abbr', 'state', 'nick'],
data: Ext.exampledata.states
});
var select = new Ext.ux.BoxSelect({
id: 'select',
resizable: true,
fieldLabel: 'Send To',
name: 'states',
anchor:'100%',
store: states,
mode: 'local',
displayField: 'state',
displayFieldTpl: '<a href="" title="{nick}">{state} - {abbr}</a>',
valueField: 'abbr',
value: [{abbr: 'AL', state : 'Alabama'}, {abbr: 'NY', state: 'New York'}, {abbr: 'MN', state: 'Minessota'}]
});
var form = new Ext.form.FormPanel({
id: 'form',
baseCls: 'x-plain',
labelWidth: 55,
url: 'index.html',
method: 'get',
defaultType: 'textfield',
items: [
select,
{
fieldLabel: 'Subject',
name: 'subject',
anchor: '100%'
},
{
xtype: 'textarea',
hideLabel: true,
name: 'msg',
anchor: '100% -53'
}
]
});
var window = new Ext.Window({
id: 'window',
title: 'Resize Me',
width: 500,
height:300,
minWidth: 300,
minHeight: 200,
layout: 'fit',
plain:true,
bodyStyle:'padding:5px;',
buttonAlign:'center',
items: form,
maximizable: true,
buttons: [{
text: 'Send',
scope: this
,
handler: function(){
form.getForm().submit();
//alert(select.getValues());
}
},{
text: 'Cancel'
}]
});
window.show();
});
</script>
</head>
<body>
</body>
</html>