190 lines
5.4 KiB
JavaScript
190 lines
5.4 KiB
JavaScript
define("dijit/form/_ComboBoxMenuMixin", [
|
|
"dojo/_base/array", // array.forEach
|
|
"dojo/_base/declare", // declare
|
|
"dojo/dom-attr", // domAttr.set
|
|
"dojo/i18n", // i18n.getLocalization
|
|
"dojo/i18n!./nls/ComboBox"
|
|
], function(array, declare, domAttr, i18n){
|
|
|
|
// module:
|
|
// dijit/form/_ComboBoxMenuMixin
|
|
|
|
return declare( "dijit.form._ComboBoxMenuMixin", null, {
|
|
// summary:
|
|
// Focus-less menu for internal use in `dijit/form/ComboBox`
|
|
// tags:
|
|
// private
|
|
|
|
// _messages: Object
|
|
// Holds "next" and "previous" text for paging buttons on drop down
|
|
_messages: null,
|
|
|
|
postMixInProperties: function(){
|
|
this.inherited(arguments);
|
|
this._messages = i18n.getLocalization("dijit.form", "ComboBox", this.lang);
|
|
},
|
|
|
|
buildRendering: function(){
|
|
this.inherited(arguments);
|
|
|
|
// fill in template with i18n messages
|
|
this.previousButton.innerHTML = this._messages["previousMessage"];
|
|
this.nextButton.innerHTML = this._messages["nextMessage"];
|
|
},
|
|
|
|
_setValueAttr: function(/*Object*/ value){
|
|
this.value = value;
|
|
this.onChange(value);
|
|
},
|
|
|
|
onClick: function(/*DomNode*/ node){
|
|
if(node == this.previousButton){
|
|
this._setSelectedAttr(null);
|
|
this.onPage(-1);
|
|
}else if(node == this.nextButton){
|
|
this._setSelectedAttr(null);
|
|
this.onPage(1);
|
|
}else{
|
|
this.onChange(node);
|
|
}
|
|
},
|
|
|
|
// stubs
|
|
onChange: function(/*Number*/ /*===== direction =====*/){
|
|
// summary:
|
|
// Notifies ComboBox/FilteringSelect that user selected an option.
|
|
// tags:
|
|
// callback
|
|
},
|
|
|
|
onPage: function(/*Number*/ /*===== direction =====*/){
|
|
// summary:
|
|
// Notifies ComboBox/FilteringSelect that user clicked to advance to next/previous page.
|
|
// tags:
|
|
// callback
|
|
},
|
|
|
|
onClose: function(){
|
|
// summary:
|
|
// Callback from dijit.popup code to this widget, notifying it that it closed
|
|
// tags:
|
|
// private
|
|
this._setSelectedAttr(null);
|
|
},
|
|
|
|
_createOption: function(/*Object*/ item, labelFunc){
|
|
// summary:
|
|
// Creates an option to appear on the popup menu subclassed by
|
|
// `dijit/form/FilteringSelect`.
|
|
|
|
var menuitem = this._createMenuItem();
|
|
var labelObject = labelFunc(item);
|
|
if(labelObject.html){
|
|
menuitem.innerHTML = labelObject.label;
|
|
}else{
|
|
menuitem.appendChild(
|
|
menuitem.ownerDocument.createTextNode(labelObject.label)
|
|
);
|
|
}
|
|
// #3250: in blank options, assign a normal height
|
|
if(menuitem.innerHTML == ""){
|
|
menuitem.innerHTML = " "; //
|
|
}
|
|
|
|
// update menuitem.dir if BidiSupport was required
|
|
this.applyTextDir(menuitem, (menuitem.innerText || menuitem.textContent || ""));
|
|
|
|
return menuitem;
|
|
},
|
|
|
|
createOptions: function(results, options, labelFunc){
|
|
// summary:
|
|
// Fills in the items in the drop down list
|
|
// results:
|
|
// Array of items
|
|
// options:
|
|
// The options to the query function of the store
|
|
//
|
|
// labelFunc:
|
|
// Function to produce a label in the drop down list from a dojo.data item
|
|
|
|
this.items = results;
|
|
|
|
// display "Previous . . ." button
|
|
this.previousButton.style.display = (options.start == 0) ? "none" : "";
|
|
domAttr.set(this.previousButton, "id", this.id + "_prev");
|
|
// create options using _createOption function defined by parent
|
|
// ComboBox (or FilteringSelect) class
|
|
// #2309:
|
|
// iterate over cache nondestructively
|
|
array.forEach(results, function(item, i){
|
|
var menuitem = this._createOption(item, labelFunc);
|
|
menuitem.setAttribute("item", i); // index to this.items; use indirection to avoid mem leak
|
|
domAttr.set(menuitem, "id", this.id + i);
|
|
this.nextButton.parentNode.insertBefore(menuitem, this.nextButton);
|
|
}, this);
|
|
// display "Next . . ." button
|
|
var displayMore = false;
|
|
// Try to determine if we should show 'more'...
|
|
if(results.total && !results.total.then && results.total != -1){
|
|
if((options.start + options.count) < results.total){
|
|
displayMore = true;
|
|
}else if((options.start + options.count) > results.total && options.count == results.length){
|
|
// Weird return from a data store, where a start + count > maxOptions
|
|
// implies maxOptions isn't really valid and we have to go into faking it.
|
|
// And more or less assume more if count == results.length
|
|
displayMore = true;
|
|
}
|
|
}else if(options.count == results.length){
|
|
//Don't know the size, so we do the best we can based off count alone.
|
|
//So, if we have an exact match to count, assume more.
|
|
displayMore = true;
|
|
}
|
|
|
|
this.nextButton.style.display = displayMore ? "" : "none";
|
|
domAttr.set(this.nextButton,"id", this.id + "_next");
|
|
},
|
|
|
|
clearResultList: function(){
|
|
// summary:
|
|
// Clears the entries in the drop down list, but of course keeps the previous and next buttons.
|
|
var container = this.containerNode;
|
|
while(container.childNodes.length > 2){
|
|
container.removeChild(container.childNodes[container.childNodes.length-2]);
|
|
}
|
|
this._setSelectedAttr(null);
|
|
},
|
|
|
|
highlightFirstOption: function(){
|
|
// summary:
|
|
// Highlight the first real item in the list (not Previous Choices).
|
|
this.selectFirstNode();
|
|
},
|
|
|
|
highlightLastOption: function(){
|
|
// summary:
|
|
// Highlight the last real item in the list (not More Choices).
|
|
this.selectLastNode();
|
|
},
|
|
|
|
selectFirstNode: function(){
|
|
this.inherited(arguments);
|
|
if(this.getHighlightedOption() == this.previousButton){
|
|
this.selectNextNode();
|
|
}
|
|
},
|
|
|
|
selectLastNode: function(){
|
|
this.inherited(arguments);
|
|
if(this.getHighlightedOption() == this.nextButton){
|
|
this.selectPreviousNode();
|
|
}
|
|
},
|
|
|
|
getHighlightedOption: function(){
|
|
return this.selected;
|
|
}
|
|
});
|
|
|
|
});
|