source: extensions/GrumPluginClasses/js/ui.iconSelector.js @ 23963

Last change on this file since 23963 was 16012, checked in by grum, 12 years ago

feature:2634- compatibility with Piwigo 2.4
+add some objects on js framework

  • Property svn:executable set to *
File size: 19.5 KB
RevLine 
[7146]1/**
2 * -----------------------------------------------------------------------------
3 * file: ui.iconSelector.js
[16012]4 * file version: 1.0.1
5 * date: 2012-06-18
[7146]6 *
7 * A jQuery plugin provided by the piwigo's plugin "GrumPluginClasses"
8 *
9 * -----------------------------------------------------------------------------
10 * Author     : Grum
11 *   email    : grum@piwigo.com
12 *   website  : http://photos.grum.fr
13 *
14 *   << May the Little SpaceFrog be with you ! >>
15 * -----------------------------------------------------------------------------
16 *
17 *  Options         Type                 Default value
18 *  - images        Array<String>        []
19 *      Define the list at initialization
20 *        $(".selector").iconSelector({images:['url1', 'url2', ..., 'urlN']});
21 *
22 *      Set/get the images list after initialisation
23 *        $(".selector").iconSelector('images', ['url1', 'url2', ..., 'urlN']);
24 *        $(".selector").iconSelector('images');
25 *
26 *  - numCols       Integer              1
27 *  - numRows       Integer              8
28 *      Define the number of cols/rows displayed
29 *      If number of icon is greater than numCols*numRows, a scrollbar allows to
30 *      scroll on the list
31 *        $(".selector").iconSelector({numCols:4, numRows:4});
32 *
33 *      Set/get the numCols/numRows after initialisation
34 *        $(".selector").iconSelector('numCols', 4);
35 *        $(".selector").iconSelector('numCols');
36 *
37 *  - cellWidth     Integer              32
38 *  - cellHeight    Integer              32
39 *      Define the width/height of cells in the list
40 *      If number of icon is greater than numCols*numRows, a scrollbar allows to
41 *      scroll on the list
42 *        $(".selector").iconSelector({cellWidth:40, cellHeight:20});
43 *
44 *      Set/get the cellWidth/cellHeight after initialisation
45 *        $(".selector").iconSelector('cellHeight', 20);
46 *        $(".selector").iconSelector('cellHeight');
47 *
48 *  - value         String               (first value of image list)
49 *      Define the current selected image
50 *      can also take special values ':first' or ':last'
51 *        $(".selector").iconSelector({value:'urlX'});
52 *
53 *      Set/get the selected icon after initialisation
54 *        $(".selector").iconSelector('value', 'urlX');
55 *        $(".selector").iconSelector('value');
56 *
57 *
58 *  Events
59 *  - popup
60 *      Triggered when the selection list is opened/closed
61 *      One parameter is given (selection list is visible or not)
62 *        $(".selector").iconSelector({popup: function (event, visible) { ... } } );
63 *
64 *      To bind on the event :
65 *        $(".selector").bind('iconSelectorPopup', function (event, visible) { ... } );
66 *
67 *  - change
68 *      Triggered when the selected in has changed
69 *      One parameter is given (the selected value)
70 *        $(".selector").iconSelector({change: function (event, value) { ... } } );
71 *
72 *      To bind on the event :
73 *        $(".selector").bind('iconSelectorChange', function (event, value) { ... } );
74 *
75 *
76 *  Styles
77 *  .ui-icon-selector               : CSS class for the main object
78 *  .ui-icon-selector-list          : CSS class for the icon list container
79 *  .ui-icon-selector-icon          : CSS class for icons
80 *  .ui-icon-selector-selected-icon : CSS class for the selected icon
81 *
82 *
83 * :: HISTORY ::
84 *
85 * | release | date       |
86 * | 1.0.0   | 2010/10/10 | first release
87 * |         |            |
[16012]88 * | 1.0.1   | 2012/06/18 | * imoprove memory managment
[7146]89 * |         |            |
90 * |         |            |
91 * |         |            |
92 * |         |            |
93 * |         |            |
94 *
95 */
96
97
98
99(
100  function($)
101  {
102    /*
103     * plugin 'public' functions
104     */
105    var publicMethods =
106    {
107      init : function (opt)
108        {
109          return this.each(function()
110            {
111              // default values for the plugin
112              var $this=$(this),
113                  data = $this.data('options'),
114                  objects = $this.data('objects'),
115                  properties = $this.data('properties'),
116                  options =
117                    {
118                      images:[],
119                      numCols:1,
120                      numRows:8,
121                      cellWidth:32,
122                      cellHeight:32,
123                      popup:null,
124                      change:null
125                    };
126
127              // if options given, merge it
128              if(opt) $.extend(options, opt);
129
[7175]130              $this.data('options', options);
[7146]131
132              if(!properties)
133              {
134                $this.data('properties',
135                  {
136                    index:-1,
137                    initialized:false,
138                    selectorVisible:false
139                  }
140                );
141                properties=$this.data('properties');
142              }
143
144              if(!objects)
145              {
146                objects =
147                  {
148                    container:$('<div/>',
149                        {
[8961]150                          'class':' ui-icon-selector '
[7146]151                        }
152                    ).bind('click.iconSelector',
153                        function ()
154                        {
155                          privateMethods.displaySelector($this, !$this.data('properties').selectorVisible);
156                        }
157                      ),
158                    listContainer:$('<div/>',
159                        {
160                          html: "",
161                          'class':' ui-icon-selector-list ',
162                          css: {
163                            overflow:"auto",
164                            width:'0px',
165                            height:'0px',
166                            display:'none',
167                            position:'absolute'
168                          }
169                        }
170                    ).bind('mouseleave.iconSelector',
171                        function ()
172                        {
173                          privateMethods.displaySelector($this, false);
174                        }
175                      ),
176                    list:$('<ul/>',
177                      {
178                        css: {
179                          listStyle:'none',
180                          padding:'0px',
181                          margin:'0px'
182                        }
183                      }
184                    )
185                  };
186
187                $this
188                  .html('')
189                  .append(objects.container)
190                  .append(objects.listContainer.append(objects.list));
191
192
193                $this.data('objects', objects);
194              }
195
196              privateMethods.setImages($this, options.images);
197              privateMethods.setCellWidth($this, options.cellWidth);
198              privateMethods.setCellHeight($this, options.cellHeight);
199              privateMethods.setNumCols($this, options.numCols);
200              privateMethods.setNumRows($this, options.numRows);
201              privateMethods.setEventPopup($this, options.popup);
202              privateMethods.setEventChange($this, options.change);
203              if(options.images.length>0) privateMethods.setValue($this, options.images[0]);
204
205              properties.initialized=true;
206            }
207          );
208        }, // init
209      destroy : function ()
210        {
211          return this.each(
212            function()
213            {
214              // default values for the plugin
215              var $this=$(this),
216                  objects = $this.data('objects');
217              objects.container.unbind().remove();
218              objects.list.children().unbind();
219              objects.listContainer.remove();
220              $this
221                .unbind('.iconSelector')
[16012]222                .removeData()
[7146]223                .css(
224                  {
225                    width:'',
226                    height:'',
227                    backgroundImage:''
228                  }
229                );
[16012]230              delete $this;
[7146]231            }
232          );
233        }, // destroy
234      images : function (list)
235        {
236          if(list)
237          {
238            // set images list values
[7175]239            return this.each(function()
[7146]240              {
[7175]241                privateMethods.setImages($(this), list);
[7146]242              }
243            );
244          }
245          else
246          {
247            // return images list values
[7175]248            var options = this.data('options');
[7146]249
[7175]250            if(options)
[7146]251            {
[7175]252              return(options.images);
[7146]253            }
254            else
255            {
256              return([]);
257            }
258          }
259        }, // images
260      numCols: function (value)
261        {
262          if(value)
263          {
264            // set numCols values
[7175]265            return this.each(function()
[7146]266              {
[7175]267                privateMethods.setCols($(this), value);
[7146]268              }
269            );
270          }
271          else
272          {
273            // return images list values
[7175]274            var options = this.data('options');
[7146]275
[7175]276            if(options)
[7146]277            {
[7175]278              return(options.numCols);
[7146]279            }
280            else
281            {
282              return(0);
283            }
284          }
285        }, // numCols
286      numRows: function (value)
287        {
288          if(value)
289          {
290            // set numRows values
[7175]291            return this.each(function()
[7146]292              {
[7175]293                privateMethods.setRows($(this), value);
[7146]294              }
295            );
296          }
297          else
298          {
299            // return images list values
[7175]300            var options = this.data('options');
[7146]301
[7175]302            if(options)
[7146]303            {
[7175]304              return(options.numRows);
[7146]305            }
306            else
307            {
308              return(0);
309            }
310          }
311        }, // numRows
312      cellWidth: function (value)
313        {
314          if(value)
315          {
316            // set cell width values
[7175]317            return this.each(function()
[7146]318              {
[7175]319                privateMethods.setCellWidth($(this), value);
[7146]320              }
321            );
322          }
323          else
324          {
325            // return images list values
[7175]326            var options = this.data('options');
[7146]327
[7175]328            if(options)
[7146]329            {
[7175]330              return(options.cellWidth);
[7146]331            }
332            else
333            {
334              return(0);
335            }
336          }
337        }, // cellWidth
338      cellHeight: function (value)
339        {
340          if(value)
341          {
342            // set cell width values
[7175]343            return this.each(function()
[7146]344              {
[7175]345                privateMethods.setCellHeight($(this), value);
[7146]346              }
347            );
348          }
349          else
350          {
351            // return images list values
[7175]352            var options = this.data('options');
[7146]353
[7175]354            if(options)
[7146]355            {
[7175]356              return(options.cellHeight);
[7146]357            }
358            else
359            {
360              return(0);
361            }
362          }
363        }, // cellHeight
364      value: function (value)
365        {
366          if(value)
367          {
368            // set selected value
[7175]369            return this.each(function()
[7146]370              {
[7175]371                privateMethods.setValue($(this), value);
[7146]372              }
373            );
374          }
375          else
376          {
377            // return the selected value
[7175]378            var options=this.data('options'),
[7146]379                properties=this.data('properties');
380
[7175]381            if(options && properties && properties.index>-1 && properties.index<options.images.length)
[7146]382            {
[7175]383              return(options.images[properties.index]);
[7146]384            }
385            else
386            {
387              return('');
388            }
389          }
390        }, // value
391      popup: function (value)
392        {
393          if(value && $.isFunction(value))
394          {
395            // set selected value
[7175]396            return this.each(function()
[7146]397              {
[7175]398                privateMethods.setEventPopup($(this), value);
[7146]399              }
400            );
401          }
402          else
403          {
404            // return the selected value
[7175]405            var options=this.data('options');
[7146]406
[7175]407            if(options)
[7146]408            {
[7175]409              return(options.popup);
[7146]410            }
411            else
412            {
413              return(null);
414            }
415          }
416        }, // popup
417      change: function (value)
418        {
419          if(value && $.isFunction(value))
420          {
421            // set selected value
[7175]422            return this.each(function()
[7146]423              {
[7175]424                privateMethods.setEventChange($(this), value);
[7146]425              }
426            );
427          }
428          else
429          {
430            // return the selected value
[7175]431            var options=this.data('options');
[7146]432
[7175]433            if(options)
[7146]434            {
[7175]435              return(options.change);
[7146]436            }
437            else
438            {
439              return(null);
440            }
441          }
[7175]442        } // popup
[7146]443
[7175]444    }; // methods
[7146]445
446
447    /*
448     * plugin 'private' methods
449     */
450    var privateMethods =
451    {
452      updateListArea : function (object)
453        {
[7175]454          var options=object.data('options'),
[7146]455              objects=object.data('objects'),
456              icon=objects.list.children().first(),
[7175]457              width=icon.outerWidth()*options.numCols,
458              height=icon.outerHeight()*options.numRows;
[7146]459
460          objects.listContainer.css(
461            {
462              width:width+'px',
463              height:height+'px'
464            }
465          );
466
467          delta = width-objects.listContainer.get(0).clientWidth;
468          // adjust size if scrollbars are present
469          if(delta>0)
470          {
471            objects.listContainer.css('width', (width+delta)+'px');
472          }
473        },
474      setImages : function (object, value)
475        {
[7175]476          var options=object.data('options'),
[7146]477              objects=object.data('objects'),
478              properties=object.data('properties');
[7175]479          options.images=value;
[7146]480
481          objects.list.children().unbind();
482          objects.list.html('');
[7175]483          for(var i=0;i<options.images.length;i++)
[7146]484          {
485            liClass=' ui-icon-selector-icon ';
486            if(i==properties.index)
487            {
488              liClass+=' ui-icon-selector-selected-icon ';
489            }
490            objects.list.append(
[7175]491              $('<li indexValue="'+i+'" class="'+liClass+'" style="display:inline-block;width:'+options.cellWidth+'px;height:'+options.cellHeight+'px;background-image:url('+options.images[i]+');"></li>')
[7146]492                .bind('click',
493                  {object:object},
494                  function (event)
495                  {
496                    privateMethods.setValueByIndex(event.data.object, $(this).attr('indexValue'), true);
497                    privateMethods.displaySelector(event.data.object, false);
498                  }
499                )
500            );
501          }
502
[7175]503          return(options.images);
[7146]504        },
505      setNumCols : function (object, value)
506        {
[7175]507          var options=object.data('options'),
[7146]508              properties=object.data('properties');
[7175]509          if((!properties.initialized || options.numCols!=value) && value>0)
[7146]510          {
[7175]511            options.numCols=value;
[7146]512          }
[7175]513          return(options.numCols);
[7146]514        },
515      setNumRows : function (object, value)
516        {
[7175]517          var options=object.data('options'),
[7146]518              properties=object.data('properties');
[7175]519          if((!properties.initialized || options.numRows!=value) && value>0)
[7146]520          {
[7175]521            options.numRows=value;
[7146]522          }
[7175]523          return(options.numRows);
[7146]524        },
525      setCellWidth : function (object, value)
526        {
[7175]527          var options=object.data('options'),
[7146]528              properties=object.data('properties'),
529              objects=object.data('objects');
[7175]530          if((!properties.initialized || options.cellWidth!=value) && value>=0)
[7146]531          {
[7175]532            options.cellWidth=value;
[7146]533            objects.container.css('width', value+'px');
534          }
[7175]535          return(options.cellWidth);
[7146]536        },
537      setCellHeight : function (object, value)
538        {
[7175]539          var options=object.data('options'),
[7146]540              properties=object.data('properties'),
541              objects=object.data('objects');
[7175]542          if((!properties.initialized || options.cellHeight!=value) && value>=0)
[7146]543          {
[7175]544            options.cellHeight=value;
[7146]545            objects.container.css('height', value+'px');
546          }
[7175]547          return(options.cellHeight);
[7146]548        },
549      setValue : function (object, value)
550        {
[7175]551          var options=object.data('options'),
[7146]552              properties=object.data('properties'),
553              index=-1;
554
555          switch(value)
556          {
557            case ':first':
[7175]558              if(options.images.length>0) index=0;
[7146]559              break;
560            case ':last':
[7175]561              index=options.images.length-1;
[7146]562              break;
563            default:
[7175]564              index=$.inArray(value, options.images);
[7146]565              break;
566          }
567
568          if((!properties.initialized || properties.index!=index) && index>-1)
569          {
570            privateMethods.setValueByIndex(object, index, false);
571          }
[7175]572          return(options.images[properties.index]);
[7146]573        },
574      setValueByIndex : function (object, value, trigger)
575        {
[7175]576          var options=object.data('options'),
[7146]577              properties=object.data('properties'),
578              objects=object.data('objects');
[7175]579          if((!properties.initialized || properties.index!=value) && value>-1 && value<options.images.length)
[7146]580          {
581            objects.list.children('.ui-icon-selector-selected-icon').removeClass('ui-icon-selector-selected-icon');
582            objects.list.children('[indexValue="'+value+'"]').addClass('ui-icon-selector-selected-icon');
583            properties.index=value;
[7175]584            objects.container.css('background-image', 'url('+options.images[properties.index]+')');
585            if(trigger && options.change) object.trigger('iconSelectorChange', [properties.index]);
[7146]586          }
[7175]587          return(options.images[properties.index]);
[7146]588        },
589      displaySelector : function (object, value)
590        {
[7175]591          var options=object.data('options'),
[7146]592              properties=object.data('properties'),
593              objects=object.data('objects');
594          if(properties.selectorVisible!=value)
595          {
596            properties.selectorVisible=value;
597
598            if(properties.selectorVisible)
599            {
600              objects.listContainer
601                .css('display', 'block')
602                .scrollTop(objects.listContainer.scrollTop()+objects.list.children('[indexValue="'+properties.index+'"]').position().top);
603              privateMethods.updateListArea(object);
604            }
605            else
606            {
607              objects.listContainer.css('display', 'none');
608            }
[7175]609            if(options.popup) object.trigger('iconSelectorPopup', [properties.selectorVisible]);
[7146]610          }
611          return(properties.selectorVisible);
612        },
613      setEventPopup : function (object, value)
614        {
[7175]615          var options=object.data('options');
616          options.popup=value;
[7146]617          object.unbind('iconSelectorPopup');
[7175]618          if(value) object.bind('iconSelectorPopup', options.popup);
619          return(options.popup);
[7146]620        },
621      setEventChange : function (object, value)
622        {
[7175]623          var options=object.data('options');
624          options.change=value;
[7146]625          object.unbind('iconSelectorChange');
[7175]626          if(value) object.bind('iconSelectorChange', options.change);
627          return(options.change);
[7146]628        }
[7175]629    };
[7146]630
631
632    $.fn.iconSelector = function(method)
633    {
634      if(publicMethods[method])
635      {
636        return publicMethods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
637      }
638      else if(typeof method === 'object' || ! method)
639      {
640        return publicMethods.init.apply(this, arguments);
641      }
642      else
643      {
644        $.error( 'Method ' +  method + ' does not exist on jQuery.iconSelector' );
645      }
646    } // $.fn.iconSelector
647
648  }
649)(jQuery);
650
651
Note: See TracBrowser for help on using the repository browser.