views:

5880

answers:

4

I am using the excellent jQuery MultiSelect plugin as advertised here: http://abeautifulsite.net/notebook/62

The problem I have is that I would like to submit the form when the values have changed. Having all sorts of trouble getting this one working, does anyone have insight into how to achieve this?

Also open to alternative jQuery plugins/scripts if there are any that handle this nicely.

+1  A: 

Have you tried attaching it directly to the multiselect callback?

$(document).ready( function() {
    $("#control_id").multiSelect(options, function() {
        $('#myFormId').submit();
    });
});
Chris Pebble
Yes, however the callback is called each time one of the options is checked/unchecked, as opposed to the hide/finish event. So the page will submit in the middle of the selection process.
Toby Hede
+2  A: 

You could try patching jQueryMultiSelect (Untested)

Line:34 --

multiSelect: function(o, callback ) {

Line:34 ++

multiSelect: function(o, callback, postback) {

Line 221: ++

if( postback ) postback($(this));

Full Codez

if(jQuery) (function($){

 $.extend($.fn, {
  multiSelect: function(o, callback, postback) {
   // Default options
   if( !o ) var o = {};
   if( o.selectAll == undefined ) o.selectAll = true;
   if( o.selectAllText == undefined ) o.selectAllText = "Select All";
   if( o.noneSelected == undefined ) o.noneSelected = 'Select options';
   if( o.oneOrMoreSelected == undefined ) o.oneOrMoreSelected = '% selected';

   // Initialize each multiSelect
   $(this).each( function() {
    var select = $(this);
    var html = '<input type="text" readonly="readonly" class="multiSelect" value="" style="cursor: default;" />';
    html += '<div class="multiSelectOptions" style="position: absolute; z-index: 99999; display: none;">';
    if( o.selectAll ) html += '<label class="selectAll"><input type="checkbox" class="selectAll" />' + o.selectAllText + '</label>';
    $(select).find('OPTION').each( function() {
     if( $(this).val() != '' ) {
      html += '<label><input type="checkbox" name="' + $(select).attr('name') + '" value="' + $(this).val() + '"';
      if( $(this).attr('selected') ) html += ' checked="checked"';
      html += ' />' + $(this).html() + '</label>';
     }
    });
    html += '</div>';
    $(select).after(html);

    // Events
    $(select).next('.multiSelect').mouseover( function() {
     $(this).addClass('hover');
    }).mouseout( function() {
     $(this).removeClass('hover');
    }).click( function() {
     // Show/hide on click
     if( $(this).hasClass('active') ) {
      $(this).multiSelectOptionsHide();
     } else {
      $(this).multiSelectOptionsShow();
     }
     return false;
    }).focus( function() {
     // So it can be styled with CSS
     $(this).addClass('focus');
    }).blur( function() {
     // So it can be styled with CSS
     $(this).removeClass('focus');
    });

    // Determine if Select All should be checked initially
    if( o.selectAll ) {
     var sa = true;
     $(select).next('.multiSelect').next('.multiSelectOptions').find('INPUT:checkbox').not('.selectAll').each( function() {
      if( !$(this).attr('checked') ) sa = false;
     });
     if( sa ) $(select).next('.multiSelect').next('.multiSelectOptions').find('INPUT.selectAll').attr('checked', true).parent().addClass('checked');
    }

    // Handle Select All
    $(select).next('.multiSelect').next('.multiSelectOptions').find('INPUT.selectAll').click( function() {
     if( $(this).attr('checked') == true ) $(this).parent().parent().find('INPUT:checkbox').attr('checked', true).parent().addClass('checked'); else $(this).parent().parent().find('INPUT:checkbox').attr('checked', false).parent().removeClass('checked');
    });

    // Handle checkboxes
    $(select).next('.multiSelect').next('.multiSelectOptions').find('INPUT:checkbox').click( function() {
     $(this).parent().parent().multiSelectUpdateSelected(o);
     $(this).parent().parent().find('LABEL').removeClass('checked').find('INPUT:checked').parent().addClass('checked');
     $(this).parent().parent().prev('.multiSelect').focus();
     if( !$(this).attr('checked') ) $(this).parent().parent().find('INPUT:checkbox.selectAll').attr('checked', false).parent().removeClass('checked');
     if( callback ) callback($(this));
    });

    // Initial display
    $(select).next('.multiSelect').next('.multiSelectOptions').each( function() {
     $(this).multiSelectUpdateSelected(o);
     $(this).find('INPUT:checked').parent().addClass('checked');
    });

    // Handle hovers
    $(select).next('.multiSelect').next('.multiSelectOptions').find('LABEL').mouseover( function() {
     $(this).parent().find('LABEL').removeClass('hover');
     $(this).addClass('hover');
    }).mouseout( function() {
     $(this).parent().find('LABEL').removeClass('hover');
    });

    // Keyboard
    $(select).next('.multiSelect').keydown( function(e) {
     // Is dropdown visible?
     if( $(this).next('.multiSelectOptions').is(':visible') ) {
      // Dropdown is visible
      // Tab
      if( e.keyCode == 9 ) {
       $(this).addClass('focus').trigger('click'); // esc, left, right - hide
       $(this).focus().next(':input').focus();
       return true;
      }

      // ESC, Left, Right
      if( e.keyCode == 27 || e.keyCode == 37 || e.keyCode == 39 ) {
       // Hide dropdown
       $(this).addClass('focus').trigger('click');
      }
      // Down
      if( e.keyCode == 40 ) {
       if( !$(this).next('.multiSelectOptions').find('LABEL').hasClass('hover') ) {
        // Default to first item
        $(this).next('.multiSelectOptions').find('LABEL:first').addClass('hover');
       } else {
        // Move down, cycle to top if on bottom
        $(this).next('.multiSelectOptions').find('LABEL.hover').removeClass('hover').next('LABEL').addClass('hover');
        if( !$(this).next('.multiSelectOptions').find('LABEL').hasClass('hover') ) {
         $(this).next('.multiSelectOptions').find('LABEL:first').addClass('hover');
        }
       }
       return false;
      }
      // Up
      if( e.keyCode == 38 ) {
       if( !$(this).next('.multiSelectOptions').find('LABEL').hasClass('hover') ) {
        // Default to first item
        $(this).next('.multiSelectOptions').find('LABEL:first').addClass('hover');
       } else {
        // Move up, cycle to bottom if on top
        $(this).next('.multiSelectOptions').find('LABEL.hover').removeClass('hover').prev('LABEL').addClass('hover');
        if( !$(this).next('.multiSelectOptions').find('LABEL').hasClass('hover') ) {
         $(this).next('.multiSelectOptions').find('LABEL:last').addClass('hover');
        }
       }
       return false;
      }
      // Enter, Space
      if( e.keyCode == 13 || e.keyCode == 32 ) {
       // Select All
       if( $(this).next('.multiSelectOptions').find('LABEL.hover INPUT:checkbox').hasClass('selectAll') ) {
        if( $(this).next('.multiSelectOptions').find('LABEL.hover INPUT:checkbox').attr('checked') ) {
         // Uncheck all
         $(this).next('.multiSelectOptions').find('INPUT:checkbox').attr('checked', false).parent().removeClass('checked');
        } else {
         // Check all
         $(this).next('.multiSelectOptions').find('INPUT:checkbox').attr('checked', true).parent().addClass('checked');
        }
        $(this).next('.multiSelectOptions').multiSelectUpdateSelected(o);
        if( callback ) callback($(this));
        return false;
       }
       // Other checkboxes
       if( $(this).next('.multiSelectOptions').find('LABEL.hover INPUT:checkbox').attr('checked') ) {
        // Uncheck
        $(this).next('.multiSelectOptions').find('LABEL.hover INPUT:checkbox').attr('checked', false);
        $(this).next('.multiSelectOptions').multiSelectUpdateSelected(o);
        $(this).next('.multiSelectOptions').find('LABEL').removeClass('checked').find('INPUT:checked').parent().addClass('checked');
        // Select all status can't be checked at this point
        $(this).next('.multiSelectOptions').find('INPUT:checkbox.selectAll').attr('checked', false).parent().removeClass('checked');
        if( callback ) callback($(this));
       } else {
        // Check
        $(this).next('.multiSelectOptions').find('LABEL.hover INPUT:checkbox').attr('checked', true);
        $(this).next('.multiSelectOptions').multiSelectUpdateSelected(o);
        $(this).next('.multiSelectOptions').find('LABEL').removeClass('checked').find('INPUT:checked').parent().addClass('checked');
        if( callback ) callback($(this));
       }
      }
      return false;
     } else {
      // Dropdown is not visible
      if( e.keyCode == 38 || e.keyCode == 40 || e.keyCode == 13 || e.keyCode == 32 ) { // down, enter, space - show
       // Show dropdown
       $(this).removeClass('focus').trigger('click');
       $(this).next('.multiSelectOptions').find('LABEL:first').addClass('hover');
       return false;
      }
      //  Tab key
      if( e.keyCode == 9 ) {
       // Shift focus to next INPUT element on page
       $(this).focus().next(':input').focus();
       return true;
      }
     }
     // Prevent enter key from submitting form
     if( e.keyCode == 13 ) return false;
    });

    // Eliminate the original form element
    $(select).remove();
   });

  },

  // Hide the dropdown
  multiSelectOptionsHide: function() {
   $(this).removeClass('active').next('.multiSelectOptions').hide();
   if( postback ) postback($(this));
  },

  // Show the dropdown
  multiSelectOptionsShow: function() {
   // Hide any open option boxes
   $('.multiSelect').multiSelectOptionsHide();
   $(this).next('.multiSelectOptions').find('LABEL').removeClass('hover');
   $(this).addClass('active').next('.multiSelectOptions').show();

   // Position it
   var offset = $(this).offset();
   $(this).next('.multiSelectOptions').css({ top:  offset.top + $(this).outerHeight() + 'px' });
   $(this).next('.multiSelectOptions').css({ left: offset.left + 'px' });

   // Disappear on hover out
   multiSelectCurrent = $(this);
   var timer = '';
   $(this).next('.multiSelectOptions').hover( function() {
    clearTimeout(timer);
   }, function() {
    timer = setTimeout('$(multiSelectCurrent).multiSelectOptionsHide(); $(multiSelectCurrent).unbind("hover");', 250);
   });

  },

  // Update the textbox with the total number of selected items
  multiSelectUpdateSelected: function(o) {
   var i = 0, s = '';
   $(this).find('INPUT:checkbox:checked').not('.selectAll').each( function() {
    i++;
   })
   if( i == 0 ) {
    $(this).prev('INPUT.multiSelect').val( o.noneSelected );
   } else {
    if( o.oneOrMoreSelected == '*' ) {
     var display = '';
     $(this).find('INPUT:checkbox:checked').each( function() {
      if( $(this).parent().text() != o.selectAllText ) display = display + $(this).parent().text() + ', ';
     });
     display = display.substr(0, display.length - 2);
     $(this).prev('INPUT.multiSelect').val( display );
    } else {
     $(this).prev('INPUT.multiSelect').val( o.oneOrMoreSelected.replace('%', i) );
    }
   }
  }

 });

})(jQuery);
garrow
Found a very dodgy hack based on this solution that is too dodgy to post (involving global_variables tied to my specific requirements), but is graced by the actual value of working correctly. Cheers
Toby Hede
A: 

i just come across the exact problem. is there any update? or can the hack be shared?

mango
A: 

I m also facing same problem on page post back control is not maintaining its viewstate

Tahseen