jquery.multiselect2side hinzugefĆ¼gt
[kivitendo-erp.git] / js / jquery.multiselect2side.js
1 /*\r
2  * multiselect2side jQuery plugin\r
3  *\r
4  * Copyright (c) 2010 Giovanni Casassa (senamion.com - senamion.it)\r
5  *\r
6  * Dual licensed under the MIT (MIT-LICENSE.txt)\r
7  * and GPL (GPL-LICENSE.txt) licenses.\r
8  *\r
9  * http://www.senamion.com\r
10  *\r
11  */\r
12 \r
13 (function($) {\r
14   jQuery.fn.multiselect2side = function (o) {\r
15     o = $.extend({\r
16       selectedPosition: 'right',\r
17       moveOptions:      true,\r
18       labelTop:         'Top',\r
19       labelBottom:      'Bottom',\r
20       labelUp:          'Up',\r
21       labelDown:        'Down',\r
22       labelSort:        'Sort',\r
23       labelsx:          'Available',\r
24       labeldx:          'Selected',\r
25       maxSelected:      -1\r
26     }, o);\r
27 \r
28     return this.each(function () {\r
29       var el = $(this);\r
30 \r
31       var originalName = $(this).attr("name");\r
32       if (originalName.indexOf('[') != -1)\r
33         originalName = originalName.substring(0, originalName.indexOf('['));\r
34 \r
35       var nameDx = originalName + "ms2side__dx";\r
36       var nameSx = originalName + "ms2side__sx";\r
37       var size   = $(this).attr("size");\r
38       // SIZE MIN\r
39       if (size < 6) {\r
40         $(this).attr("size", "6");\r
41         size = 6;\r
42       }\r
43 \r
44       // UP AND DOWN\r
45       var divUpDown =\r
46         "<div class='ms2side__updown'>" +\r
47         "<p class='SelSort' title='Sort'>" + o.labelSort + "</p>" +\r
48         "<p class='MoveTop' title='Move on top selected option'>" + o.labelTop + "</p>" +\r
49         "<p class='MoveUp' title='Move up selected option'>" + o.labelUp + "</p>" +\r
50         "<p class='MoveDown' title='Move down selected option'>" + o.labelDown + "</p>" +\r
51         "<p class='MoveBottom' title='Move on bottom selected option'>" + o.labelBottom + "</p>" +\r
52         "</div>";\r
53 \r
54       // CREATE NEW ELEMENT (AND HIDE IT) AFTER THE HIDDED ORGINAL SELECT\r
55       var htmlToAdd =\r
56         "<div class='ms2side__div'>" +\r
57         ((o.selectedPosition != 'right' && o.moveOptions) ? divUpDown : "") +\r
58         "<div class='ms2side__select'>" +\r
59         (o.labelsx ? ("<div class='ms2side__header'>" + o.labelsx + "</div>") : "") +\r
60         "<select title='" + o.labelsx + "' name='" + nameSx + "' id='" + nameSx + "' size='" + size + "' multiple='multiple' ></select>" +\r
61         "</div>" +\r
62         "<div class='ms2side__options'>" +\r
63         ((o.selectedPosition == 'right')\r
64          ?\r
65          ("<p class='AddOne' title='Add Selected'>&rsaquo;</p>" +\r
66           "<p class='AddAll' title='Add All'>&raquo;</p>" +\r
67           "<p class='RemoveOne' title='Remove Selected'>&lsaquo;</p>" +\r
68           "<p class='RemoveAll' title='Remove All'>&laquo;</p>")\r
69          :\r
70          ("<p class='AddOne' title='Add Selected'>&lsaquo;</p>" +\r
71           "<p class='AddAll' title='Add All'>&laquo;</p>" +\r
72           "<p class='RemoveOne' title='Remove Selected'>&rsaquo;</p>" +\r
73           "<p class='RemoveAll' title='Remove All'>&raquo;</p>")\r
74         ) +\r
75         "</div>" +\r
76         "<div class='ms2side__select'>" +\r
77         (o.labeldx ? ("<div class='ms2side__header'>" + o.labeldx + "</div>") : "") +\r
78         "<select title='" + o.labeldx + "' name='" + nameDx + "' id='" + nameDx + "' size='" + size + "' multiple='multiple' ></select>" +\r
79         "</div>" +\r
80         ((o.selectedPosition == 'right' && o.moveOptions) ? divUpDown : "") +\r
81         "</div>";\r
82       $(this).after(htmlToAdd).hide();\r
83 \r
84       // ELEMENTS\r
85       var allSel    = $(this).next().find("select");\r
86       var leftSel   = (o.selectedPosition == 'right') ? allSel.eq(0) : allSel.eq(1);\r
87       var rightSel  = (o.selectedPosition == 'right') ? allSel.eq(1) : allSel.eq(0);\r
88       // HEIGHT DIV\r
89       var heightDiv = $(".ms2side__select").eq(0).height();\r
90 \r
91       // CENTER MOVE OPTIONS AND UPDOWN OPTIONS\r
92       $(this).next().find('.ms2side__options, .ms2side__updown').each(function(){\r
93         var     top = ((heightDiv/2) - ($(this).height()/2));\r
94         if (top > 0)\r
95           $(this).css('padding-top',  top + 'px' );\r
96       });\r
97 \r
98       // MOVE SELECTED OPTION TO RIGHT, NOT SELECTED TO LEFT\r
99       $(this).find("option:selected").clone().appendTo(rightSel);\r
100       $(this).find("option:not(:selected)").clone().appendTo(leftSel);\r
101 \r
102       // SELECT FIRST LEFT ITEM\r
103       if (!($.browser.msie && $.browser.version == '6.0'))\r
104         leftSel.find("option").eq(0).attr("selected", true);\r
105 \r
106       // ON CHANGE REFRESH ALL BUTTON STATUS\r
107       allSel.change(function() {\r
108         var div        = $(this).parent().parent();\r
109         var selectSx   = leftSel.children();\r
110         var selectDx   = rightSel.children();\r
111         var selectedSx = leftSel.find("option:selected");\r
112         var selectedDx = rightSel.find("option:selected");\r
113 \r
114         if (selectedSx.size() == 0 || (o.maxSelected >= 0 && (selectedSx.size() + selectDx.size()) > o.maxSelected))\r
115           div.find(".AddOne").addClass('ms2side__hide');\r
116         else\r
117           div.find(".AddOne").removeClass('ms2side__hide');\r
118 \r
119         // FIRST HIDE ALL\r
120         div.find(".RemoveOne, .MoveUp, .MoveDown, .MoveTop, .MoveBottom, .SelSort").addClass('ms2side__hide');\r
121         if (selectDx.size() > 1)\r
122           div.find(".SelSort").removeClass('ms2side__hide');\r
123         if (selectedDx.size() > 0) {\r
124           div.find(".RemoveOne").removeClass('ms2side__hide');\r
125           // ALL SELECTED - NO MOVE\r
126           if (selectedDx.size() < selectDx.size()) {    // FOR NOW (JOE) && selectedDx.size() == 1\r
127             if (selectedDx.val() != selectDx.val())     // FIRST OPTION, NO UP AND TOP BUTTON\r
128               div.find(".MoveUp, .MoveTop").removeClass('ms2side__hide');\r
129             if (selectedDx.last().val() != selectDx.last().val())       // LAST OPTION, NO DOWN AND BOTTOM BUTTON\r
130               div.find(".MoveDown, .MoveBottom").removeClass('ms2side__hide');\r
131           }\r
132         }\r
133 \r
134         if (selectSx.size() == 0 || (o.maxSelected >= 0 && selectSx.size() >= o.maxSelected))\r
135           div.find(".AddAll").addClass('ms2side__hide');\r
136         else\r
137           div.find(".AddAll").removeClass('ms2side__hide');\r
138 \r
139         if (selectDx.size() == 0)\r
140           div.find(".RemoveAll").addClass('ms2side__hide');\r
141         else\r
142           div.find(".RemoveAll").removeClass('ms2side__hide');\r
143       });\r
144 \r
145       // DOUBLE CLICK ON LEFT SELECT OPTION\r
146       leftSel.dblclick(function () {\r
147         $(this).find("option:selected").each(function(i, selected){\r
148 \r
149           if (o.maxSelected < 0 || rightSel.children().size() < o.maxSelected) {\r
150             $(this).remove().appendTo(rightSel);\r
151             el.find("[value=" + $(selected).val() + "]").attr("selected", true).remove().appendTo(el);\r
152           }\r
153         });\r
154         $(this).trigger('change');\r
155       });\r
156 \r
157       // DOUBLE CLICK ON RIGHT SELECT OPTION\r
158       rightSel.dblclick(function () {\r
159         $(this).find("option:selected").each(function(i, selected){\r
160           $(this).remove().appendTo(leftSel);\r
161           el.find("[value=" + $(selected).val() + "]").attr("selected", false).remove().appendTo(el);\r
162         });\r
163         $(this).trigger('change');\r
164       });\r
165 \r
166       // CLICK ON OPTION\r
167       $(this).next().find('.ms2side__options').children().click(function () {\r
168         if (!$(this).hasClass("ms2side__hide")) {\r
169           if ($(this).hasClass("AddOne")) {\r
170             leftSel.find("option:selected").each(function(i, selected){\r
171               $(this).remove().appendTo(rightSel);\r
172               el.find("[value=" + $(selected).val() + "]").attr("selected", true).remove().appendTo(el);\r
173             });\r
174 \r
175           } else if ($(this).hasClass("AddAll")) {        // ALL SELECTED\r
176             leftSel.children().appendTo(rightSel);\r
177             leftSel.children().remove();\r
178             el.find('option').attr("selected", true);\r
179             // el.children().attr("selected", true); -- PROBLEM WITH OPTGROUP\r
180 \r
181           } else if ($(this).hasClass("RemoveOne")) {\r
182             rightSel.find("option:selected").each(function(i, selected){\r
183               $(this).remove().appendTo(leftSel);\r
184               el.find("[value=" + $(selected).val() + "]").attr("selected", false).remove().appendTo(el);\r
185             });\r
186 \r
187           } else if ($(this).hasClass("RemoveAll")) {     // ALL REMOVED\r
188             rightSel.children().appendTo(leftSel);\r
189             rightSel.children().remove();\r
190             el.find('option').attr("selected", false);\r
191             //el.children().attr("selected", false); -- PROBLEM WITH OPTGROUP\r
192           }\r
193         }\r
194 \r
195         leftSel.trigger('change');\r
196       });\r
197 \r
198       // CLICK ON UP - DOWN\r
199       $(this).next().find('.ms2side__updown').children().click(function () {\r
200         var selectedDx = rightSel.find("option:selected");\r
201         var selectDx   = rightSel.find("option");\r
202 \r
203         if (!$(this).hasClass("ms2side__hide")) {\r
204           if ($(this).hasClass("SelSort")) {\r
205             // SORT SELECTED ELEMENT\r
206             selectDx.sort(function(a, b) {\r
207               var compA = $(a).text().toUpperCase();\r
208               var compB = $(b).text().toUpperCase();\r
209               return (compA < compB) ? -1 : (compA > compB) ? 1 : 0;\r
210             })\r
211             // FIRST REMOVE FROM ORIGINAL SELECT\r
212             el.find("option:selected").remove();\r
213             // AFTER ADD ON ORIGINAL AND RIGHT SELECT\r
214             selectDx.each(function() {\r
215               rightSel.append($(this).clone().attr("selected", true));\r
216               el.append($(this).attr("selected", true));\r
217             });\r
218 \r
219           } else if ($(this).hasClass("MoveUp")) {\r
220             var prev = selectedDx.first().prev();\r
221             var hPrev = el.find("[value=" + prev.val() + "]");\r
222 \r
223             selectedDx.each(function() {\r
224               $(this).insertBefore(prev);\r
225               el.find("[value=" + $(this).val() + "]").insertBefore(hPrev);     // HIDDEN SELECT\r
226             });\r
227 \r
228           } else if ($(this).hasClass("MoveDown")) {\r
229             var next = selectedDx.last().next();\r
230             var hNext = el.find("[value=" + next.val() + "]");\r
231 \r
232             selectedDx.each(function() {\r
233               $(this).insertAfter(next);\r
234               el.find("[value=" + $(this).val() + "]").insertAfter(hNext);      // HIDDEN SELECT\r
235             });\r
236 \r
237           } else if ($(this).hasClass("MoveTop")) {\r
238             var first = selectDx.first();\r
239             var hFirst = el.find("[value=" + first.val() + "]");\r
240 \r
241             selectedDx.each(function() {\r
242               $(this).insertBefore(first);\r
243               el.find("[value=" + $(this).val() + "]").insertBefore(hFirst);    // HIDDEN SELECT\r
244             });\r
245 \r
246           } else if ($(this).hasClass("MoveBottom")) {\r
247             var last = selectDx.last();\r
248             var hLast = el.find("[value=" + last.val() + "]");\r
249 \r
250             selectedDx.each(function() {\r
251               last = $(this).insertAfter(last); // WITH last = SAME POSITION OF SELECTED OPTION AFTER MOVE\r
252               hLast = el.find("[value=" + $(this).val() + "]").insertAfter(hLast);      // HIDDEN SELECT\r
253             });\r
254           }\r
255         }\r
256 \r
257         leftSel.trigger('change');\r
258       });\r
259 \r
260       // HOVER ON OPTION\r
261       $(this).next().find('.ms2side__options, .ms2side__updown').children().hover(\r
262         function () {\r
263           $(this).addClass('ms2side_hover');\r
264         },\r
265         function () {\r
266           $(this).removeClass('ms2side_hover');\r
267         }\r
268       );\r
269 \r
270       // UPDATE BUTTON ON START\r
271       leftSel.trigger('change');\r
272       // SHOW WHEN ALL READY\r
273       $(this).next().show();\r
274     });\r
275   };\r
276 })(jQuery);\r