--- 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);