source: extensions/GrumPluginClasses/js/ui.categorySelector.js @ 7181

Last change on this file since 7181 was 7181, checked in by grum, 13 years ago

Fix bug on the categorySelector (multiselect mode) ; add property 'name'
Fix bug on the requestBuilder (add DISTINCT keyword on request...)

  • Property svn:executable set to *
File size: 47.5 KB
Line 
1/**
2 * -----------------------------------------------------------------------------
3 * file: ui.categorySelector.js
4 * file version: 1.0.1
5 * date: 2010-10-10
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 *   PWG user : http://forum.phpwebgallery.net/profile.php?id=3706
14 *
15 *   << May the Little SpaceFrog be with you ! >>
16 * -----------------------------------------------------------------------------
17 *
18 * see ui.categorySelector.help.txt for help about this plugin
19 *
20 * :: HISTORY ::
21 *
22 * | release | date       |
23 * | 1.0.0   | 2010/10/10 | * first release
24 * |         |            |
25 * | 1.0.1   | 2010/10/14 | * fix bug on 'value' functions ':none', ':all' and
26 * |         |            |   ':invert'
27 * |         |            |
28 * |         |            | * add 'name' property
29 * |         |            |
30 * |         |            |
31 *
32 */
33
34
35
36(
37  function($)
38  {
39    /*
40     * plugin 'public' functions
41     */
42    var publicMethods =
43    {
44      init : function (opt)
45        {
46          return this.each(function()
47            {
48              // default values for the plugin
49              var $this=$(this),
50                  data = $this.data('options'),
51                  objects = $this.data('objects'),
52                  properties = $this.data('properties'),
53                  options =
54                    {
55                      autoLoad:true,
56                      galleryRoot:true,
57                      displayStatus:true,
58                      //displayNbPhotos:true,
59                      listMaxWidth:0,
60                      listMaxHeight:0,
61                      levelIndent:16,
62                      iconWidthEC:15,
63                      iconWidthCheck:18,
64                      serverUrl:'plugins/GrumPluginClasses/gpc_ajax.php',
65                      filter:'accessible',
66                      popup:null,
67                      change:null,
68                      load:null,
69                      multiple:false,
70                      userMode:'public'
71                    };
72
73              // if options given, merge it
74              // if(opt) $.extend(options, opt); ==> options are set by setters
75
76              $this.data('options', options);
77
78
79              if(!properties)
80              {
81                $this.data('properties',
82                  {
83                    index:-1,
84                    initialized:false,
85                    selectorVisible:false,
86                    categories:[],
87                    labelStatus:['', ''],
88                  }
89                );
90                properties=$this.data('properties');
91              }
92
93              if(!objects)
94              {
95                objects =
96                  {
97                    container:$('<div/>',
98                        {
99                          'class':'ui-category-selector',
100                          css:{
101                            width:'100%'
102                          }
103                        }
104                    ).bind('click.categorySelector',
105                        function ()
106                        {
107                          privateMethods.displaySelector($this, !$this.data('properties').selectorVisible);
108                        }
109                      ),
110                    containerName:$('<div/>',
111                      {
112                        html: '&nbsp;',
113                        'class':'ui-category-selector-name',
114                      }
115                    ),
116                    containerStatus:$('<div/>',
117                      {
118                        'class':'ui-category-selector-status',
119                        css: {
120                          float:'right',
121                          display:(options.displayStatus)?'block':'none'
122                        }
123                      }
124                    ),
125                    containerArrow:$('<div/>',
126                      {
127                        html: '&dArr;',
128                        'class':'ui-category-selector-arrow',
129                        css: {
130                          'float':'right',
131                          cursor:'pointer'
132                        }
133                      }
134                    ),
135
136                    listContainer:$('<div/>',
137                        {
138                          html: "",
139                          'class':'ui-category-selector-list',
140                          css: {
141                            overflow:"auto",
142                            display:'none',
143                            position:'absolute'
144                          }
145                        }
146                    ).bind('mouseleave.categorySelector',
147                        function ()
148                        {
149                          privateMethods.displaySelector($this, false);
150                        }
151                      ),
152                    list:$('<ul/>',
153                      {
154                        css: {
155                          listStyle:'none',
156                          padding:'0px',
157                          margin:'0px'
158                        }
159                      }
160                    )
161                  };
162
163                $this
164                  .html('')
165                  .append(objects.container.append(objects.containerArrow).append(objects.containerStatus).append(objects.containerName))
166                  .append(objects.listContainer.append(objects.list));
167
168                $this.data('objects', objects);
169              }
170
171              privateMethods.setOptions($this, opt);
172            }
173          );
174        }, // init
175      destroy : function ()
176        {
177          return this.each(
178            function()
179            {
180              // default values for the plugin
181              var $this=$(this),
182                  objects = $this.data('objects');
183              objects.container.unbind().remove();
184              objects.list.children().unbind();
185              objects.listContainer.remove();
186              $this
187                .unbind('.categorySelector')
188                .css(
189                  {
190                    width:'',
191                    height:''
192                  }
193                );
194            }
195          );
196        }, // destroy
197
198      options: function (value)
199        {
200          return this.each(function()
201            {
202              privateMethods.setOptions($(this), value);
203            }
204          );
205        }, // autoLoad
206
207      autoLoad: function (value)
208        {
209          if(value!=null)
210          {
211            return this.each(function()
212              {
213                privateMethods.setAutoLoad($(this), value);
214              }
215            );
216          }
217          else
218          {
219            var options = this.data('options');
220
221            if(options)
222            {
223              return(options.autoLoad);
224            }
225            else
226            {
227              return(true);
228            }
229          }
230        }, // autoLoad
231
232      galleryRoot: function (value)
233        {
234          if(value!=null)
235          {
236            return this.each(function()
237              {
238                privateMethods.setGalleryRoot($(this), value);
239              }
240            );
241          }
242          else
243          {
244            var options = this.data('options');
245
246            if(options)
247            {
248              return(options.galleryRoot);
249            }
250            else
251            {
252              return(true);
253            }
254          }
255        }, // autoLoad
256
257
258      listMaxWidth: function (value)
259        {
260          if(value)
261          {
262            return this.each(function()
263              {
264                privateMethods.setListMaxWidth($(this), value);
265              }
266            );
267          }
268          else
269          {
270            var options = this.data('options');
271
272            if(options)
273            {
274              return(options.listMaxWidth);
275            }
276            else
277            {
278              return(0);
279            }
280          }
281        }, // listMaxWidth
282
283      listMaxHeight: function (value)
284        {
285          if(value)
286          {
287            return this.each(function()
288              {
289                privateMethods.setListMaxHeight($(this), value);
290              }
291            );
292          }
293          else
294          {
295            var options = this.data('options');
296
297            if(options)
298            {
299              return(options.listMaxHeight);
300            }
301            else
302            {
303              return(0);
304            }
305          }
306        }, // listMaxHeight
307
308      displayStatus: function (value)
309        {
310          if(value!=null)
311          {
312            return this.each(function()
313              {
314                privateMethods.setDisplayStatus($(this), value);
315              }
316            );
317          }
318          else
319          {
320            var options = this.data('options');
321
322            if(options)
323            {
324              return(options.displayStatus);
325            }
326            else
327            {
328              return(true);
329            }
330          }
331        }, // displayStatus
332
333      levelIndent: function (value)
334        {
335          if(value)
336          {
337            return this.each(function()
338              {
339                privateMethods.setLevelIndent($(this), value);
340              }
341            );
342          }
343          else
344          {
345            var options = this.data('options');
346
347            if(options)
348            {
349              return(options.levelIndent);
350            }
351            else
352            {
353              return(0);
354            }
355          }
356        }, // levelIndent
357
358      serverUrl: function (value)
359        {
360          if(value)
361          {
362            return this.each(function()
363              {
364                privateMethods.setServerUrl($(this), value);
365              }
366            );
367          }
368          else
369          {
370            var options = this.data('options');
371
372            if(options)
373            {
374              return(options.serverUrl);
375            }
376            else
377            {
378              return('');
379            }
380          }
381        }, // serverUrl
382
383      filter: function (value)
384        {
385          if(value)
386          {
387            return this.each(function()
388              {
389                privateMethods.setFilter($(this), value);
390              }
391            );
392          }
393          else
394          {
395            var options = this.data('options');
396
397            if(options)
398            {
399              return(options.filter);
400            }
401            else
402            {
403              return('');
404            }
405          }
406        }, // filter
407
408      collapse: function (value)
409        {
410          return this.each(function()
411            {
412              if(!value) value=':all';
413              privateMethods.setExpandCollapse($(this), value, 'C');
414            }
415          );
416        }, // collapse
417
418      expand: function (value)
419        {
420          return this.each(function()
421            {
422              if(!value) value=':all';
423              privateMethods.setExpandCollapse($(this), value, 'E');
424            }
425          );
426        }, // expand
427
428      iconWidthEC: function (value)
429        {
430          if(value)
431          {
432            return this.each(function()
433              {
434                privateMethods.setIconWidthEC($(this), value);
435              }
436            );
437          }
438          else
439          {
440            var options = this.data('options');
441
442            if(options)
443            {
444              return(options.iconWidthEC);
445            }
446            else
447            {
448              return(0);
449            }
450          }
451        }, // iconWidthEC
452
453      iconWidthCheck: function (value)
454        {
455          if(value)
456          {
457            return this.each(function()
458              {
459                privateMethods.setIconWidthCheck($(this), value);
460              }
461            );
462          }
463          else
464          {
465            var options = this.data('options');
466
467            if(options)
468            {
469              return(options.iconWidthCheck);
470            }
471            else
472            {
473              return(0);
474            }
475          }
476        }, // iconWidthCheck
477
478      userMode: function (value)
479        {
480          if(value)
481          {
482            return this.each(function()
483              {
484                privateMethods.setUserMode($(this), value);
485              }
486            );
487          }
488          else
489          {
490            var options = this.data('options');
491
492            if(options)
493            {
494              return(options.userMode);
495            }
496            else
497            {
498              return(0);
499            }
500          }
501        }, // userMode
502
503      name: function ()
504        {
505          var options=this.data('options'),
506              properties=this.data('properties'),
507              objects=this.data('objects');
508
509          if(!options.multiple)
510          {
511            return(properties.categories[properties.index].name);
512          }
513          else
514          {
515            var listNames=[];
516            for(var i=0;i<properties.index.length;i++)
517            {
518              listNames.push(properties.categories[properties.index[i]].name);
519            }
520            return(listNames);
521          }
522        }, // userMode
523
524      value: function (value)
525        {
526          if(value)
527          {
528            // set selected value
529            return this.each(function()
530              {
531                privateMethods.setValue($(this), value);
532              }
533            );
534          }
535          else
536          {
537            // return the selected value
538            var properties=this.data('properties'),
539                options = this.data('options');
540
541            if(properties && properties.index!=null && !options.multiple && properties.index>-1 && properties.index<properties.categories.length)
542            {
543              return(properties.categories[properties.index].id);
544            }
545            else if(properties && properties.index!=null && options.multiple)
546            {
547              var returned=[];
548              for(var i=0;i<properties.index.length;i++)
549              {
550                if(properties.index[i]>-1 && properties.index[i]<properties.categories.length)
551                  returned.push(properties.categories[properties.index[i]].id);
552              }
553              return(returned);
554            }
555            else
556            {
557              return(null);
558            }
559          }
560        }, // value
561      load: function (value)
562        {
563          /*
564           * two functionnalities :
565           *  - if value is set, use it to set the load event function
566           *  - if no value, loads data from server
567           */
568          if(value && $.isFunction(value))
569          {
570            // set selected value
571            return this.each(function()
572              {
573                privateMethods.setEventLoad($(this), value);
574              }
575            );
576          }
577          else
578          {
579            // loads data from server
580            privateMethods.load(this);
581          }
582        },
583
584      popup: function (value)
585        {
586          if(value && $.isFunction(value))
587          {
588            // set selected value
589            return this.each(function()
590              {
591                privateMethods.setEventPopup($(this), value);
592              }
593            );
594          }
595          else
596          {
597            // return the selected value
598            var options=this.data('options');
599
600            if(options)
601            {
602              return(options.popup);
603            }
604            else
605            {
606              return(null);
607            }
608          }
609        }, // popup
610      change: function (value)
611        {
612          if(value && $.isFunction(value))
613          {
614            // set selected value
615            return this.each(function()
616              {
617                privateMethods.setEventChange($(this), value);
618              }
619            );
620          }
621          else
622          {
623            // return the selected value
624            var options=this.data('options');
625
626            if(options)
627            {
628              return(options.change);
629            }
630            else
631            {
632              return(null);
633            }
634          }
635        }, // popup
636      numberOfCategories: function ()
637        {
638          var properties=this.data('properties');
639
640          if(properties)
641          {
642            return(properties.categories.length);
643          }
644          else
645          {
646            return(null);
647          }
648        }, // numberOfCategories
649      properties: function (value)
650        {
651          var properties=this.data('properties');
652
653          if(properties && value==':first' && properties.categories.length>0)
654          {
655            return(properties.categories[0]);
656          }
657          else if(properties && properties.index!=null && (value==':selected' || value==null) && properties.categories.length>0)
658          {
659            if(!option.multiple && properties.index>-1 && properties.index<properties.categories.length)
660            {
661              return(properties.categories[properties.index]);
662            }
663            else if(option.multiple)
664            {
665              var returned=[];
666              for(var i=0;i<properties.index.length;i++)
667              {
668                if(properties.index[i]>-1 && properties.index<properties.categories.length)
669                  returned.push(properties.categories[properties.index[i]]);
670              }
671              return(returned);
672            }
673            return(null);
674          }
675          else if(properties && value>-1)
676          {
677            var index=privateMethods.findIndexByValue(this, value);
678            if(index>-1)
679            {
680              return(properties.categories[index]);
681            }
682            return(null);
683          }
684          else
685          {
686            return(null);
687          }
688        }, // numberOfCategories
689    }; // methods
690
691
692    /*
693     * plugin 'private' methods
694     */
695    var privateMethods =
696    {
697      setOptions : function (object, value)
698        {
699          var properties=object.data('properties'),
700              options=object.data('options');
701
702          if(!$.isPlainObject(value)) return(false);
703
704          properties.initialized=false;
705
706          privateMethods.setAutoLoad(object, (value.autoLoad!=null)?value.autoLoad:options.autoLoad);
707          privateMethods.setGalleryRoot(object, (value.galleryRoot!=null)?value.galleryRoot:options.galleryRoot);
708          privateMethods.setDisplayStatus(object, (value.displayStatus!=null)?value.displayStatus:options.displayStatus);
709          privateMethods.setListMaxWidth(object, (value.listMaxWidth!=null)?value.listMaxWidth:options.listMaxWidth);
710          privateMethods.setListMaxHeight(object, (value.listMaxHeight!=null)?value.listMaxHeight:options.listMaxHeight);
711          privateMethods.setLevelIndent(object, (value.levelIndent!=null)?value.levelIndent:options.levelIndent);
712          privateMethods.setIconWidthEC(object, (value.iconWidthEC!=null)?value.iconWidthEC:options.iconWidthEC);
713          privateMethods.setIconWidthCheck(object, (value.iconWidthCheck!=null)?value.iconWidthCheck:options.iconWidthCheck);
714          privateMethods.setServerUrl(object, (value.serverUrl!=null)?value.serverUrl:options.serverUrl);
715          privateMethods.setFilter(object, (value.filter!=null)?value.filter:options.filter);
716          privateMethods.setUserMode(object, (value.userMode!=null)?value.userMode:options.userMode);
717          privateMethods.setEventPopup(object, (value.popup!=null)?value.popup:options.popup);
718          privateMethods.setEventChange(object, (value.change!=null)?value.change:options.change);
719          privateMethods.setEventLoad(object, (value.load!=null)?value.load:options.load);
720          privateMethods.setMultiple(object, (value.multiple!=null)?value.multiple:options.multiple); // can be set only at the initialization
721
722          if(options.autoLoad) privateMethods.load(object);
723
724          properties.initialized=true;
725        },
726
727      setAutoLoad : function (object, value)
728        {
729          var options=object.data('options'),
730              properties=object.data('properties');
731          if((!properties.initialized || options.autoLoad!=value) && (value==true || value==false))
732          {
733            options.autoLoad=value;
734          }
735          return(options.autoLoad);
736        },
737
738      setGalleryRoot : function (object, value)
739        {
740          var options=object.data('options'),
741              properties=object.data('properties');
742          if((!properties.initialized || options.galleryRoot!=value) && (value==true || value==false))
743          {
744            options.galleryRoot=value;
745            if(options.autoLoad && properties.initialized) privateMethods.load(object);
746          }
747          return(options.galleryRoot);
748        },
749
750      setListMaxWidth : function (object, value)
751        {
752          var options=object.data('options'),
753              properties=object.data('properties'),
754              objects=object.data('objects');
755          if((!properties.initialized || options.listMaxWidth!=value) && value>=0)
756          {
757            options.listMaxWidth=value;
758            if(options.listMaxWidth>0)
759            {
760              objects.listContainer.css('max-width', options.listMaxWidth+'px');
761            }
762            else
763            {
764              objects.listContainer.css('max-width', '');
765            }
766          }
767          return(options.listMaxWidth);
768        },
769
770      setListMaxHeight : function (object, value)
771        {
772          var options=object.data('options'),
773              properties=object.data('properties'),
774              objects=object.data('objects');
775          if((!properties.initialized || options.listMaxHeight!=value) && value>=0)
776          {
777            options.listMaxHeight=value;
778            if(options.listMaxHeight>0)
779            {
780              objects.listContainer.css('max-height', options.listMaxHeight+'px');
781            }
782            else
783            {
784              objects.listContainer.css('max-height', '');
785            }
786          }
787          return(options.listMaxHeight);
788        },
789
790      setDisplayStatus : function (object, value)
791        {
792          var options=object.data('options'),
793              properties=object.data('properties'),
794              objects=object.data('objects');
795          if((!properties.initialized || options.displayStatus!=value) && (value==true || value==false))
796          {
797            options.displayStatus=value;
798            if(options.displayStatus)
799            {
800              object.find('.ui-category-selector-status').show();
801            }
802            else
803            {
804              object.find('.ui-category-selector-status').hide();
805            }
806          }
807          return(options.displayStatus);
808        },
809
810      setLevelIndent : function (object, value)
811        {
812          var options=object.data('options'),
813              properties=object.data('properties'),
814              objects=object.data('objects');
815          if((!properties.initialized || options.levelIndent!=value) && value>=0)
816          {
817            options.levelIndent=value;
818            objects.list.find('.ui-category-selector-item').each(
819              function ()
820              {
821                $(this).css('padding-left', (options.iconWidthEC+options.iconWidthCheck+$(this).attr('level')*options.levelIndent)+'px');
822              }
823            );
824          }
825          return(options.levelIndent);
826        },
827
828      setServerUrl : function (object, value)
829        {
830          var options=object.data('options'),
831              properties=object.data('properties');
832          if(!properties.initialized || options.serverUrl!=value)
833          {
834            options.serverUrl=value;
835            if(options.autoLoad && properties.initialized) privateMethods.load(object);
836          }
837          return(options.serverUrl);
838        },
839
840
841      setFilter : function (object, value)
842        {
843          var options=object.data('options'),
844              properties=object.data('properties');
845          if((!properties.initialized || options.filter!=value) && (value=='none' || value=='accessible' || value=='public'))
846          {
847            options.filter=value;
848            if(options.autoLoad && properties.initialized) privateMethods.load(object);
849          }
850          return(options.filter);
851        },
852
853      setIconWidthEC : function (object, value)
854        {
855          var options=object.data('options'),
856              properties=object.data('properties'),
857              objects=object.data('objects');
858          if((!properties.initialized || options.iconWidthEC!=value) && value>=0)
859          {
860            options.iconWidthEC=value;
861            objects.list.find('.ui-category-selector-item').each(
862              function ()
863              {
864                $(this).css('padding-left', (options.iconWidthEC+options.iconWidthCheck+$(this).attr('level')*options.levelIndent)+'px');
865              }
866            );
867          }
868          return(options.filter);
869        },
870
871      setIconWidthCheck : function (object, value)
872        {
873          var options=object.data('options'),
874              properties=object.data('properties'),
875              objects=object.data('objects');
876          if((!properties.initialized || options.iconWidthCheck!=value) && (value>=0 && options.multiple || !options.multiple && value==0))
877          {
878            options.iconWidthCheck=value;
879            objects.list.find('.ui-category-selector-item').each(
880              function ()
881              {
882                $(this).css('padding-left', (options.iconWidthEC+options.iconWidthCheck+$(this).attr('level')*options.levelIndent)+'px');
883              }
884            );
885          }
886          return(options.filter);
887        },
888
889      setMultiple : function (object, value)
890        {
891          var options=object.data('options'),
892              properties=object.data('properties'),
893              objects=object.data('objects');
894          if((!properties.initialized || options.multiple!=value) && (value==true || value==false))
895          {
896            if(!value)
897            {
898              privateMethods.setIconWidthCheck(object, 0);
899              properties.index=-1;
900            }
901            else
902            {
903              properties.index=[];
904              objects.listContainer.addClass('ui-category-selector-multiple');
905            }
906            options.multiple=value;
907          }
908          return(options.filter);
909        }, //setMultiple
910
911      setUserMode : function (object, value)
912        {
913          var options=object.data('options'),
914              properties=object.data('properties'),
915              objects=object.data('objects');
916          if((!properties.initialized || options.userMode!=value) && (value=='admin' || value=='public'))
917          {
918            options.userMode=value;
919            if(options.autoLoad && properties.initialized) privateMethods.load(object);
920          }
921          return(options.filter);
922        }, //setUserMode
923
924      /**
925       * usage : see notes on the header file
926       *
927       * @param jQuery object : the jQuery object
928       * @param String value : the filter
929       * @param String mode : 'C' for collapse, 'E' for expand
930       */
931      setExpandCollapse : function (object, value, mode)
932        {
933          var objects=object.data('objects');
934
935          /*
936           *  target[1] = ':all' or catId
937           * target[2] = '=' or '<' or '>' or '+'
938           * target[3] = level
939           */
940          re=/^(?:(:all)(?:(=|<|>|\+)(\d+))?)|(?:(\d+)(<|>|\+))?$/i;
941          target=re.exec(value);
942
943          if(target!=null)
944          {
945            switch(mode)
946            {
947              case 'C':
948                applyExpandCollapse=privateMethods.applyCollapse;
949                break;
950              case 'E':
951                applyExpandCollapse=privateMethods.applyExpand;
952                break;
953            }
954
955
956            if(target[1]==':all')
957            {
958              objects.list.find('.ui-category-selector-expandable-item, .ui-category-selector-collapsable-item').each(applyExpandCollapse);
959            }
960            else if(target[4]!=null)
961            {
962              switch(target[5])
963              {
964                case '+':
965                  objects.list.find('.ui-category-selector-expandable-item, .ui-category-selector-collapsable-item').each(privateMethods.applyCollapse);
966                  objects.list.find(':has([catId='+target[4]+'])').prev().each(privateMethods.applyExpand);
967                  objects.list.find('[catId='+target[4]+']').each(applyExpandCollapse);
968                  break;
969                case '>':
970                  objects.list.find('[catId='+target[4]+'] + ul').find('.ui-category-selector-expandable-item, .ui-category-selector-collapsable-item').each(applyExpandCollapse);
971                  objects.list.find('[catId='+target[4]+']').each(applyExpandCollapse);
972                  break;
973                case '<':
974                  objects.list.find(':has([catId='+target[4]+'])').prev().each(applyExpandCollapse);
975                  objects.list.find('[catId='+target[4]+']').each(applyExpandCollapse);
976                  break;
977                default:
978                  objects.list.find('[catId='+target[4]+']').each(applyExpandCollapse);
979                  break;
980              }
981            }
982
983          }
984        }, //setExpandCollapse
985
986      applyExpand : function (index, domElt)
987        {
988          privateMethods.applyExpandCollapse(index, domElt, 'E');
989        }, //applyExpand
990      applyCollapse : function (index, domElt)
991        {
992          privateMethods.applyExpandCollapse(index, domElt, 'C');
993        }, //applyCollapse
994
995      /**
996       * used by the setExpandCollapse function
997       * not aimed to be used directly
998       */
999      applyExpandCollapse : function (index, domElt, mode)
1000              {
1001                action='';
1002                var $domElt=$(domElt);
1003
1004                if(target.length>2 && target[2]!=null && target[3]!=null)
1005                {
1006                  switch(target[2])
1007                  {
1008                    case '=':
1009                      if($domElt.attr('level')==target[3]) action=mode;
1010                      break;
1011                    case '>':
1012                      if($domElt.attr('level')>=target[3]) action=mode;
1013                      break;
1014                    case '<':
1015                      if($domElt.attr('level')<=target[3]) action=mode;
1016                      break;
1017                    case '+':
1018                      if((mode=='E' && $domElt.attr('level')<=target[3]) ||
1019                         (mode=='C' && $domElt.attr('level')>=target[3]))
1020                      {
1021                        action=mode;
1022                      }
1023                      else
1024                      {
1025                        action=(mode=='C')?'E':'C';
1026                      }
1027                      break;
1028                  }
1029                }
1030                else action=mode;
1031
1032                switch(action)
1033                {
1034                  case 'C':
1035                    $domElt
1036                      .removeClass('ui-category-selector-expandable-item ui-category-selector-collapsable-item')
1037                      .addClass('ui-category-selector-expandable-item')
1038                      .next().hide();
1039                    break;
1040                  case 'E':
1041                    $domElt
1042                      .removeClass('ui-category-selector-expandable-item ui-category-selector-collapsable-item')
1043                      .addClass('ui-category-selector-collapsable-item')
1044                      .next().show();
1045                    break;
1046                }
1047
1048              }, //applyExpandCollapse
1049
1050      setValue : function (object, value, trigger)
1051        {
1052          var options=object.data('options'),
1053              properties=object.data('properties'),
1054              objects=object.data('objects'),
1055              index=-1;
1056
1057          re=/^(:invert|:all|:none)(?:(=|<|>)(\d+))$/i;
1058          target=re.exec(value);
1059          if(target!=null) value=target[1];
1060
1061          switch(value)
1062          {
1063            case ':first':
1064              if(properties.categories.length>0) index=0;
1065              break;
1066            case ':last':
1067              index=properties.categories.length-1;
1068              break;
1069            case ':invert':
1070              if(!options.multiple) return(false);
1071              properties.index=[];
1072              objects.list.find('.ui-category-selector-item').each(
1073                function ()
1074                {
1075                  var $this=$(this),
1076                      apply=true;
1077
1078                  if(target!=null)
1079                  {
1080                    switch(target[2])
1081                    {
1082                      case '=':
1083                        apply=($this.attr('level')==target[3]);
1084                        break;
1085                      case '>':
1086                        apply=($this.attr('level')>=target[3]);
1087                        break;
1088                      case '<':
1089                        apply=($this.attr('level')<=target[3]);
1090                        break;
1091                    }
1092                  }
1093
1094                  if(apply)
1095                  {
1096                    if($this.hasClass('ui-category-selector-selected-item'))
1097                    {
1098                      $this.removeClass('ui-category-selector-selected-item');
1099                    }
1100                    else
1101                    {
1102                      $this.addClass('ui-category-selector-selected-item');
1103                      tmp=privateMethods.findIndexByValue(object, $this.attr('catId'));
1104                      if(tmp>-1) properties.index.push(tmp);
1105                    }
1106                  }
1107                }
1108              );
1109              privateMethods.setValue(object, [], false);
1110              return(false);
1111              break;
1112            case ':none':
1113              if(!options.multiple) return(false);
1114
1115              properties.index=[];
1116              objects.list.find('.ui-category-selector-selected-item').each(
1117                function ()
1118                {
1119                  var $this=$(this),
1120                      apply=true;
1121
1122                  if(target!=null)
1123                  {
1124                    switch(target[2])
1125                    {
1126                      case '=':
1127                        apply=($this.attr('level')==target[3]);
1128                        break;
1129                      case '>':
1130                        apply=($this.attr('level')>=target[3]);
1131                        break;
1132                      case '<':
1133                        apply=($this.attr('level')<=target[3]);
1134                        break;
1135                    }
1136                  }
1137
1138                  if(apply) $this.removeClass('ui-category-selector-selected-item');
1139                }
1140              );
1141              privateMethods.setValue(object, [], false);
1142              return(false);
1143              break;
1144            case ':all':
1145              if(!options.multiple) return(false);
1146              properties.index=[];
1147              objects.list.find('.ui-category-selector-item').each(
1148                function ()
1149                {
1150                  var $this=$(this),
1151                      apply=true;
1152
1153                  if(target!=null)
1154                  {
1155                    switch(target[2])
1156                    {
1157                      case '=':
1158                        apply=($this.attr('level')==target[3]);
1159                        break;
1160                      case '>':
1161                        apply=($this.attr('level')>=target[3]);
1162                        break;
1163                      case '<':
1164                        apply=($this.attr('level')<=target[3]);
1165                        break;
1166                    }
1167                  }
1168                  if(apply)
1169                  {
1170                    tmp=privateMethods.findIndexByValue(object, $this.attr('catId'));
1171                    if(tmp>-1) properties.index.push(tmp);
1172
1173                    $this.addClass('ui-category-selector-selected-item');
1174                  }
1175                }
1176              );
1177              privateMethods.setValue(object, [], false);
1178              return(false);
1179              break;
1180            default:
1181              if($.isArray(value) && options.multiple)
1182              {
1183                index=[];
1184                for(var i=0;i<value.length;i++)
1185                {
1186                  tmp=privateMethods.findIndexByValue(object, value[i]);
1187                  if(tmp>-1) index.push(tmp);
1188                }
1189              }
1190              else
1191              {
1192                index=privateMethods.findIndexByValue(object, value);
1193              }
1194
1195              break;
1196          }
1197
1198          if(!options.multiple && (!properties.initialized || properties.index!=index) && index>-1)
1199          {
1200            objects.list.find('.ui-category-selector-selected-item').removeClass('ui-category-selector-selected-item');
1201            objects.list.find('[catId="'+value+'"]').addClass('ui-category-selector-selected-item');
1202            properties.index=index;
1203            objects.containerName.html(properties.categories[properties.index].name);
1204            objects.containerStatus.html(properties.labelStatus[properties.categories[properties.index].status]);
1205            if(trigger && options.change) object.trigger('categorySelectorChange', [properties.categories[properties.index].id]);
1206            if(properties.index>-1) return(properties.categories[properties.index].id);
1207          }
1208          else if(options.multiple)
1209          {
1210            if(!$.isArray(index))
1211            {
1212              if(index<0 || index==null) return(-1);
1213              index=[index];
1214            }
1215            tmp=[];
1216            for(var i=0;i<index.length;i++)
1217            {
1218              var item=objects.list.find('[catId="'+properties.categories[index[i]].id+'"]');
1219
1220              if(item.hasClass('ui-category-selector-selected-item'))
1221              {
1222                item.removeClass('ui-category-selector-selected-item');
1223
1224                tmpIndex=$.inArray(index[i] ,properties.index);
1225                if(tmpIndex>-1) properties.index.splice(tmpIndex, 1);
1226              }
1227              else
1228              {
1229                item.addClass('ui-category-selector-selected-item');
1230                properties.index.push(index[i]);
1231              }
1232              tmp.push(properties.categories[index[i]].id);
1233            }
1234            containerHtml='';
1235            objects.list.find('.ui-category-selector-selected-item div.ui-category-selector-name').each(
1236              function ()
1237              {
1238                containerHtml+=((containerHtml=='')?'':'&nbsp;; ')+$(this).html();
1239              }
1240            );
1241            if(containerHtml=='') containerHtml="&nbsp;";
1242            objects.containerName.html(containerHtml);
1243            if(trigger && options.change) object.trigger('categorySelectorChange', [tmp]);
1244            return(tmp);
1245          }
1246          return(null);
1247        },
1248
1249      displaySelector : function (object, value)
1250        {
1251          var options=object.data('options'),
1252              properties=object.data('properties'),
1253              objects=object.data('objects');
1254          if(properties.selectorVisible!=value)
1255          {
1256            properties.selectorVisible=value;
1257
1258            if(properties.selectorVisible && properties.categories.length>0)
1259            {
1260              var index=0;
1261              objects.listContainer
1262                .css(
1263                  {
1264                    display:'block',
1265                    'min-width':objects.listContainer.parent().css('width')
1266                  }
1267                );
1268              if($.isArray(properties.index))
1269              {
1270                if (properties.index.length>0) index=properties.index[0];
1271              }
1272              else if(properties.index>-1)
1273              {
1274                index=properties.index;
1275              }
1276              objects.listContainer.scrollTop(objects.listContainer.scrollTop()+objects.list.find('[catId="'+properties.categories[index].id+'"]').position().top);
1277            }
1278            else
1279            {
1280              objects.listContainer.css('display', 'none');
1281            }
1282            if(options.popup) object.trigger('categorySelectorPopup', [properties.selectorVisible]);
1283          }
1284          return(properties.selectorVisible);
1285        },
1286
1287      load : function (object)
1288        {
1289          // load datas from server through an asynchronous ajax call
1290          var options=object.data('options'),
1291              properties=object.data('properties'),
1292              objects=object.data('objects');
1293
1294          $.ajax(
1295            {
1296              type: "POST",
1297              url: options.serverUrl,
1298              async: true,
1299              data:
1300                {
1301                  ajaxfct:options.userMode+'.categorySelector.getList',
1302                  filter:options.filter,
1303                  galleryRoot:options.galleryRoot?'y':'n',
1304                  tree:'y'
1305                },
1306              success: function(msg)
1307                {
1308                  list=$.parseJSON(msg);
1309
1310                  properties.labelStatus=list.status;
1311                  privateMethods.listClear(object);
1312                  privateMethods.listAddItems(object, list.categories, objects.list);
1313
1314                  properties.initialized=false;
1315                  privateMethods.setValue(object, ':first');
1316                  properties.initialized=true;
1317
1318                  if(options.load) object.trigger('categorySelectorLoad');
1319                },
1320              error: function(msg)
1321                {
1322                  objects.listContainer.html('Error ! '+msg);
1323                },
1324            }
1325         );
1326        },
1327
1328      listClear : function (object)
1329        {
1330          // clear the categorie list
1331          var objects=object.data('objects'),
1332              options=object.data('options'),
1333              properties=object.data('properties');
1334
1335          objects.list.children().unbind();
1336          objects.list.html('');
1337          if(options.multiple)
1338          {
1339            properties.index=[];
1340          }
1341          else
1342          {
1343            properties.index=-1;
1344          }
1345          properties.categories=[];
1346        },
1347      listAddItems : function (object, listItems, parent)
1348        {
1349          // add the items to the categorie list
1350          var options=object.data('options'),
1351              properties=object.data('properties'),
1352              objects=object.data('objects');
1353
1354          var previousLevel=-1;
1355          for(var i=0;i<listItems.length;i++)
1356          {
1357            properties.categories.push(
1358              {
1359                id:listItems[i].id,
1360                level:listItems[i].level,
1361                name:listItems[i].name,
1362                status:listItems[i].status,
1363                childs:listItems[i].childs.length
1364              }
1365            );
1366
1367            if(options.displayStatus)
1368            {
1369              status="<div class='ui-category-selector-status'>"+properties.labelStatus[listItems[i].status]+"</div>";
1370            }
1371            else
1372            {
1373              status="";
1374            }
1375
1376            var spaceWidth = (options.iconWidthEC+options.iconWidthCheck+listItems[i].level*options.levelIndent),
1377                li=$('<li/>',
1378                      {
1379                        'class':'ui-category-selector-item',
1380                        html:"<div>"+status+"<div class='ui-category-selector-name'>"+listItems[i].name+"</div></div>",
1381                        catId:listItems[i].id,
1382                        level:listItems[i].level,
1383                        css:{
1384                          'padding-left':spaceWidth+'px'
1385                        }
1386                      }
1387                    ).bind('click.categorySelector',
1388                        {object:object, expandArea: spaceWidth, nbchilds:listItems[i].childs.length },
1389                        function (event)
1390                        {
1391                          if(!event.layerX && event.offsetX)
1392                          {
1393                            // trick for IE..
1394                            event.layerX=event.offsetX;
1395                            event.layerY=event.offsetY;
1396                          }
1397
1398                          if(event.layerX<event.data.expandArea && event.data.nbchilds>0 )
1399                          {
1400                            if($(this).hasClass('ui-category-selector-expandable-item'))
1401                            {
1402                              $(this)
1403                                .removeClass('ui-category-selector-expandable-item')
1404                                .addClass('ui-category-selector-collapsable-item')
1405                                .next().show();
1406                            }
1407                            else
1408                            {
1409                              $(this)
1410                                .removeClass('ui-category-selector-collapsable-item')
1411                                .addClass('ui-category-selector-expandable-item')
1412                                .next().hide();
1413                            }
1414                          }
1415                          else
1416                          {
1417                            privateMethods.setValue(event.data.object, $(this).attr('catId'), true);
1418                            if(options.multiple)
1419                            {
1420                            }
1421                            else
1422                            {
1423                              privateMethods.displaySelector(event.data.object, false);
1424                            }
1425                          }
1426                        }
1427                      );
1428            if(listItems[i].childs.length>0)
1429            {
1430              li.addClass('ui-category-selector-collapsable-item').css('background-position', (options.iconWidthCheck+options.levelIndent*listItems[i].level)+'px 0px');
1431            }
1432
1433            if(options.multiple)
1434            {
1435              li.prepend('<div class="ui-category-selector-check"></div>');
1436            }
1437
1438            parent.append(li);
1439
1440            if(listItems[i].childs.length>0)
1441            {
1442              var ul=$('<ul/>',
1443                        {
1444                          'class':'ui-category-selector-group',
1445                          css: {
1446                            listStyle:'none',
1447                            padding:'0px',
1448                            margin:'0px',
1449                            'font-size':(100-listItems[i].level*2)+'%'
1450                          }
1451                        }
1452                      );
1453              li.after(ul);
1454              privateMethods.listAddItems(object, listItems[i].childs, ul);
1455            }
1456
1457          }
1458        },
1459
1460      findIndexByValue : function (object, value)
1461        {
1462          /*
1463           * search a categorie inside the categories list and return the index
1464           * in the array
1465           */
1466          var properties=object.data('properties');
1467          for(var i=0;i<properties.categories.length;i++)
1468          {
1469            if(properties.categories[i].id==value) return(i);
1470          }
1471          return(-1);
1472        },
1473      setEventPopup : function (object, value)
1474        {
1475          var options=object.data('options');
1476          options.popup=value;
1477          object.unbind('categorySelectorPopup');
1478          if(value) object.bind('categorySelectorPopup', options.popup);
1479          return(options.popup);
1480        },
1481      setEventChange : function (object, value)
1482        {
1483          var options=object.data('options');
1484          options.change=value;
1485          object.unbind('categorySelectorChange');
1486          if(value) object.bind('categorySelectorChange', options.change);
1487          return(options.change);
1488        },
1489      setEventLoad : function (object, value)
1490        {
1491          var options=object.data('options');
1492          options.load=value;
1493          object.unbind('categorySelectorLoad');
1494          if(value) object.bind('categorySelectorLoad', options.load);
1495          return(options.load);
1496        }
1497    };
1498
1499
1500    $.fn.categorySelector = function(method)
1501    {
1502      if(publicMethods[method])
1503      {
1504        return publicMethods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
1505      }
1506      else if(typeof method === 'object' || ! method)
1507      {
1508        return publicMethods.init.apply(this, arguments);
1509      }
1510      else
1511      {
1512        $.error( 'Method ' +  method + ' does not exist on jQuery.categorySelector' );
1513      }
1514    } // $.fn.categorySelector
1515
1516  }
1517)(jQuery);
1518
1519
Note: See TracBrowser for help on using the repository browser.