Skip to content

Instantly share code, notes, and snippets.

@mbusigin
Last active August 9, 2017 15:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mbusigin/121dbf875996de96d41ba101ef2390bf to your computer and use it in GitHub Desktop.
Save mbusigin/121dbf875996de96d41ba101ef2390bf to your computer and use it in GitHub Desktop.
A multi-selection ComboBox for Qooxdoo.
/*
* This is a multi-select dropdown combobox deriviative!
*
* I had seen that some other folks had been looking for similar functionality, and although the Qooxdoo
* community was helpful, and explained what kinds of things they'd have to do to implement it, no finished class
* emerged. So, I had the need, and here it is. Please spin any improvements back to me!
*
* Matthew Busigin, CIO @ Hover Networks, Inc (mbusigin <at> hovernetworks <dot> com)
*
* We're overriding a bunch of stuff here:
* https://github.com/qooxdoo/qooxdoo/blob/master/framework/source/class/qx/ui/form/AbstractSelectBox.js#L215
*
*/
qx.Class.define("analytics.widgets.MultiComboBox",
{
extend : qx.ui.form.ComboBox,
construct : function(editable)
{
this.base(arguments);
this.getChildControl("list").setSelectionMode("additive");
this.editable = editable;
if ( this.editable == false )
{
this.getChildControl("textfield").set( {readOnly: true} );
}
else {
this.getChildControl("textfield").addListener("input", function(e) {
this.getChildControl("list").setSelection( [] );
this.fireDataEvent( "updateSelections", [e.getData()] );
}, this);
}
// this.getChildControl("list").addListener("appear", function(e) {
// this.getChildControl("list").setSelection( this.elements );
// }, this );
this.getChildControl("list").addListener("changeSelection", function(e) {
this.elements = this.getSelections();
if (this.dontEvent == false) {
this.fireDataEvent("updateSelections", this.getSelections());
}
this.setValues(this.elements);
}, this);
},
events:
{
"updateSelections" : "qx.event.type.Data"
},
members:
{
elements: [],
allowClose: false,
dontEvent: false,
alreadyInSetValues: false,
editable: false,
setValues: function(v)
{
if ( this.alreadyInSetValues == true )
{
return;
}
this.alreadyInSetValues = true;
var oldDontEvent = this.dontEvent;
this.dontEvent = true;
this.elements = v;
if ( this.elements.length == 0 )
{
this.getChildControl("textfield").setValue("");
}
else if ( this.elements.length == 1 )
{
/* Do nothing -- the textfield will get automatically updated by the superclass here */
}
else {
/* Superclass will set this to the most recently selected, so we override it for multiple selections */
this.getChildControl("textfield").setValue("(multiple)");
}
var opts = this.getChildControl("list").getSelectables();
var selections = [];
for ( var o in opts )
{
var p = opts[ o ];
if ( this.elements.includes(p.getModel()) )
{
selections.push( p );
}
}
this.getChildControl("list").setSelection( selections );
this.dontEvent = oldDontEvent;
this.alreadyInSetValues = false;
},
_onTextFieldChangeValue: function(e)
{
},
_onPopupChangeVisibility : function(e)
{
},
getSelections: function()
{
var dows = this.getChildControl("list").getSelection().map(function(o){ return(o.getModel());});
return dows;
},
/**
* Reacts on special keys and forwards other key events to the list widget.
*
* @param e {qx.event.type.KeySequence} Keypress event
*/
_onKeyPress : function(e)
{
var identifier = e.getKeyIdentifier();
var listPopup = this.getChildControl("popup");
if (!listPopup.isHidden() && identifier == "Escape")
{
this.allowClose = true;
}
this.base(arguments, e);
},
_onBlur: function(e)
{
this.allowClose = true;
this.base( arguments, e );
},
toggle: function()
{
var isListOpen = this.getChildControl("popup").isVisible();
if (isListOpen) {
this.dontEvent = true;
this.allowClose = true;
this.close();
this.dontEvent = false;
} else {
this.dontEvent = true;
this.open();
// this.getChildControl("list").setSelection( this.elements );
this.dontEvent = false;
}
},
close: function() {
if ( this.allowClose == true )
{
this.allowClose = false;
this.base(arguments);
}
}
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment