2012-01-03 12 views
8

Im usando una lista de selección simple y la biblioteca jquery.dropkick para que sea hermosa. Ahora quiero cambiar ese contenido dropkick después de que se haya cambiado el elemento de selección correspondiente (una nueva opción entró). Pero simplemente llamando a $ ('# select'). Dropkick(); no funcionaCómo volver a cargar el objeto jquery dropkick

Y parece que no es compatible. Sería suficiente reconstruir ese dropkick desde cero. ¿Hay alguna posibilidad de "destruir" ese objeto dropkick y luego reconstruirlo llamando al método .dropkick()?

Respuesta

23

Me he enfrentado al mismo problema y no he podido encontrar una solución, pero finalmente logré que este truco funcione.

$select = $("#select1"); 
$select.removeData("dropkick"); 
$("#dk_container_select1").remove(); 

$select.append("<option>opt4</option>"); 
$select.append("<option>opt5</option>"); 

$select.dropkick(); 
+0

muchas gracias. Ese trabajó para mí. – NovumCoder

+0

gracias que funciona perfectamente – privatejava

+0

Gracias! exactamente lo que necesito;) –

2

Para visitantes nuevos. Dropkick added redraw method.

$("select").dropkick('redraw'); 
+0

Como se señaló anteriormente, este método en realidad se "reinicia" en Dropkick 1.4. –

12

Para aún más visitantes. Dropkick usa el método de reinicio ... no vuelve a dibujar.

$("select").dropkick('reset'); 
+1

Rockin bueno. Funcionó muy bien. Gracias. –

4

me encontré con el mismo problema, he hecho algunos parches al script jQuery-patada-1.0.0 para resolver este problema. Agregué un método forceSyncWithSelect al objeto dropkick.

He aquí una lista de los cambios que hice:

  • añadir soporte para la etiqueta
  • agregar configuraciones ANCHO AUTO dejar el ancho de css
  • método add para abrir, cerrar, forceSyncWithSelect y isDropkicked
  • torreón tabindex predeterminado 0
  • agregue la opción optgroup class con el atributo data-dkgroupclass en el elemento op
  • f Método ix forceSyncWithSelect si el valor de aparecer varias de tiempo, tomar la primera ocurrencia única
  • de palanca al hacer clic en el menú de selección
  • prevenir la EI se cierre el menú en la interacción barra de desplazamiento (un evento de desenfoque se puso en marcha en la interacción barra de desplazamiento, este comportamiento es tan malo)

