/** * ----------------------------------------------------------------------------- * file: ui.inputList.js * file version: 1.0.0 * date: 2010-11-02 * * A jQuery plugin provided by the piwigo's plugin "GrumPluginClasses" * * ----------------------------------------------------------------------------- * Author : Grum * email : grum@piwigo.com * website : http://photos.grum.fr * PWG user : http://forum.phpwebgallery.net/profile.php?id=3706 * * << May the Little SpaceFrog be with you ! >> * ----------------------------------------------------------------------------- * * * * * :: HISTORY :: * * | release | date | * | 1.0.0 | 2010/10/10 | first release * | | | * | | | * | | | * | | | * | | | * | | | * */ ( function($) { /* * plugin 'public' functions */ var publicMethods = { init : function (opt) { return this.each(function() { // default values for the plugin var $this=$(this), data = $this.data('options'), objects = $this.data('objects'), properties = $this.data('properties'), options = { serverUrl:'', autoLoad:true, listMaxWidth:0, listMaxHeight:0, multiple:false, downArrow:'⇓', popupMode:'click', colsWidth:[], colsDisplayed:[], colsCss:[], disabled:false, popup:null, change:null, load:null, returnMode:'selected' }; // if options given, merge it // if(opt) $.extend(options, opt); ==> options are set by setters $this.data('options', options); if(!properties) { $this.data('properties', { index:-1, initialized:false, selectorVisible:false, items:[], mouseOver:false, isValid:true, firstPopup:true } ); properties=$this.data('properties'); } if(!objects) { objects = { container:$('
', { 'class':'ui-inputList', tabindex:0, css:{ width:'100%' } } ).bind('click.inputList', function () { privateMethods.displaySelector($this, !$this.data('properties').selectorVisible); $(this).focus(); } ), containerValue:$('
', { html: ' ', 'class':'ui-inputList-value', css:{ overflow:'hidden' } } ), containerList:null, containerArrow:$('
', { html: '⇓', 'class':'ui-inputList-arrow', css: { 'float':'right', cursor:'pointer' } } ).bind('mousedown', function () { $(this).addClass('ui-inputList-arrow-active'); } ).bind('mouseup', function () { $(this).removeClass('ui-inputList-arrow-active'); } ), listContainer:$('
', { html: "", 'class':'ui-inputList-list', css: { overflow:"auto", display:'none', position:'absolute' } } ), list:$('
    ', { css: { listStyle:'none', padding:'0px', margin:'0px' } } ) }; } $this.data('objects', objects); privateMethods.setOptions($this, opt); if($this.text()!='') { var tmp=$.parseJSON($.trim($this.text())), selectedValues=[], values=[]; if($.isArray(tmp)) { values=tmp; } else if(tmp.values!=null) { values=tmp.values; } if(tmp.selected!=null) selectedValues=tmp.selected; privateMethods.setItems($this, values); privateMethods.setValue($this, selectedValues); } $this .html('') .append(objects.container.append(objects.containerArrow).append(objects.containerValue)) .append(objects.listContainer.append(objects.list)); } ); }, // init destroy : function () { return this.each( function() { // default values for the plugin var $this=$(this), objects = $this.data('objects'); objects.container.unbind().remove(); objects.list.children().unbind(); objects.listContainer.remove(); $this .unbind('.inputList') .css( { width:'', height:'' } ); } ); }, // destroy options: function (value) { return this.each(function() { privateMethods.setOptions($(this), value); } ); }, // autoLoad autoLoad: function (value) { if(value!=null) { return this.each(function() { privateMethods.setAutoLoad($(this), value); } ); } else { var options = this.data('options'); if(options) { return(options.autoLoad); } else { return(true); } } }, // autoLoad listMaxWidth: function (value) { if(value!=null) { return this.each(function() { privateMethods.setListMaxWidth($(this), value); } ); } else { var options = this.data('options'); if(options) { return(options.listMaxWidth); } else { return(0); } } }, // listMaxWidth listMaxHeight: function (value) { if(value!=null) { return this.each(function() { privateMethods.setListMaxHeight($(this), value); } ); } else { var options = this.data('options'); if(options) { return(options.listMaxHeight); } else { return(0); } } }, // listMaxHeight serverUrl: function (value) { if(value!=null) { return this.each(function() { privateMethods.setServerUrl($(this), value); } ); } else { var options = this.data('options'); if(options) { return(options.serverUrl); } else { return(''); } } }, // serverUrl cols: function () { var options=this.data('options'), properties=this.data('properties'); if(!options.multiple) { return(properties.items[properties.index].cols); } else { var listCols=[]; for(var i=0;i-1 && properties.index-1 && properties.index[i]0) { return(properties.items[0]); } else if(properties && properties.index!=null && (value==':selected' || value==null) && properties.items.length>0) { if(!options.multiple && properties.index>-1 && properties.index-1 && properties.index-1) { return(properties.items[index]); } return(null); } else { return(null); } } // properties }; // methods /* * plugin 'private' methods */ var privateMethods = { setOptions : function (object, value) { var properties=object.data('properties'), options=object.data('options'); if(!$.isPlainObject(value)) return(false); properties.initialized=false; privateMethods.setReturnMode(object, (value.returnMode!=null)?value.returnMode:options.returnMode); privateMethods.setAutoLoad(object, (value.autoLoad!=null)?value.autoLoad:options.autoLoad); privateMethods.setListMaxWidth(object, (value.listMaxWidth!=null)?value.listMaxWidth:options.listMaxWidth); privateMethods.setListMaxHeight(object, (value.listMaxHeight!=null)?value.listMaxHeight:options.listMaxHeight); privateMethods.setServerUrl(object, (value.serverUrl!=null)?value.serverUrl:options.serverUrl); privateMethods.setPopupMode(object, (value.popupMode!=null)?value.popupMode:options.popupMode); privateMethods.setDownArrow(object, (value.downArrow!=null)?value.downArrow:options.downArrow); privateMethods.setEventPopup(object, (value.popup!=null)?value.popup:options.popup); privateMethods.setEventChange(object, (value.change!=null)?value.change:options.change); privateMethods.setEventLoad(object, (value.load!=null)?value.load:options.load); privateMethods.setColsWidth(object, (value.colsWidth!=null)?value.colsWidth:options.colsWidth); privateMethods.setColsDisplayed(object, (value.colsDisplayed!=null)?value.colsDisplayed:options.colsDisplayed); privateMethods.setColsCss(object, (value.colsCss!=null)?value.colsCss:options.colsCss); privateMethods.setItems(object, (value.items!=null)?value.items:options.items); privateMethods.setMultiple(object, (value.multiple!=null)?value.multiple:options.multiple); // can be set only at the initialization if(options.autoLoad) privateMethods.load(object); properties.initialized=true; }, setIsValid : function (object, value) { var objects=object.data('objects'), properties=object.data('properties'); if(properties.isValid!=value) { properties.isValid=value; if(properties.isValid) { objects.container.removeClass('ui-error'); } else { objects.container.addClass('ui-error'); } } return(properties.isValid); }, setAutoLoad : function (object, value) { var options=object.data('options'), properties=object.data('properties'); if((!properties.initialized || options.autoLoad!=value) && (value==true || value==false)) { options.autoLoad=value; } return(options.autoLoad); }, setReturnMode : function (object, value) { var options=object.data('options'), properties=object.data('properties'); if((!properties.initialized || options.returnMode!=value) && (value=='selected' || value=='notSelected')) { options.returnMode=value; } return(options.returnMode); }, setColsWidth : function (object, value) { var options=object.data('options'), properties=object.data('properties'), width=0; if((!properties.initialized || options.colsWidth!=value) && $.isArray(value)) { options.colsWidth=value; } return(options.colsWidth); }, setColsDisplayed : function (object, value) { var options=object.data('options'), properties=object.data('properties'); if((!properties.initialized || options.colsDisplayed!=value) && $.isArray(value)) { options.colsDisplayed=value; } return(options.colsDisplayed); }, setColsCss : function (object, value) { var options=object.data('options'), properties=object.data('properties'); if((!properties.initialized || options.colsCss!=value) && $.isArray(value)) { options.colsCss=value; } return(options.colsCss); }, setListMaxWidth : function (object, value) { var options=object.data('options'), properties=object.data('properties'), objects=object.data('objects'); if((!properties.initialized || options.listMaxWidth!=value) && value>=0) { options.listMaxWidth=value; if(options.listMaxWidth>0) { objects.listContainer.css('max-width', options.listMaxWidth+'px'); } else { objects.listContainer.css('max-width', ''); } } return(options.listMaxWidth); }, setListMaxHeight : function (object, value) { var options=object.data('options'), properties=object.data('properties'), objects=object.data('objects'); if((!properties.initialized || options.listMaxHeight!=value) && value>=0) { options.listMaxHeight=value; if(options.listMaxHeight>0) { objects.listContainer.css('max-height', options.listMaxHeight+'px'); } else { objects.listContainer.css('max-height', ''); } } return(options.listMaxHeight); }, setServerUrl : function (object, value) { var options=object.data('options'), properties=object.data('properties'); if(!properties.initialized || options.serverUrl!=value) { options.serverUrl=value; if(options.autoLoad && properties.initialized) privateMethods.load(object); } return(options.serverUrl); }, setMultiple : function (object, value) { var options=object.data('options'), properties=object.data('properties'), objects=object.data('objects'); if((!properties.initialized || options.multiple!=value) && (value==true || value==false)) { if(!value) { properties.index=-1; if(objects.containerList!=null) { objects.containerList.remove(); objects.containerList=null; } } else { properties.index=[]; objects.listContainer.addClass('ui-inputList-multiple'); if(objects.containerList==null) { objects.containerList=$('
      ', { html:'
    •  
    • ' } ); objects.containerValue.html('').append(objects.containerList); } } options.multiple=value; } return(options.multiple); }, //setMultiple setPopupMode : function (object, value) { var options=object.data('options'), properties=object.data('properties'), objects=object.data('objects'); if((!properties.initialized || options.popupMode!=value) && (value=='click' || value=='mouseout')) { options.popupMode=value; if(value=='mouseout') { objects.listContainer .unbind('mouseleave.inputList') .unbind('mouseenter.inputList') .bind('mouseleave.inputList', function () { privateMethods.displaySelector(object, false); } ); } else { objects.listContainer .unbind('mouseleave.inputList') .bind('mouseleave.inputList', function () { properties.mouseOver=false; } ) .bind('mouseenter.inputList', function () { properties.mouseOver=true; } ); $(document).bind('focusout focusin', function (event) { if(!properties.mouseOver) privateMethods.displaySelector(object, false); event.stopPropagation(); } ); } } return(options.popupMode); }, //setPopupMode setDownArrow : function (object, value) { var options=object.data('options'), properties=object.data('properties'), objects=object.data('objects'); if(!properties.initialized || options.downArrow!=value) { options.downArrow=value; objects.containerArrow.html(options.downArrow); } return(options.downArrow); }, //setDownArrow setItems : function (object, value) { var properties=object.data('properties'); if(value=='' || value==null) { value=[]; } else if(!$.isArray(value)) { try { value=$.parseJSON($.trim(value)); } catch (e) { return(false); } } privateMethods.listClear(object); if(value.length>0) privateMethods.listAddItems(object, value); }, setValue : function (object, value, trigger) { var options=object.data('options'), properties=object.data('properties'), objects=object.data('objects'), index=-1; re=/^(:invert|:all|:none)(?:(=|<|>)(\d+))$/i; target=re.exec(value); if(target!=null) value=target[1]; switch(value) { case ':first': if(properties.items.length>0) index=0; break; case ':last': index=properties.items.length-1; break; case ':invert': if(!options.multiple) return(false); properties.index=[]; objects.list.find('.ui-inputList-item').each( function () { var $this=$(this), apply=true; if(target!=null) { switch(target[2]) { case '=': apply=($this.attr('level')==target[3]); break; case '>': apply=($this.attr('level')>=target[3]); break; case '<': apply=($this.attr('level')<=target[3]); break; } } if(apply) { if($this.hasClass('ui-inputList-selected-item')) { $this.removeClass('ui-inputList-selected-item'); } else { $this.addClass('ui-inputList-selected-item'); tmp=privateMethods.findIndexByValue(object, $this.attr('idvalue')); if(tmp>-1) properties.index.push(tmp); } } } ); privateMethods.setValue(object, [], false); return(false); break; case ':none': if(!options.multiple) return(false); properties.index=[]; objects.list.find('.ui-inputList-selected-item').each( function () { var $this=$(this), apply=true; if(target!=null) { switch(target[2]) { case '=': apply=($this.attr('level')==target[3]); break; case '>': apply=($this.attr('level')>=target[3]); break; case '<': apply=($this.attr('level')<=target[3]); break; } } if(apply) $this.removeClass('ui-inputList-selected-item'); } ); privateMethods.setValue(object, [], false); return(false); break; case ':all': if(!options.multiple) return(false); properties.index=[]; objects.list.find('.ui-inputList-item').each( function () { var $this=$(this), apply=true; if(target!=null) { switch(target[2]) { case '=': apply=($this.attr('level')==target[3]); break; case '>': apply=($this.attr('level')>=target[3]); break; case '<': apply=($this.attr('level')<=target[3]); break; } } if(apply) { tmp=privateMethods.findIndexByValue(object, $this.attr('idvalue')); if(tmp>-1) properties.index.push(tmp); $this.addClass('ui-inputList-selected-item'); } } ); privateMethods.setValue(object, [], false); return(false); break; default: if($.isArray(value) && options.multiple) { index=[]; for(var i=0;i-1) index.push(tmp); } } else { index=privateMethods.findIndexByValue(object, value); } break; } if(!options.multiple && (!properties.initialized || properties.index!=index) && index>-1) { objects.list.find('.ui-inputList-selected-item').removeClass('ui-inputList-selected-item'); objects.list.find('[idvalue="'+value+'"]').addClass('ui-inputList-selected-item'); properties.index=index; privateMethods.setItemContent(object, index, objects.containerValue); if(trigger) object.trigger('inputListChange', [properties.items[properties.index].value]); if(properties.index>-1) return(properties.items[properties.index].value); } else if(options.multiple) { if(!$.isArray(index)) { if(index<0 || index==null) return(-1); index=[index]; } tmp=[]; for(var i=0;i-1) properties.index.splice(tmpIndex, 1); } else { item.addClass('ui-inputList-selected-item'); properties.index.push(index[i]); } } objects.containerList.html(''); objects.list.children('.ui-inputList-selected-item').each( function () { var value=$(this).attr('idvalue'), index=privateMethods.findIndexByValue(object, value), li=$('
    • ', { 'class':'ui-inputList-selected-item' } ); privateMethods.setItemContent(object, index, li); objects.containerList.append( li.prepend( $('', { 'html':'x', 'class':'ui-inputList-delete-item' } ).bind('click.inputList', {object:object, value:value}, function (event) { event.stopPropagation(); privateMethods.setValue(event.data.object, event.data.value, true); } ) ) ); } ); if(objects.containerList.children().length==0) objects.containerList.append('
    •  
    • '); if(trigger) object.trigger('inputListChange', [tmp]); return(tmp); } return(null); }, displaySelector : function (object, value) { var options=object.data('options'), properties=object.data('properties'), objects=object.data('objects'), scrollBarWidth=0; if(properties.selectorVisible!=value) { properties.selectorVisible=value; if(properties.selectorVisible && properties.items.length>0) { var index=0; objects.listContainer .css( { display:'block', 'min-width':objects.listContainer.parent().css('width') } ); if($.isArray(properties.index)) { if (properties.index.length>0) index=properties.index[0]; } else if(properties.index>-1) { index=properties.index; } scrollBarWidth=objects.listContainer.width()-objects.list.width(); if(scrollBarWidth>0 && properties.firstPopup) { objects.listContainer.width(objects.listContainer.width()+scrollBarWidth); properties.firstPopup=false; } objects.listContainer.scrollTop(objects.listContainer.scrollTop()+objects.list.find('[idValue="'+properties.items[index].value+'"]').position().top); } else { objects.listContainer.css('display', 'none'); } if(options.popup) object.trigger('inputListPopup', [properties.selectorVisible]); } return(properties.selectorVisible); }, load : function (object) { // load datas from server through an asynchronous ajax call var options=object.data('options'), properties=object.data('properties'), objects=object.data('objects'); if(options.serverUrl=='') return(false); $.ajax( { type: "POST", url: options.serverUrl, async: true, success: function(msg) { privateMethods.setItems(object, msg); properties.initialized=false; if(options.multiple) { privateMethods.setValue(object, ':none'); } else { privateMethods.setValue(object, ':first'); } properties.initialized=true; if(options.load) object.trigger('inputListLoad'); }, error: function(msg) { objects.listContainer.html('Error ! '+msg); } } ); }, listClear : function (object) { // clear the items list var objects=object.data('objects'), options=object.data('options'), properties=object.data('properties'); objects.list.children().unbind(); objects.list.html(''); if(options.multiple) { properties.index=[]; } else { properties.index=-1; } properties.items=[]; properties.firstPopup=true; }, listAddItems : function (object, listItems) { // add the items to the items list var options=object.data('options'), properties=object.data('properties'), objects=object.data('objects'), width=0; for(var i=0;i', { 'class':'ui-inputList-value' } ), li=$('
    • ', { 'class':'ui-inputList-item', 'idValue':listItems[i].value } ).bind('click.inputList', {object:object}, function (event) { privateMethods.setValue(event.data.object, $(this).attr('idValue'), true); if(options.multiple) { } else { privateMethods.displaySelector(event.data.object, false); } if(options.multiple) objects.container.focus(); } ); for(var j=0;j', { html:listItems[i].cols[j], css: { width:privateMethods.getColWidth(object, j) }, 'class':privateMethods.getColCss(object, j) } ) ); } li.append(content); if(options.multiple) { li.children().prepend('
      '); } objects.list.append(li); } }, findIndexByValue : function (object, value) { /* * search an item inside the item list and return the index * in the array */ var properties=object.data('properties'); for(var i=0;i=0 && index=0 && index=0 && index<=properties.items[itemIndex].cols.length) { return(properties.items[itemIndex].cols[index]); } return(''); }, setItemContent : function (object, index, container) { var options=object.data('options'), properties=object.data('properties'), colContent='', colsDisplayed=[]; container.html(''); if(options.colsDisplayed.length==0) { for(var j=0;j', { 'html':colContent, css: { width:privateMethods.getColWidth(object, colsDisplayed[j]) }, 'class':privateMethods.getColCss(object, colsDisplayed[j]) } ) ); } } } }; $.fn.inputList = function(method) { if(publicMethods[method]) { return publicMethods[method].apply( this, Array.prototype.slice.call( arguments, 1 )); } else if(typeof method === 'object' || ! method) { return publicMethods.init.apply(this, arguments); } else { $.error( 'Method ' + method + ' does not exist on jQuery.inputList' ); } } // $.fn.inputList } )(jQuery);