Merge remote-tracking branch 'origin/new/bug_8209'
[koha.git] / koha-tmpl / opac-tmpl / lib / jquery / plugins / jquery.jqtransform_select.js
1 /*
2  *
3  * jqTransform
4  * by mathieu vilaplana mvilaplana@dfc-e.com
5  * Designer ghyslain armand garmand@dfc-e.com
6  *
7  *
8  * Version 1.0 25.09.08
9  * Version 1.1 06.08.09
10  * Add event click on Checkbox and Radio
11  * Auto calculate the size of a select element
12  * Can now, disabled the elements
13  * Correct bug in ff if click on select (overflow=hidden)
14  * No need any more preloading !!
15  *
16  ******************************************** */
17
18 (function($){
19  var defaultOptions = {preloadImg:true};
20         var jqTransformImgPreloaded = false;
21
22   var jqTransformPreloadHoverFocusImg = function(strImgUrl) {
23             //guillemets to remove for ie
24           strImgUrl = strImgUrl.replace(/^url\((.*)\)/,'$1').replace(/^\"(.*)\"$/,'$1');
25          var imgHover = new Image();
26             imgHover.src = strImgUrl.replace(/\.([a-zA-Z]*)$/,'-hover.$1');
27                 var imgFocus = new Image();
28             imgFocus.src = strImgUrl.replace(/\.([a-zA-Z]*)$/,'-focus.$1');
29         };
30
31
32    /***************************
33      Labels
34        ***************************/
35    var jqTransformGetLabel = function(objfield){
36           var selfForm = $(objfield.get(0).form);
37                 var oLabel = objfield.next();
38           if(!oLabel.is('label')) {
39                       oLabel = objfield.prev();
40                       if(oLabel.is('label')){
41                                 var inputname = objfield.attr('id');
42                            if(inputname){
43                                  oLabel = selfForm.find('label[for="'+inputname+'"]');
44                           }
45                       }
46               }
47               if(oLabel.is('label')){return oLabel.css('cursor','pointer');}
48          return false;
49   };
50
51     /* Hide all open selects */
52     var jqTransformHideSelect = function(oTarget){
53          var ulVisible = $('.jqTransformSelectWrapper ul:visible');
54              ulVisible.each(function(){
55                      var oSelect = $(this).parents(".jqTransformSelectWrapper:first").find("select").get(0);
56                         //do not hide if click on the label object associated to the select
57                     if( !(oTarget && oSelect.oLabel && oSelect.oLabel.get(0) == oTarget.get(0)) ){$(this).hide();}
58          });
59     };
60      /* Check for an external click */
61       var jqTransformCheckExternalClick = function(event) {
62           if ($(event.target).parents('.jqTransformSelectWrapper').length === 0) { jqTransformHideSelect($(event.target)); }
63      };
64
65     /* Apply document listener */
66   var jqTransformAddDocumentListener = function (){
67               $(document).mousedown(jqTransformCheckExternalClick);
68   };
69
70     /* Add a new handler for the reset action */
71    var jqTransformReset = function(f){
72             var sel;
73                $('.jqTransformSelectWrapper select', f).each(function(){sel = (this.selectedIndex<0) ? 0 : this.selectedIndex; $('ul', $(this).parent()).each(function(){$('a:eq('+ sel +')', this).click();});});
74             $('a.jqTransformCheckbox, a.jqTransformRadio', f).removeClass('jqTransformChecked');
75            $('input:checkbox, input:radio', f).each(function(){if(this.checked){$('a', $(this).parent()).addClass('jqTransformChecked');}});
76       };
77
78     /***************************
79      Buttons
80        ***************************/
81   $.fn.jqTransInputButton = function(){
82           return this.each(function(){
83                    var newBtn = $('<button id="'+ this.id +'" name="'+ this.name +'" type="'+ this.type +'" class="'+ this.className +' jqTransformButton"><span><span>'+ $(this).attr('value') +'</span></span>')
84                                 .hover(function(){newBtn.addClass('jqTransformButton_hover');},function(){newBtn.removeClass('jqTransformButton_hover')})
85                               .mousedown(function(){newBtn.addClass('jqTransformButton_click')})
86                              .mouseup(function(){newBtn.removeClass('jqTransformButton_click')})
87                     ;
88                       $(this).replaceWith(newBtn);
89            });
90     };
91
92     /***************************
93      Text Fields
94    ***************************/
95   $.fn.jqTransInputText = function(){
96             return this.each(function(){
97                    var $input = $(this);
98
99                  if($input.hasClass('jqtranformdone') || !$input.is('input')) {return;}
100                  $input.addClass('jqtranformdone');
101
102                     var oLabel = jqTransformGetLabel($(this));
103                      oLabel && oLabel.bind('click',function(){$input.focus();});
104
105                    var inputSize=$input.width();
106                   if($input.attr('size')){
107                                inputSize = $input.attr('size')*10;
108                             $input.css('width',inputSize);
109                  }
110
111                      $input.addClass("jqTransformInput").wrap('<div class="jqTransformInputWrapper"><div class="jqTransformInputInner"><div></div></div></div>');
112                    var $wrapper = $input.parent().parent().parent();
113                       $wrapper.css("width", inputSize+10);
114                    $input
115                          .focus(function(){$wrapper.addClass("jqTransformInputWrapper_focus");})
116                                 .blur(function(){$wrapper.removeClass("jqTransformInputWrapper_focus");})
117                               .hover(function(){$wrapper.addClass("jqTransformInputWrapper_hover");},function(){$wrapper.removeClass("jqTransformInputWrapper_hover");})
118                      ;
119
120                      /* If this is safari we need to add an extra class */
121                   $.browser.safari && $wrapper.addClass('jqTransformSafari');
122                     $.browser.safari && $input.css('width',$wrapper.width()+16);
123                    this.wrapper = $wrapper;
124
125               });
126     };
127
128     /***************************
129      Check Boxes
130    ***************************/
131   $.fn.jqTransCheckBox = function(){
132              return this.each(function(){
133                    if($(this).hasClass('jqTransformHidden')) {return;}
134
135                    var $input = $(this);
136                   var inputSelf = this;
137
138                  //set the click on the label
139                    var oLabel=jqTransformGetLabel($input);
140                         oLabel && oLabel.click(function(){aLink.trigger('click');});
141
142                   var aLink = $('<a href="#" class="jqTransformCheckbox"></a>');
143                  //wrap and add the link
144                         $input.addClass('jqTransformHidden').wrap('<span class="jqTransformCheckboxWrapper"></span>').parent().prepend(aLink);
145                  //on change, change the class of the link
146                       $input.change(function(){
147                               this.checked && aLink.addClass('jqTransformChecked') || aLink.removeClass('jqTransformChecked');
148                                return true;
149                    });
150                     // Click Handler, trigger the click and change event on the input
151                       aLink.click(function(){
152                                 //do nothing if the original input is disabled
153                          if($input.attr('disabled')){return false;}
154                              //trigger the envents on the input object
155                               $input.trigger('click').trigger("change");
156                              return false;
157                   });
158
159                    // set the default state
160                        this.checked && aLink.addClass('jqTransformChecked');
161           });
162     };
163      /***************************
164      Radio Buttons
165          ***************************/
166   $.fn.jqTransRadio = function(){
167                 return this.each(function(){
168                    if($(this).hasClass('jqTransformHidden')) {return;}
169
170                    var $input = $(this);
171                   var inputSelf = this;
172
173                  oLabel = jqTransformGetLabel($input);
174                   oLabel && oLabel.click(function(){aLink.trigger('click');});
175
176                   var aLink = $('<a href="#" class="jqTransformRadio" rel="'+ this.name +'"></a>');
177                       $input.addClass('jqTransformHidden').wrap('<span class="jqTransformRadioWrapper"></span>').parent().prepend(aLink);
178
179                    $input.change(function(){
180                               inputSelf.checked && aLink.addClass('jqTransformChecked') || aLink.removeClass('jqTransformChecked');
181                           return true;
182                    });
183                     // Click Handler
184                        aLink.click(function(){
185                                 if($input.attr('disabled')){return false;}
186                              $input.trigger('click').trigger('change');
187
188                             // uncheck all others of same name input radio elements
189                                 $('input[name="'+$input.attr('name')+'"]',inputSelf.form).not($input).each(function(){
190                                  $(this).attr('type')=='radio' && $(this).trigger('change');
191                             });
192
193                            return false;
194                   });
195                     // set the default state
196                        inputSelf.checked && aLink.addClass('jqTransformChecked');
197              });
198     };
199
200     /***************************
201      TextArea
202       ***************************/
203   $.fn.jqTransTextarea = function(){
204              return this.each(function(){
205                    var textarea = $(this);
206
207                        if(textarea.hasClass('jqtransformdone')) {return;}
208                      textarea.addClass('jqtransformdone');
209
210                  oLabel = jqTransformGetLabel(textarea);
211                         oLabel && oLabel.click(function(){textarea.focus();});
212
213                         var strTable = '<table cellspacing="0" cellpadding="0" border="0" class="jqTransformTextarea">';
214                        strTable +='<tr><td id="jqTransformTextarea-tl"></td><td id="jqTransformTextarea-tm"></td><td id="jqTransformTextarea-tr"></td></tr>';
215                  strTable +='<tr><td id="jqTransformTextarea-ml">&nbsp;</td><td id="jqTransformTextarea-mm"><div></div></td><td id="jqTransformTextarea-mr">&nbsp;</td></tr>';
216                   strTable +='<tr><td id="jqTransformTextarea-bl"></td><td id="jqTransformTextarea-bm"></td><td id="jqTransformTextarea-br"></td></tr>';
217                  strTable +='</table>';
218                  var oTable = $(strTable)
219                                        .insertAfter(textarea)
220                                  .hover(function(){
221                                              !oTable.hasClass('jqTransformTextarea-focus') && oTable.addClass('jqTransformTextarea-hover');
222                                  },function(){
223                                           oTable.removeClass('jqTransformTextarea-hover');
224                                        })
225                              ;
226
227                      textarea
228                                .focus(function(){oTable.removeClass('jqTransformTextarea-hover').addClass('jqTransformTextarea-focus');})
229                              .blur(function(){oTable.removeClass('jqTransformTextarea-focus');})
230                             .appendTo($('#jqTransformTextarea-mm div',oTable))
231                      ;
232                       this.oTable = oTable;
233                   if($.browser.safari){
234                           $('#jqTransformTextarea-mm',oTable)
235                                     .addClass('jqTransformSafariTextarea')
236                                  .find('div')
237                                            .css('height',textarea.height())
238                                                .css('width',textarea.width())
239                          ;
240                       }
241               });
242     };
243
244     /***************************
245      Select
246         ***************************/
247   $.fn.jqTransSelect = function(){
248                return this.each(function(index){
249                       var $select = $(this);
250
251                         if($select.hasClass('jqTransformHidden')) {return;}
252                     if($select.attr('multiple')) {return;}
253
254                         var oLabel  =  jqTransformGetLabel($select);
255                    /* First thing we do is Wrap it */
256                      var $wrapper = $select
257                          .addClass('jqTransformHidden')
258                          .wrap('<div class="jqTransformSelectWrapper"></div>')
259                           .parent()
260                               .css({zIndex: 1000-index})
261                      ;
262
263                      /* Now add the html for the select */
264                   $wrapper.prepend('<div><span></span><a href="#" class="jqTransformSelectOpen"></a></div><ul></ul>');
265                    var $ul = $('ul', $wrapper).css('width',$select.width()).hide();
266                        /* Now we add the options */
267                    $('option', this).each(function(i){
268                             var oLi = $('<li><a href="#" index="'+ i +'">'+ $(this).html() +'</a></li>');
269                           $ul.append(oLi);
270                        });
271
272                    /* Add click handler to the a */
273                        $ul.find('a').click(function(){
274                                         $('a.selected', $wrapper).removeClass('selected');
275                                      $(this).addClass('selected');
276                                   /* Fire the onchange event */
277                                   if ($select[0].selectedIndex != $(this).attr('index') && $select[0].onchange) { $select[0].selectedIndex = $(this).attr('index'); $select[0].onchange(); }
278                                      $select[0].selectedIndex = $(this).attr('index');
279                                       $('span:eq(0)', $wrapper).html($(this).html());
280                                         $ul.hide();
281                                     return false;
282                   });
283                     /* Set the default */
284                   $('a:eq('+ this.selectedIndex +')', $ul).click();
285                       $('span:first', $wrapper).click(function(){$("a.jqTransformSelectOpen",$wrapper).trigger('click');});
286                   oLabel && oLabel.click(function(){$("a.jqTransformSelectOpen",$wrapper).trigger('click');});
287                    this.oLabel = oLabel;
288
289                  /* Apply the click handler to the Open */
290                       var oLinkOpen = $('a.jqTransformSelectOpen', $wrapper)
291                          .click(function(){
292                                      //Check if box is already open to still allow toggle, but close all other selects
293                                       if( $ul.css('display') == 'none' ) {jqTransformHideSelect();}
294                                   if($select.attr('disabled')){return false;}
295
296                                    $ul.slideToggle('fast', function(){
297                                             var offSet = ($('a.selected', $ul).offset().top - $ul.offset().top);
298                                            $ul.animate({scrollTop: offSet});
299                                       });
300                                     return false;
301                           })
302                      ;
303
304                      // Set the new width
305                    var iSelectWidth = $select.outerWidth();
306                        var oSpan = $('span:first',$wrapper);
307                   var newWidth = (iSelectWidth > oSpan.innerWidth())?iSelectWidth+oLinkOpen.outerWidth():$wrapper.width();
308                        $wrapper.css('width',newWidth);
309                         $ul.css('width',newWidth-2);
310                    oSpan.css({width:iSelectWidth});
311
312                       // Calculate the height if necessary, less elements that the default height
313                     //show the ul to calculate the block, if ul is not displayed li height value is 0
314                       $ul.css({display:'block',visibility:'hidden'});
315                         var iSelectHeight = ($('li',$ul).length)*($('li:first',$ul).height());//+1 else bug ff
316                  (iSelectHeight < $ul.height()) && $ul.css({height:iSelectHeight,'overflow':'hidden'});//hidden else bug with ff
317                         $ul.css({display:'none',visibility:'visible'});
318
319                });
320     };
321      $.fn.jqTransform = function(options){
322           var opt = $.extend({},defaultOptions,options);
323
324                 /* each form */
325                  return this.each(function(){
326                   var selfForm = $(this);
327                         if(selfForm.hasClass('jqtransformdone')) {return;}
328                      selfForm.addClass('jqtransformdone');
329
330                  //$('input:submit, input:reset, input[type="button"]', this).jqTransInputButton();
331                      //$('input:text, input:password', this).jqTransInputText();
332                     //$('input:checkbox', this).jqTransCheckBox();
333                  //$('input:radio', this).jqTransRadio();
334                        //$('textarea', this).jqTransTextarea();
335
336                       if( $('select', this).jqTransSelect().length > 0 ){jqTransformAddDocumentListener();}
337                   selfForm.bind('reset',function(){var action = function(){jqTransformReset(this);}; window.setTimeout(action, 10);});
338
339                   //preloading dont needed anymore since normal, focus and hover image are the same one
340                   /*if(opt.preloadImg && !jqTransformImgPreloaded){
341                               jqTransformImgPreloaded = true;
342                                 var oInputText = $('input:text:first', selfForm);
343                               if(oInputText.length > 0){
344                                      //pour ie on eleve les ""
345                                       var strWrapperImgUrl = oInputText.get(0).wrapper.css('background-image');
346                                       jqTransformPreloadHoverFocusImg(strWrapperImgUrl);
347                                      var strInnerImgUrl = $('div.jqTransformInputInner',$(oInputText.get(0).wrapper)).css('background-image');
348                                       jqTransformPreloadHoverFocusImg(strInnerImgUrl);
349                                }
350
351                              var oTextarea = $('textarea',selfForm);
352                                 if(oTextarea.length > 0){
353                                       var oTable = oTextarea.get(0).oTable;
354                                   $('td',oTable).each(function(){
355                                                 var strImgBack = $(this).css('background-image');
356                                               jqTransformPreloadHoverFocusImg(strImgBack);
357                                    });
358                             }
359                       }*/
360
361
362           }); /* End Form each */
363
364        };/* End the Plugin */
365
366 })(jQuery);