YUI.add('resourcelist', function(Y) { var Lang = Y.Lang, Widget = Y.Widget, Node = Y.Node; Widget.ResourceList = ResourceList; var NS = Y.namespace('mazzle'); NS.ResourceList = ResourceList; /* ResourceList class constructor */ function ResourceList(config) { ResourceList.superclass.constructor.apply(this, arguments); } /* * Required NAME static field, to identify the Widget class and * used as an event prefix, to generate class names etc. (set to the * class name in camel case). */ ResourceList.NAME = "resourcelist"; /* * The attribute configuration for the ResourceList widget. Attributes can be * defined with default values, get/set functions and validator functions * as with any other class extending Base. */ ResourceList.ATTRS = { query: { value: null }, minQueryLength: { value: 2, validator: Lang.isNumber }, queryDelay: { value: 0.3, validator: Lang.isNumber }, searchEnabled: { value: true, validator: Lang.isBoolean }, page: { value: 0, validator: Lang.isNumber }, maxNumberItems: { value: 100, validator : Lang.isNumber }, totalNumberOfResults: { value: 0, validator: Lang.isNumber }, resources: { value: [], validator : Lang.isArray }, selected: { value: [], validator : Lang.isArray }, options: { value: [], validator: Lang.isArray }, loading: { value: false, validator: Lang.isBoolean }, datasource: { value: null }, request: { value: "" }, params: { value: {} } }; /* Static constants used to define the markup templates used to create ResourceList DOM elements */ ResourceList.LIST_CLASS = ResourceList.NAME+'-list'; ResourceList.ITEM_CLASS = ResourceList.NAME+'-item'; ResourceList.LIST_TEMPLATE = ''; ResourceList.ITEM_TEMPLATE = '
  • '; /* ResourceList extends the base Widget class */ Y.extend(ResourceList, Widget, { initializer: function(config) { this._nDelayID = -1; this._listItems = []; this._list = null; this._load = null; this._pagination = null; this.publish("itemClick", {}); this.publish("beforeContentUpdate", {}); this.publish("afterContentUpdate", {}); this.publish("optionSelect", {}); }, destructor : function() { }, renderUI : function() { this._renderSearch(); this._renderOptions(); this._renderLoad(); this._renderList(); }, bindUI : function() { Y.delegate("click", this._itemSelect, this._list, "li", this); }, syncUI : function() { if(this.get("loading")) { // replace content with loading message this._list.addClass("hidden"); this._load.removeClass("hidden"); } else { // update the column content this.populateList(); // hide loading message and show content this._load.addClass("hidden"); this._list.removeClass("hidden"); } }, _renderList : function() { var content = this.get("contentBox"), nListLength = this.get("maxNumberItems"); // add ul var list = content.one("."+ResourceList.LIST_CLASS); if(!list) { list = content.appendChild(Node.create(ResourceList.LIST_TEMPLATE)); } // add list items var listItems = []; for (var i=0; i < nListLength; i++) { var listItem = list.appendChild(Node.create(ResourceList.ITEM_TEMPLATE)); listItem.setStyle("display", "block"); listItem._node._nItemIndex = i; listItems.push({el:listItem}); } this._list = list; this._listItems = listItems; }, /** * Creates a HTML select list with options provided in the * configuration for columns[index]. * An eventhandler is added to the HTML select element which is * handled by _optionSelect * * @private **/ _renderOptions : function() { var options = this.get("options"); if(options&&options.length>0) { var optionsNode = this.get("contentBox") .appendChild(Node.create('')); var selectedIndex = 0; for (var i=0; i < options.length; i++) { var option = options[i], value = option.value, label = option.label ? option.label : value; if (option.selected) selectedIndex = i; optionsNode.insert(''); optionsNode.set('selectedIndex', selectedIndex); } optionsNode.on("change", this._optionSelect, this); } }, _renderSearch : function() { if(this.get("searchEnabled")) { var search = this.get("contentBox") .appendChild(Node.create('')) .appendChild(Node.create('')); search.on("valuechange", this._valueChangeHandler, this); } }, /** * Creates pagination in a column. * An eventhandler is added to the prev and next buttons which is * handled by _offsetSelect * The pagination is stored in column._pagination, such that it is created * only once. * If pagination already exists we simply show it. * * @private * @param length {Integer} the number of resources **/ _renderPagination : function() { var length = this.get("totalNumberOfResults"), limit = this.get("maxNumberItems"), start = this.get("page")*limit, end = start+Math.min(limit, length); if(length>limit) { if(!this._pagination) { // create the pagination HTML var pagination = this.get("contentBox") .appendChild(Node.create('')); pagination.appendChild(Node.create('prev')) .on("click", this._offsetSelect, this, -1); pagination.insert(''); pagination.appendChild(Node.create('next')) .on("click", this._offsetSelect, this, 1); this._pagination = pagination; } else { // or show it this._pagination.removeClass("hidden"); } // now disable the inactive buttons if(length