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 type="text/javascript" src="../../source/core/Ext.js"></script>
<script type="text/javascript" src="../../source/adapter/ext-base.js"></script>
<!-- <script src="../../adapter/ext/ext-base.js" type="text/javascript"></script> -->
<script src="../../ext-all-debug.js" type="text/javascript"></script>
<script src="../form/states.js" type="text/javascript"></script>
<script type="text/javascript" src="Ext.ux.BoxSelect.v3.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>',
//displayFieldTpl: '{state} - {abbr}',
valueField: 'abbr',
value: [{abbr: 'AL', state : 'Alabama'}, {abbr: 'NY', state: 'New York'}, {abbr: 'MN', state: 'Minnesota'}]
});
var select2 = new Ext.ux.BoxSelect({
id: 'select2',
resizable: true,
fieldLabel: 'Send To',
name: 'states2',
anchor:'100%',
store: states,
mode: 'local',
displayField: 'state',
//displayFieldTpl: '<a href="" title="{nick}">{state} - {abbr}</a>',
displayFieldTpl: '{state} - {abbr}',
valueField: 'abbr',
disabled: true,
value: [{abbr: 'AL', state : 'Alabama'}, {abbr: 'NY', state: 'New York'}, {abbr: 'MN', state: 'Minessota'}],
addUniqueValues: true
});
var form = new Ext.form.FormPanel({
id: 'form',
baseCls: 'x-plain',
labelWidth: 55,
url: 'submit.php',
//method: 'get',
defaultType: 'textfield',
items: [
select,
select2,
{
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>
JS:
Code:
Ext.ux.Box = Ext.extend(Ext.Component, {
initComponent : function(){
Ext.ux.Box.superclass.initComponent.call(this);
},
onElClick : function(e){
this.focus();
},
onLnkClick : function(e){
e.stopEvent();
this.fireEvent('remove', this);
this.dispose();
},
onLnkFocus : function(){
this.el.addClass("bit-box-focus");
},
onLnkBlur : function(){
this.el.removeClass("bit-box-focus");
},
enableElListeners : function() {
this.el.on('click', this.onElClick, this, {stopEvent:true});
},
enableLnkListeners : function() {
this.lnk.on({
'click': this.onLnkClick,
'focus': this.onLnkFocus,
'blur': this.onLnkBlur,
scope: this
});
},
enableAllListeners : function() {
this.enableElListeners();
this.enableLnkListeners();
},
disableAllListeners : function() {
this.el.un('click', this.onElClick, this);
this.lnk.un('click', this.onLnkClick, this);
this.lnk.un('focus', this.onLnkFocus, this);
this.lnk.un('blur', this.onLnkBlur, 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.enableElListeners();
this.el.update(this.caption);
this.lnk = this.el.createChild({
'tag': 'a',
'class': 'closebutton',
'href':'#'
});
this.enableLnkListeners();
this.on({
'disable': this.disableAllListeners,
'enable': this.enableAllListeners,
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)
}
]).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, {
/**
* @cfg {Boolean} addUniqueValues True to add only unique values.
*/
addUniqueValues: true,
initComponent:function() {
Ext.apply(this, {
selectedValues: {},
boxElements: {},
current: false,
options: {
className: 'bit',
separator: ','
},
hideTrigger: true,
grow: false
});
Ext.ux.BoxSelect.superclass.initComponent.call(this);
},
// private
onEnable: function(){
Ext.ux.BoxSelect.superclass.onEnable.apply(this, arguments);
for(var k in this.boxElements){
this.boxElements[k].enable();
}
},
// private
onDisable: function(){
Ext.ux.BoxSelect.superclass.onDisable.apply(this, arguments);
for(var k in this.boxElements){
this.boxElements[k].disable();
}
},
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'
});
if(!Ext.isIE) {
this.holder.dom.style.overflow='hidden';
}
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(typeof this.value !== 'undefined'){
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];
}
if (!this.checkValue(caption)) {
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(e.getKey() == e.ENTER)
{
var value = this.el.dom.value;
if(value.length > 0)
{
if (!this.checkValue(value)) {
this.addBox(value, value);
} else {
Ext.Msg.alert('Message', 'Item is already on the list');
}
this.el.dom.value = '';
}
} else {
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)
var caption;
if(this.displayFieldTpl)
caption = this.displayFieldTpl.apply(record.data)
else if(this.displayField)
caption = record.data[this.displayField];
if (!this.checkValue(caption)) {
this.addBox(record.data[this.valueField], caption);
} else {
Ext.Msg.alert('Message', 'Item is already on the list');
}
this.collapse();
this.setRawValue('');
this.lastSelectionText = '';
this.applyEmptyText();
this.autoSize();
},
checkValue: function (caption) {
if (this.addUniqueValues) {
return typeof this.selectedValues[caption] != 'undefined';
} else {
return true;
}
},
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){
delete this.selectedValues[box.caption];
delete this.boxElements[box.caption];
},
scope: this
}
});
box.render();
if (this.hiddenName) {
var name = this.hiddenName;
} else {
var name = this.name + '[' + id + ']';
}
box.hidden = this.el.insertSibling({
'tag':'input',
'type':'hidden',
//'value': id,
'name': name
},'before', true);
this.selectedValues[caption] = id;
this.boxElements[caption] = box;
},
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);