PDA

View Full Version : Autocomplete combo with multiple values



mschering
29 Oct 2007, 7:49 AM
This one is almost like the one I found at the forum here ( http://extjs.com/forum/showthread.php?t=11806) but I couldn't post in that premium thread.

I modified it to use a textarea rather then an input field so it can hold more values.

It works in Ext 2.0b1. The only problem is that it doesn't fire the select event. If I call that the value is somehow reset to the last value. Any improvements are welcome.

Just call it like a combobox but specify a height and a sep parameter.


Ext.form.ComboBoxMulti = function(config) {
this.sep = config.sep;
this.hideTrigger=true;
this.defaultAutoCreate = {
tag: "textarea",
autocomplete: "off"
};
Ext.form.ComboBoxMulti.superclass.constructor.call (this, config);
};

Ext.extend(Ext.form.ComboBoxMulti, Ext.form.ComboBox, {
getPosition: function() {
if (document.selection) { // IE
var r = document.selection.createRange();
var d = r.duplicate();
d.moveToElementText(this.el.dom);
d.setEndPoint( 'EndToEnd', r );
return d.text.length;
} else {
return this.el.dom.selectionEnd;
}
},

getActiveRange: function() {
var s = this.sep;
var p = this.getPosition();
var v = this.getRawValue();
var left = p
while (left > 0 && v.charAt(left) != s)
--left;
if (left > 0) left++;
return {left: left, right: p};
},

getActiveEntry: function() {
var r = this.getActiveRange();
return this.getRawValue().substring(r.left, r.right).replace(/^\s+|\s+$/g, '');
},

replaceActiveEntry: function(value) {
var r = this.getActiveRange();
var v = this.getRawValue();
var pad = (this.sep == ' ' ? '' : ' ');
//this.setValue(v.substring(0, r.left) + pad + value + this.sep + pad + v.substring(r.right));

var activeRange = v.substring(0, r.left);
if(activeRange != "")
{
activeRange+=pad;
}

this.setValue(activeRange + value + this.sep + pad + v.substring(r.right));
var p = r.left + value.length + 2 + pad.length;
this.selectText.defer(200, this, [p,p]);
},

// private
onSelect : function(record, index){
if(this.fireEvent('beforeselect', this, record, index) !== false){
var value = record.data[this.valueField || this.displayField];
if (this.sep) {
this.replaceActiveEntry(value);
} else {
this.setValue(value);
}
this.collapse();

//this.fireEvent('select', this, record, index);
}
},

onRender : function(ct, position)
{
Ext.form.ComboBoxMulti.superclass.onRender.call(this, ct, position);
this.setHeight(this.height);


},

// private
initQuery : function(){
this.doQuery(this.sep ? this.getActiveEntry() : this.getRawValue());
}
});

JohnStalcup
14 Feb 2008, 9:25 AM
added an option to prevent duplicate entries, fixed a bug that was causing the very first entry to have an extra space character at the front, added the widget to the ext namespace, added line ending semicolons for minification compatibility, and added some comments



/**
* @class Ext.form.ComboBoxMulti
* @extends Ext.form.ComboBox
* Adds freeform multiselect and duplicate entry prevention to the standard combobox
* @constructor
* Create a new ComboBoxMulti.
* @param {Object} config Configuration options
*/
Ext.form.ComboBoxMulti = function(config){
/**
* @cfg {String} sep is used to separate text entries
*/
/**
* @cfg {Boolean} preventDuplicates indicates whether repeated selections of the same option will generate extra entries
*/
Ext.apply(config);

// this option will interfere will expected operation
this.typeAhead = false;
// these options customize behavior
this.minChars = 2;
this.hideTrigger = true;
this.defaultAutoCreate = {
tag: "textarea",
autocomplete: "off"
};

Ext.form.ComboBoxMulti.superclass.constructor.call(this, config);
};

Ext.form.ComboBoxMulti = Ext.extend(Ext.form.ComboBoxMulti, Ext.form.ComboBox, {
getPosition: function(){
if (document.selection) { // IE
var r = document.selection.createRange();
var d = r.duplicate();
d.moveToElementText(this.el.dom);
d.setEndPoint('EndToEnd', r);
return d.text.length;
}
else {
return this.el.dom.selectionEnd;
}
},

getActiveRange: function(){
var s = this.sep;
var p = this.getPosition();
var v = this.getRawValue();
var left = p;
while (left > 0 && v.charAt(left) != s) {
--left;
}
if (left > 0) {
left++;
}
return {
left: left,
right: p
};
},

getActiveEntry: function(){
var r = this.getActiveRange();
return this.getRawValue().substring(r.left, r.right).replace(/^\s+|\s+$/g, '');
},

replaceActiveEntry: function(value){
var r = this.getActiveRange();
var v = this.getRawValue();
if (this.preventDuplicates && v.indexOf(value) >= 0) {
return;
}
var pad = (this.sep == ' ' ? '' : ' ');
this.setValue(v.substring(0, r.left) + (r.left > 0 ? pad : '') + value + this.sep + pad + v.substring(r.right));
var p = r.left + value.length + 2 + pad.length;
this.selectText.defer(200, this, [p, p]);
},

onSelect: function(record, index){
if (this.fireEvent('beforeselect', this, record, index) !== false) {
var value = record.data[this.valueField || this.displayField];
if (this.sep) {
this.replaceActiveEntry(value);
}
else {
this.setValue(value);
}
this.collapse();
this.fireEvent('select', this, record, index);
}
},

initQuery: function(){
this.doQuery(this.sep ? this.getActiveEntry() : this.getRawValue());
}
});

Ext.reg('combomulti', Ext.form.ComboBoxMulti);

dawesi
27 Feb 2008, 3:53 PM
Can you post this in a zip file we can drop in our examples folder... more people will try it if you do :-) (which means more bug fixed and sweeter control!)

sanraj
9 Apr 2009, 11:47 PM
Hi This is working fine for me.
But in IE7 it gives Invalid Argument error when combo values populate.

I searched for it , Error is at setHeight function in Ext-all-debug.js file




setHeight : function(height, animate){
height = this.adjustHeight(height);
if(!animate || !A){
this.dom.style.height = this.addUnits(height);
}else{
this.anim({height: {to: height}}, this.preanim(arguments, 1));
}
returnthis;
},



Can anyone help me to resolve this........

Thanks in advance.

soemi
28 Apr 2009, 5:18 PM
me too.
i found the same mistake with ie.
please help us.

sanraj
29 Apr 2009, 3:05 AM
Hey,

Just change the name of function getPosition to any other name.

-sanraj
:):):)

sanraj
26 May 2009, 5:22 AM
Hi,

When I use this extension , scrollbar not displaying for textarea in Safari.

Is anybody getting the same problem?

-sanraj

sircyaj
29 Jun 2009, 6:41 AM
Hi,

I was just wondering if it is possible to create a combo that uses text area, wherein the textarea can adjust dynamically based on the current value so we will not need the scroll bar anymore?

Thanks!