web/data/cubicweb.widgets.js
changeset 9377 4e0d8f06efbc
parent 8260 5a81fa526b30
child 9388 4c34a63bd113
--- a/web/data/cubicweb.widgets.js	Thu Aug 01 09:39:43 2013 +0200
+++ b/web/data/cubicweb.widgets.js	Wed Jan 08 14:00:31 2014 +0100
@@ -544,105 +544,77 @@
 // IE things can not handle hide/show options on select, this cloned list solition (should propably have 2 widgets)
 
 (function ($) {
-    var defaultSettings = {
-        bindDblClick: true
-    };
+
     var methods = {
-        __init__: function(fromSelect, toSelect, options) {
-            var settings = $.extend({}, defaultSettings, options);
-            var bindDblClick = settings['bindDblClick'];
-            var $fromNode = $(cw.jqNode(fromSelect));
-            var clonedSelect = $fromNode.clone();
-            var $toNode = $(cw.jqNode(toSelect));
-            var $addButton = $(this.find('.cwinoutadd')[0]);
-            var $removeButton = $(this.find('.cwinoutremove')[0]);
-            // bind buttons
-            var name = this.attr('id');
-            var instanceData = {'fromNode':fromSelect,
-                                'toNode':toSelect,
-                                'cloned':clonedSelect,
-                                'bindDblClick':bindDblClick,
-                                'name': name};
-            $addButton.bind('click', {'instanceData':instanceData}, methods.inOutWidgetAddValues);
-            $removeButton.bind('click', {'instanceData':instanceData}, methods.inOutWidgetRemoveValues);
-            if(bindDblClick){
-                $toNode.bind('dblclick', {'instanceData': instanceData}, methods.inOutWidgetRemoveValues);
-            }
-            methods.inOutWidgetRemplaceSelect($fromNode, $toNode, clonedSelect, bindDblClick, name);
-        },
+        __init__: function(fromSelect, toSelect) {
+            // closed over state
+            var state = {'$fromNode' : $(cw.escape('#' + fromSelect)),
+                         '$toNode'   : $(cw.escape('#' + toSelect)),
+                         'name'      : this.attr('id')};
 
-        inOutWidgetRemplaceSelect: function($fromNode, $toNode, clonedSelect, bindDblClick, name){
-             var $newSelect = clonedSelect.clone();
-             $toNode.find('option').each(function() {
-                 $newSelect.find('$(this)[value='+$(this).val()+']').remove();
-              });
-             var fromparent = $fromNode.parent();
-             if (bindDblClick) {
-                 //XXX jQuery live binding does not seem to work here
-                 $newSelect.bind('dblclick', {'instanceData': {'fromNode':$fromNode.attr('id'),
-                                     'toNode': $toNode.attr('id'),
-                                     'cloned':clonedSelect,
-                                     'bindDblClick':bindDblClick,
-                                     'name': name}},
-                                 methods.inOutWidgetAddValues);
-             }
-             $fromNode.remove();
-             fromparent.append($newSelect);
-        },
+            function sortoptions($optionlist) {
+                var $sorted = $optionlist.find('option').sort(function(opt1, opt2) {
+                    return $(opt1).text() > $(opt2).text() ? 1 : -1;
+                });
+                // this somehow translates to an inplace sort
+                $optionlist.append($sorted);
+            };
+            sortoptions(state.$fromNode);
+            sortoptions(state.$toNode);
 
-        inOutWidgetAddValues: function(event){
-            var $fromNode = $(cw.jqNode(event.data.instanceData.fromNode));
-            var $toNode = $(cw.jqNode(event.data.instanceData.toNode));
-            $fromNode.find('option:selected').each(function() {
-                var option = $(this);
-                var newoption = OPTION({'value':option.val()},
-	 			 value=option.text());
-                $toNode.append(newoption);
-                var hiddenInput = INPUT({
-                    type: "hidden", name: event.data.instanceData.name,
-                    value:option.val()
+            // will move selected options from one list to the other
+            // and call an option handler on each option
+            function moveoptions ($fromlist, $tolist, opthandler) {
+                $fromlist.find('option:selected').each(function(index, option) {
+                    var $option = $(option);
+                    // add a new option to the target list
+                    $tolist.append(OPTION({'value' : $option.val()},
+	 			          $option.text()));
+                    // process callback on the option
+                    opthandler.call(null, $option);
+                    // remove option from the source list
+                    $option.remove();
                 });
-                $toNode.parent().append(hiddenInput);
-            });
-            methods.inOutWidgetRemplaceSelect($fromNode, $toNode, event.data.instanceData.cloned,
-                                              event.data.instanceData.bindDblClick,
-                                              event.data.instanceData.name);
-            // for ie 7 : ie does not resize correctly the select
-            if($.browser.msie && $.browser.version.substr(0,1) < 8){
-                var p = $toNode.parent();
-                var newtoNode = $toNode.clone();
-                if (event.data.instanceData.bindDblClick) {
-                    newtoNode.bind('dblclick', {'fromNode': $fromNode.attr('id'),
-                                                'toNode': $toNode.attr('id'),
-                                                'cloned': event.data.instanceData.cloned,
-                                                'bindDblClick': true,
-                                                'name': event.data.instanceData.name},
-                                   methods.inOutWidgetRemoveValues);
-                }
-                $toNode.remove();
-                p.append(newtoNode);
-            }
-        },
+                // re-sort both lists
+                sortoptions($fromlist);
+                sortoptions($tolist);
+            };
+
+            function addvalues () {
+                moveoptions(state.$fromNode, state.$toNode, function ($option) {
+                    // add an hidden input for the edit controller
+                    var hiddenInput = INPUT({
+                        type: 'hidden', name: state.name,
+                        value : $option.val()
+                    });
+                    state.$toNode.parent().append(hiddenInput);
+                });
+            };
 
-        inOutWidgetRemoveValues: function(event){
-            var $fromNode = $(cw.jqNode(event.data.instanceData.toNode));
-            var $toNode = $(cw.jqNode(event.data.instanceData.fromNode));
-            var name = event.data.instanceData.name.replace(':', '\\:');
-            $fromNode.find('option:selected').each(function(){
-                var option = $(this);
-                var newoption = OPTION({'value':option.val()},
-	 			 value=option.text());
-                option.remove();
-                $fromNode.parent().find('input[name]='+ name).each(function() {
-                    $(this).val()==option.val()?$(this).remove():null;
-               });
-            });
-            methods.inOutWidgetRemplaceSelect($toNode, $fromNode,  event.data.instanceData.cloned,
-                                              event.data.instanceData.bindDblClick,
-                                              event.data.instanceData.name);
+            function removevalues () {
+                moveoptions(state.$toNode, state.$fromNode, function($option) {
+                    // remove hidden inputs for the edit controller
+                    var selector = 'input[name=' + cw.escape(state.name) + ']'
+                    state.$toNode.parent().find(selector).each(function(index, input) {
+                        if ($(input).val() == $option.val()) {
+                            $(input).remove();
+                        }
+                    });
+                });
+            };
+
+            var $this = $(this);
+            $this.find('.cwinoutadd').bind( // 'add >>>' symbol
+                'click', {'state' : state}, addvalues);
+            $this.find('.cwinoutremove').bind( // 'remove <<<' symbol
+                'click', {'state' : state}, removevalues);
+
+            state.$fromNode.bind('dblclick', {'state': state}, addvalues);
+            state.$toNode.bind('dblclick', {'state': state}, removevalues);
+
         }
     };
-    $.fn.cwinoutwidget = function(fromSelect, toSelect, options){
-        return methods.__init__.apply(this, [fromSelect, toSelect, options]);
+    $.fn.cwinoutwidget = function(fromSelect, toSelect) {
+        return methods.__init__.apply(this, [fromSelect, toSelect]);
     };
-})(jQuery);
\ No newline at end of file
+})(jQuery);