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

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

feature:2436 - Compatibility with Piwigo 2.4

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