puede que no quiera a todos los cambios, pero se puede hacer un parche de diferencias y de tomar lo que necesita (que sería feliz si deja que el registro de cambios o agregar la fuente de la misma en la cabecera, Quiero proponer esos cambios a Jamie Lottering, pero necesito hacer una cuenta de git hub para hacerlo.

/** 
* DropKick 
* 
* Highly customizable <select> lists 
* https://github.com/JamieLottering/DropKick 
* 
* &copy; 2011 Jamie Lottering <http://github.com/JamieLottering> 
*      <http://twitter.com/JamieLottering> 
* 
* Patch: 
* - 2012-03-30 godboutj, add support for <optgroup> tag 
* - 2012-03-30 godboutj, add autoWidth settings to leave width to css 
* - 2012-05-25 godboutj, add method for open, close, forceSyncWithSelect and isDropkicked 
* - 2012-05-25 godboutj, keep default tabindex 0 
* - 2012-08-09 godboutj, add optgroup class option with the data-dkgroupclass attribute on optgroup element 
* - 2012-08-15 godboutj, fix forceSyncWithSelect method if value appear multiple of time, take the first occurrence only 
* - 2012-09-07 godboutj, toggle on click on the menu selection 
* - 2012-09-25 godboutj, prevent IE from closing the menu on scroll bar interaction (a blur event is launched on scroll bar interaction, this behavior is so wrong) 
*/ 
(function ($, window, document) 
{ 

    var ie6 = false; 

    // Help prevent flashes of unstyled content 
    if ($.browser.msie && $.browser.version.substr(0, 1) < 7) 
    { 
     ie6 = true; 
    } else 
    { 
     document.documentElement.className = document.documentElement.className + ' dk_fouc'; 
    } 

    var 
    // Public methods exposed to $.fn.dropkick() 
    methods = {}, 

    // Cache every <select> element that gets dropkicked 
    lists = [], 

    // Convenience keys for keyboard navigation 
    keyMap = { 
     'left': 37, 
     'up': 38, 
     'right': 39, 
     'down': 40, 
     'enter': 13 
    }, 

    // HTML template for the dropdowns 
    dropdownTemplate = [ 
     '<div class="dk_container" id="dk_container_{{ id }}" tabindex="{{ tabindex }}">', 
     '<a class="dk_toggle">', 
      '<span class="dk_label">{{ label }}</span>', 
     '</a>', 
     '<div class="dk_options">', 
      '<ul class="dk_options_inner">', 
      '</ul>', 
     '</div>', 
     '</div>' 
    ].join(''), 

    // HTML template for dropdown options 
    optionTemplate = '<li class="{{ current }}"><a data-dk-dropdown-value="{{ value }}">{{ text }}</a></li>', 
    optionGroupTemplate = '<li class="dk_option_group {{ dataclass }}"><div class="dk_option_group_text">{{ text }}</div></li>', 

    // Some nice default values 
    defaults = { 
     startSpeed: 1000, // I recommend a high value here, I feel it makes the changes less noticeable to the user 
     theme: false, 
     change: false, 
     autoWidth: true 
    }, 

    // Make sure we only bind keydown on the document once 
    keysBound = false 
    ; 

    // Called by using $('foo').dropkick(); 
    methods.init = function (settings) 
    { 
     settings = $.extend({}, defaults, settings); 

     return this.each(function() 
     { 
      var 
      // The current <select> element 
      $select = $(this), 

      // Store a reference to the originally selected <option> element 
      $original = $select.find(':selected').first(), 

      // Save all of the <option> and <optgroup> elements 
      $options = $select.children('option,optgroup'), 

      // We store lots of great stuff using jQuery data 
      data = $select.data('dropkick') || {}, 

      // This gets applied to the 'dk_container' element 
      id = $select.attr('id') || $select.attr('name'), 

      // This gets updated to be equal to the longest <option> element 
      width = settings.width || $select.outerWidth(), 

      // Keep tabindex, even default value 
      tabindex = ($select.attr('tabindex') != null && $select.attr('tabindex') != undefined) ? $select.attr('tabindex') : '', 

      // The completed dk_container element 
      $dk = false, 

      theme 
     ; 

      // Dont do anything if we've already setup dropkick on this element 
      if (data.id) 
      { 
       return $select; 
      } 
      else 
      { 
       data.settings = settings; 
       data.tabindex = tabindex; 
       data.id = id; 
       data.$original = $original; 
       data.$select = $select; 
       data.value = _notBlank($select.val()) || _notBlank($original.attr('value')); 
       data.label = $original.text(); 
       data.options = $options; 
      } 

      // Build the dropdown HTML 
      $dk = _build(dropdownTemplate, data); 

      // Make the dropdown fixed width if desired 
      if (settings.autoWidth) 
      { 
       $dk.find('.dk_toggle').css({ 
        'width': width + 'px' 
       }); 
      } 
      // Hide the <select> list and place our new one in front of it 
      $select.before($dk); 

      // Update the reference to $dk 
      $dk = $('#dk_container_' + id).fadeIn(settings.startSpeed); 

      // Save the current theme 
      theme = settings.theme ? settings.theme : 'default'; 
      $dk.addClass('dk_theme_' + theme); 
      data.theme = theme; 

      // Save the updated $dk reference into our data object 
      data.$dk = $dk; 

      // Save the dropkick data onto the <select> element 
      $select.data('dropkick', data); 

      // Do the same for the dropdown, but add a few helpers 
      $dk.data('dropkick', data); 

      lists[lists.length] = $select; 

      // Focus events 
      $dk.bind('focus.dropkick', function (e) 
      { 
       $dk.addClass('dk_focus'); 
      }).bind('blur.dropkick', function (e) 
      { 
       // Prevent IE from closing the menu on focus loose, 
       // this make the menu close all the time when using the scroll bar 
       if (!$.browser.msie) 
       { 
        $dk.removeClass('dk_open'); 
       } 
       $dk.removeClass('dk_focus'); 
      }); 

      setTimeout(function() 
      { 
       $select.hide(); 
      }, 0); 
     }); 
    }; 

    // Allows dynamic theme changes 
    methods.theme = function (newTheme) 
    { 
     var 
     $select = $(this), 
     list = $select.data('dropkick'), 
     $dk = list.$dk, 
     oldtheme = 'dk_theme_' + list.theme 
    ; 

     $dk.removeClass(oldtheme).addClass('dk_theme_' + newTheme); 

     list.theme = newTheme; 
    }; 

    // Force Value sync 
    methods.forceSyncWithSelect = function() 
    { 
     var 
      $select = $(this), 
      $dk = $select.data('dropkick').$dk, 
      $current = $dk.find("li [data-dk-dropdown-value='" + $select.val() + "']").first() 
     ; 
     _updateFields($current, $dk, true); 
    }; 

    // Reset all <selects and dropdowns in our lists array 
    methods.reset = function() 
    { 
     for (var i = 0, l = lists.length; i < l; i++) 
     { 
      var 
     listData = lists[i].data('dropkick'), 
     $dk = listData.$dk, 
     $current = $dk.find('li').first() 
     ; 

      $dk.find('.dk_label').text(listData.label); 
      $dk.find('.dk_options_inner').animate({ scrollTop: 0 }, 0); 

      _setCurrent($current, $dk); 
      _updateFields($current, $dk, true); 
     } 
    }; 

    methods.close = function() 
    { 
     var 
      $select = $(this), 
      $dk = $select.data('dropkick').$dk 
     ; 
     _closeDropdown($dk); 
    } 

    methods.open = function() 
    { 
     var 
      $select = $(this), 
      $dk = $select.data('dropkick').$dk 
     ; 
     _openDropdown($dk); 
    } 

    methods.isOpen = function() 
    { 
     var 
      $select = $(this), 
      $dk = $select.data('dropkick').$dk 
     ; 
     return _isDropdownOpenned($dk); 
    } 

    methods.toggleOpen = function() 
    { 
     var 
      $select = $(this), 
      $dk = $select.data('dropkick').$dk 
     ; 
     _toggleOpenCloseDropDown($dk); 
    } 

    methods.isDropkicked = function() 
    { 
     var $select = $(this); 
     return $select.data('dropkick') != undefined; 
    } 

    // Expose the plugin 
    $.fn.dropkick = function (method) 
    { 
     if (!ie6) 
     { 
      if (methods[method]) 
      { 
       return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); 
      } else if (typeof method === 'object' || !method) 
      { 
       return methods.init.apply(this, arguments); 
      } 
     } 
    }; 

    // private 
    function _handleKeyBoardNav(e, $dk) 
    { 
     var 
     code = e.keyCode, 
     data = $dk.data('dropkick'), 
     options = $dk.find('.dk_options'), 
     open = $dk.hasClass('dk_open'), 
     current = $dk.find('.dk_option_current'), 
     first = options.find('li').first(), 
     last = options.find('li').last(), 
     next, 
     prev 
    ; 

     switch (code) 
     { 
      case keyMap.enter: 
       if (open) 
       { 
        _updateFields(current.find('a'), $dk); 
        _closeDropdown($dk); 
       } else 
       { 
        _openDropdown($dk); 
       } 
       e.preventDefault(); 
       break; 

      case keyMap.up: 
       prev = current.prev('li'); 
       if (open) 
       { 
        if (prev.length) 
        { 
         _setCurrent(prev, $dk); 
        } else 
        { 
         _setCurrent(last, $dk); 
        } 
       } else 
       { 
        _openDropdown($dk); 
       } 
       e.preventDefault(); 
       break; 

      case keyMap.down: 
       if (open) 
       { 
        next = current.next('li').first(); 
        if (next.length) 
        { 
         _setCurrent(next, $dk); 
        } else 
        { 
         _setCurrent(first, $dk); 
        } 
       } else 
       { 
        _openDropdown($dk); 
       } 
       e.preventDefault(); 
       break; 

      default: 
       break; 
     } 
    } 

    // Update the <select> value, and the dropdown label 
    function _updateFields(option, $dk, reset) 
    { 
     var value, label, data; 

     value = option.attr('data-dk-dropdown-value'); 
     label = option.text(); 
     data = $dk.data('dropkick'); 

     $select = data.$select; 
     $select.val(value); 

     $dk.find('.dk_label').text(label); 

     reset = reset || false; 

     if (data.settings.change && !reset) 
     { 
      data.settings.change.call($select, value, label); 
     } 
    } 

    // Set the currently selected option 
    function _setCurrent($current, $dk) 
    { 
     $dk.find('.dk_option_current').removeClass('dk_option_current'); 
     $current.addClass('dk_option_current'); 

     _setScrollPos($dk, $current); 
    } 

    function _setScrollPos($dk, anchor) 
    { 
     var height = anchor.prevAll('li').outerHeight() * anchor.prevAll('li').length; 
     $dk.find('.dk_options_inner').animate({ scrollTop: height + 'px' }, 0); 
    } 

    // Is dropdown openned function 
    function _isDropdownOpenned($dk) 
    { 
     return $dk.hasClass('dk_open'); 
    } 

    // Close a dropdown 
    function _closeDropdown($dk) 
    { 
     $dk.removeClass('dk_open'); 
    } 

    // Open a dropdown 
    function _openDropdown($dk) 
    { 
     var data = $dk.data('dropkick'); 
     $dk.find('.dk_options').css({ top: $dk.find('.dk_toggle').outerHeight() - 1 }); 
     if (!$dk.hasClass('dk_open')) 
     { 
      $dk.addClass('dk_open'); 
     } 
    } 

    // Toggle dropdown 
    function _toggleOpenCloseDropDown($dk) 
    { 
     if (_isDropdownOpenned($dk)) 
     { 
      _closeDropdown($dk); 
     } 
     else 
     { 
      _openDropdown($dk); 
     } 
    } 

    /** 
    * Turn the dropdownTemplate into a jQuery object and fill in the variables. 
    */ 
    function _build(tpl, view) 
    { 
     var 
     // Template for the dropdown 
      template = tpl, 
     // Holder of the dropdowns options 
      options = [], 
      $dk 
     ; 

     template = template.replace('{{ id }}', view.id); 
     template = template.replace('{{ label }}', view.label); 
     template = template.replace('{{ tabindex }}', view.tabindex); 

     if (view.options && view.options.length) 
     { 
      for (var i = 0, l = view.options.length; i < l; i++) 
      { 
       var 
        $option = $(view.options[i]), 
        current = 'dk_option_current', 
        oTemplate = optionTemplate, 
        gTemplate = optionGroupTemplate 
       ; 

       if ($option.is('optgroup')) 
       { 
        gTemplate = gTemplate.replace('{{ text }}', $option.attr('label')); 
        if ($option.attr('data-dkgroupclass') != undefined) 
        { 
         gTemplate = gTemplate.replace('{{ dataclass }}', $option.attr('data-dkgroupclass')); 
        } 
        // Support only one level as per W3C standard 
        $option.children('option').each(
         function (index, element) 
         { 
          oTemplate = optionTemplate, 
          oTemplate = oTemplate.replace('{{ value }}', $(element).val()); 
          oTemplate = oTemplate.replace('{{ current }}', (_notBlank($(element).val()) === view.value) ? current : ''); 
          oTemplate = oTemplate.replace('{{ text }}', $(element).text()); 
          gTemplate += oTemplate; 
         } 
        ); 

        options[options.length] = gTemplate; 
       } 
       else 
       { 
        oTemplate = oTemplate.replace('{{ value }}', $option.val()); 
        oTemplate = oTemplate.replace('{{ current }}', (_notBlank($option.val()) === view.value) ? current : ''); 
        oTemplate = oTemplate.replace('{{ text }}', $option.text()); 

        options[options.length] = oTemplate; 
       } 
      } 
     } 

     $dk = $(template); 
     $dk.find('.dk_options_inner').html(options.join('')); 

     return $dk; 
    } 

    function _notBlank(text) 
    { 
     return ($.trim(text).length > 0) ? text : false; 
    } 

    $(function() 
    { 

     // Handle click events on the dropdown toggler 
     $('.dk_toggle').live('click', function (e) 
     { 
      var $dk = $(this).parents('.dk_container').first(); 

      _toggleOpenCloseDropDown($dk); 

      if ("ontouchstart" in window) 
      { 
       $dk.addClass('dk_touch'); 
       $dk.find('.dk_options_inner').addClass('scrollable vertical'); 
      } 

      e.preventDefault(); 
      return false; 
     }); 

     // Handle click events on individual dropdown options 
     $('.dk_options a').live(($.browser.msie ? 'mousedown' : 'click'), function (e) 
     { 
      var 
     $option = $(this), 
     $dk = $option.parents('.dk_container').first(), 
     data = $dk.data('dropkick') 
     ; 

      _closeDropdown($dk); 
      _updateFields($option, $dk); 
      _setCurrent($option.parent(), $dk); 

      e.preventDefault(); 
      return false; 
     }); 

     // Setup keyboard nav 
     $(document).bind('keydown.dk_nav', function (e) 
     { 
      var 
      // Look for an open dropdown... 
     $open = $('.dk_container.dk_open'), 

      // Look for a focused dropdown 
     $focused = $('.dk_container.dk_focus'), 

      // Will be either $open, $focused, or null 
     $dk = null 
     ; 

      // If we have an open dropdown, key events should get sent to that one 
      if ($open.length) 
      { 
       $dk = $open; 
      } else if ($focused.length && !$open.length) 
      { 
       // But if we have no open dropdowns, use the focused dropdown instead 
       $dk = $focused; 
      } 

      if ($dk) 
      { 
       _handleKeyBoardNav(e, $dk); 
      } 
     }); 
    }); 
})(jQuery, window, document); 
+2

¿Podría ajustar su código a lo necesario para comprender la pregunta? –

14

I apalancado respuesta de diodo para modificar el código de Dropkick para hacer esto un poco más limpio:

// Reload the dropkick select widget after options have changed 
// usage: $("...").dropkick('reload'); 
methods.reload = function() { 
    var $select = $(this); 
    var data = $select.data('dropkick'); 
    $select.removeData("dropkick"); 
    $("#dk_container_"+ data.id).remove(); 
    $select.dropkick(data.settings); 
}; 

Añadir el código de arriba a la derecha después de que el siguiente fragmento de patada.JS:

methods.reset = function() { 
    ... 
}; 

continuación, puede utilizar mediante programación:

$('#my-select').html("<option>new options</option>"); 
    $('#my-select').dropkick('reload'); 
+0

Como se menciona en otros comentarios a continuación, ahora puede llamar a $ (selector) .dropkick ('restablecer') sin necesidad de modificar el núcleo; –

2
$('#select').html('<option>a</option>').dropkick('refresh'); 
+0

por favor ponga detalles breves – Muhammed

+0

Gracias por esto. Esta es una forma mucho más limpia y concisa que no está en la documentación oficial. – MountainAsh

Cuestiones relacionadas