Type.registerNamespace('Sys.Extended.UI'); Sys.Extended.UI.PagingBulletedListBehavior = function(element) { // The PagingBulletedListBehavior provides sorting and paging of a bulleted list // "element" - DOM element the behavior is associated with Sys.Extended.UI.PagingBulletedListBehavior.initializeBase(this, [element]); this._indexSizeValue = 1; this._separatorValue = ' - '; //From Server Componant this._heightValue = null; this._maxItemPerPage = null; this._clientSortValue = false; this._selectIndexCssClassValue = null; this._unselectIndexCssClassValue = null; // Local this._tabValue = new Array(); this._tabValueObject = new Array(); this._tabIndex = new Array(); this._divContent = null; this._divContentIndex = null; this._divContentUl = null; this._prevIndexSelected = null; this._indexSelected = 0; // Event this._clickIndex = null; } Sys.Extended.UI.PagingBulletedListBehavior.prototype = { initialize: function() { Sys.Extended.UI.PagingBulletedListBehavior.callBaseMethod(this, 'initialize'); // ClientState var clientState = this.get_ClientState(); if(clientState) { var stateItems = clientState.split(";"); if(stateItems.length) { this._indexSelected = stateItems[0]; if(stateItems[1] == "null") this._indexSizeValue = null; else this._indexSizeValue = stateItems[1]; if(stateItems[2] == "null") this._maxItemPerPage = null; else this._maxItemPerPage = stateItems[2]; if(stateItems[3] == "true") this._clientSortValue = true; else this._clientSortValue = false; } } var e = this.get_element(); // Div content this._divContent = document.createElement('div'); // Insert div e.parentNode.insertBefore(this._divContent, e); var liElements = e.childNodes; // Create the OnClick Index this._clickIndex = Function.createDelegate(this, this._onIndexClick); var inner, index; this._divContentIndex = document.createElement('DIV'); this._divContentIndex.style.marginBottom = '5px'; this._divContent.appendChild(this._divContentIndex); // Extract LI elements in _tabValueObject for(var i = 0 ; i < liElements.length; i++) { if(liElements[i].nodeName == 'LI') { if((liElements[i].firstChild) && (liElements[i].firstChild.innerHTML)) inner = liElements[i].firstChild.innerHTML; else inner = liElements[i].innerHTML; this._tabValueObject[this._tabValueObject.length] = { text: inner, obj: liElements[i], index: i }; } } // Sort if need if(this._clientSortValue) this._tabValueObject.sort(this.liElementSortText); // Generate Index and dispatch in TabIndex and TabValue this._generateIndexAndTabForView(); // Remove LI this._removeChilds(e.childNodes); // Add DIV for Index this._divContentUl = document.createElement('DIV'); //Height of DivContent this._changeHeightDivContent(); //Re-insert LI this._divContentUl.appendChild(e); this._divContent.appendChild(this._divContentUl); this._updateIndexAndView(this._indexSelected); }, _changeHeightDivContent: function() { // Change the height of the list if(this._heightValue) { this._divContentUl.style.overflow = 'scroll'; this._divContentUl.style.height = (this._heightValue) + 'px'; } else { this._divContentUl.style.overflow = ''; this._divContentUl.style.height = ''; } }, _createAHrefIndex: function(indexText, indexNumber) { // Create an index and display it above the list // "indexText" - text of the index // "indexNumber" - index // returns seperator element appended after the new index (so it can be removed later if last) var spanSeparator; var aIndex; // Create a for Index aIndex = document.createElement('a'); aIndex.href = ''; // Add _unSelectIndexCssClass by default if(this._unselectIndexCssClassValue) Sys.UI.DomElement.addCssClass(aIndex, this._unselectIndexCssClassValue); aIndex.innerHTML = indexText; aIndex.tag = indexNumber; // Attach event $addHandler(aIndex, 'click', this._clickIndex); // Save a Object in _tabIndex this._tabIndex[this._tabIndex.length] = aIndex; this._divContentIndex.appendChild(aIndex); // Add SPAN spanSeparator = document.createElement('SPAN'); // Add FEFF carater for not delete the first or last space spanSeparator.innerHTML = '\uFEFF' + this._separatorValue + '\uFEFF'; this._divContentIndex.appendChild(spanSeparator); // Return Separator for remove the last one return spanSeparator; }, liElementSortText: function(x, y) { // Sort function to compare two strings // "x" - object (of the form {text, index}) // "y" - object (of the form {text, index}) // returns -1 if the first is less than the second, 0 if they are equal, 1 if the first is greater than the second //Sort by text if(x.text.toLowerCase() == y.text.toLowerCase()) { return 0; } else { if(x.text.toLowerCase() < y.text.toLowerCase()) return -1; else return 1; } }, liElementSortIndex: function(x, y) { // Sort function to compare two indices // "x" - object (of the form {text, index}) // "y" - object (of the form {text, index}) // returns -1 if the first is less than the second, 0 if they are equal, 1 if the first is greater than the second //Sort by index (init order) return x.index - y.index; }, _generateIndexAndTabForView: function() { // Create the indices this._deleteTabIndexAndTabValue(); this._tabValue = new Array(); this._tabIndex = new Array(); var lastSpanSeparator; this._removeChilds(this._divContentIndex.childNodes); // Cut array _tabValueObject in _tabValue with 1 dimension per 1 index if(this._maxItemPerPage) { // If _maxItemPerPage index generation become automatique if(this._maxItemPerPage > 0) { var j = -1; for(var i = 0; i < this._tabValueObject.length; i++) { if((i % this._maxItemPerPage) == 0) { index = this._tabValueObject[i].text; this._tabValue[++j] = new Array(); lastSpanSeparator = this._createAHrefIndex(index, j); } this._tabValue[j][this._tabValue[j].length] = this._tabValueObject[i].obj; } } } else { //if Generate index with _indexSizeValue if(this._indexSizeValue > 0) { var currentIndex = ''; var j = -1; for(var i = 0; i < this._tabValueObject.length; i++) { index = this._tabValueObject[i].text.substr(0, this._indexSizeValue).toUpperCase(); if(currentIndex != index) { this._tabValue[++j] = new Array(); lastSpanSeparator = this._createAHrefIndex(index, j); currentIndex = index; } this._tabValue[j][this._tabValue[j].length] = this._tabValueObject[i].obj; } } } //Remove last SpanSeparator if(lastSpanSeparator) this._divContentIndex.removeChild(lastSpanSeparator); }, _deleteTabIndexAndTabValue: function() { // Delete the indices //Remove Event if(this._clickIndex) { for(var i = 0; i < this._tabIndex.length; i++) { var aIndex = this._tabIndex[i]; if(aIndex) $removeHandler(aIndex, 'click', this._clickIndex); } this._changeHandler = null; } // Delete _tabIndex delete this._tabIndex; // Delete Dimention two _tabValue[x] for(var i = 0; i < this._tabValue.length; i++) delete this._tabValue[i]; // Delete _tabValue delete this._tabValue; }, dispose: function() { this._deleteTabIndexAndTabValue(); delete this._tabValueObject; Sys.Extended.UI.PagingBulletedListBehavior.callBaseMethod(this, 'dispose'); }, _removeChilds: function(eChilds) { for(var i = 0; eChilds.length; i++) eChilds[0].parentNode.removeChild(eChilds[0]); }, _renderHtml: function(index) { // Display the elements for the given index // "index" - index var e = this.get_element(); this._removeChilds(e.childNodes); for(var i = 0; i < this._tabValue[index].length; i++) e.appendChild(this._tabValue[index][i]); // Position scroll to top this._divContentUl.scrollTop = 0; }, _selectIndex: function(index) { // Select the first index //Add Style Select to first Index if(this._tabIndex.length > 0) { if(this._unselectIndexCssClassValue) Sys.UI.DomElement.removeCssClass(this._tabIndex[index], this._unselectIndexCssClassValue); if(this._selectIndexCssClassValue) Sys.UI.DomElement.addCssClass(this._tabIndex[index], this._selectIndexCssClassValue); // Save previous Select Index this._prevIndexSelected = this._tabIndex[index]; // Invoke IndexChange this.raiseIndexChanged(this._tabIndex[index]); } }, _onIndexClick: function(evt) { // Handle click events raised when the index is changed // "evt" - event info var e = this.get_element(); // Get the control that raised the event var aIndex = evt.target; //Change Style for selected index if(this._selectIndexCssClassValue) Sys.UI.DomElement.removeCssClass(this._prevIndexSelected, this._selectIndexCssClassValue); if(this._unselectIndexCssClassValue) Sys.UI.DomElement.addCssClass(this._prevIndexSelected, this._unselectIndexCssClassValue); if(this._unselectIndexCssClassValue) Sys.UI.DomElement.removeCssClass(aIndex, this._unselectIndexCssClassValue); if(this._selectIndexCssClassValue) Sys.UI.DomElement.addCssClass(aIndex, this._selectIndexCssClassValue); // Save previous index selected this._prevIndexSelected = aIndex; // Clear this._renderHtml(aIndex.tag); // Invoke IndexChange this.raiseIndexChanged(aIndex); evt.preventDefault(); }, add_indexChanged: function(handler) { this.get_events().addHandler('indexChanged', handler); }, remove_indexChanged: function(handler) { this.get_events().removeHandler('indexChanged', handler); }, raiseIndexChanged: function(eventArgs) { // Update the selected index this._indexSelected = eventArgs.tag; var handler = this.get_events().getHandler('indexChanged'); if(handler) { if(!eventArgs) eventArgs = Sys.EventArgs.Empty; handler(this, eventArgs); } this.set_ClientState(eventArgs.tag + ";" + this.get_IndexSize() + ";" + this.get_MaxItemPerPage() + ";" + this.get_ClientSort()); }, get_tabIndex: function() { // DOM elements of the indices return this._tabIndex; }, get_tabValue: function() { // DOM elements of the items to display for each index return this._tabValue; }, _updateIndexAndView: function(index) { // Regenerate the tables of indices and display // Re-Generate TabIndex and TabValue this._generateIndexAndTabForView() // Select clientState index or default select first index if(this._tabIndex.length > 0) { if(index < this._tabIndex.length) { this._renderHtml(this._tabIndex[index].tag); this._selectIndex(index); } else { this._renderHtml(this._tabIndex[0].tag); this._selectIndex(0); } } }, get_Height: function() { // Height of the bulleted list return this._heightValue; }, set_Height: function(value) { if(this._heightValue != value) { this._heightValue = value; if(this.get_isInitialized()) // Change Height in the DOM this._changeHeightDivContent(); this.raisePropertyChanged('Height'); } }, get_IndexSize: function() { // Number of characters in the index headings (ignored if MaxItemPerPage is set) return this._indexSizeValue; }, set_IndexSize: function(value) { if(this._indexSizeValue != value) { // Clear ClientState to set 0 index this.set_ClientState("0;" + value + ";" + this.get_MaxItemPerPage() + ";" + this.get_ClientSort()); this._indexSizeValue = value; if(this.get_isInitialized()) //Update TabIndex and TabValue and Select first Index this._updateIndexAndView(0); this.raisePropertyChanged('IndexSize'); } }, get_MaxItemPerPage: function() { // Maximum number of items per page (ignores the IndexSize property) return this._maxItemPerPage; }, set_MaxItemPerPage: function(value) { if(this._maxItemPerPage != value) { // Clear ClientState to set 0 index this.set_ClientState("0;" + this.get_IndexSize() + ";" + value + ";" + this.get_ClientSort()); this._maxItemPerPage = value; if(this.get_isInitialized()) //Update TabIndex and TabValue and Select first Index this._updateIndexAndView(0); this.raisePropertyChanged('MaxItemPerPage'); } }, get_Separator: function() { // Separator text to be placed between indices return this._separatorValue; }, set_Separator: function(value) { if(this._separatorValue != value) { if(value) this._separatorValue = value; else this._separatorValue = ''; if(this.get_isInitialized()) // Update TabIndex and TabValue and Select first Index this._updateIndexAndView(0); this.raisePropertyChanged('Separator'); } }, get_ClientSort: function() { // Whether or not the items should be sorted client-side return this._clientSortValue; }, set_ClientSort: function(value) { if(this._clientSortValue != value) { // Clear ClientState to set 0 index this.set_ClientState("0;" + this.get_IndexSize() + ";" + this.get_MaxItemPerPage() + ";" + value); this._clientSortValue = value; if(this.get_isInitialized()) { if(this._clientSortValue) this._tabValueObject.sort(this.liElementSortText); else this._tabValueObject.sort(this.liElementSortIndex); // Update TabIndex and TabValue and Select first Index this._updateIndexAndView(0); } this.raisePropertyChanged('ClientSort'); } }, get_SelectIndexCssClass: function() { // CSS class for the selected index. return this._selectIndexCssClassValue; }, set_SelectIndexCssClass: function(value) { if(this._selectIndexCssClassValue != value) { this._selectIndexCssClassValue = value; this.raisePropertyChanged('SelectIndexCssClass'); } }, get_UnselectIndexCssClass: function() { // CSS class for indices that aren't selected return this._unselectIndexCssClassValue; }, set_UnselectIndexCssClass: function(value) { if(this._unselectIndexCssClassValue != value) { this._unselectIndexCssClassValue = value; this.raisePropertyChanged('UnselectIndexCssClass'); } } } Sys.Extended.UI.PagingBulletedListBehavior.registerClass('Sys.Extended.UI.PagingBulletedListBehavior', Sys.Extended.UI.BehaviorBase);