2012-01-03 32 views
8

Im sử dụng danh sách chọn đơn giản và thư viện jquery.dropkick để làm cho nó đẹp. Bây giờ tôi muốn thay đổi nội dung dropkick đó sau khi phần tử chọn tương ứng đã được thay đổi (tùy chọn mới được đưa vào). Nhưng chỉ cần gọi $ ('# select'). Dropkick(); không hoạt động.Cách tải lại đối tượng jquery dropkick

Và có vẻ như nó không được hỗ trợ. Nó sẽ là đủ chỉ để xây dựng lại dropkick đó từ đầu. Có khả năng nào để "phá hủy" đối tượng dropkick đó sau đó xây dựng lại nó bằng cách gọi phương thức .dropkick() không?

Trả lời

23

Tôi đã gặp phải vấn đề tương tự và không thể tìm thấy giải pháp, nhưng cuối cùng đã thành công trong việc thực hiện công việc hack này.

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

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

$select.dropkick(); 
+0

Thanks a lot. Cái đó làm việc cho tôi. – NovumCoder

+0

cảm ơn hoạt động hoàn hảo – privatejava

+0

Cảm ơn! chính xác những gì tôi cần;) –

2

Dành cho khách truy cập mới. Dropkick đã thêm phương thức vẽ lại.

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

Như đã nói ở trên, phương pháp này thực sự là "thiết lập lại" trong Dropkick 1.4. –

12

Đối với khách truy cập mới hơn. Dropkick sử dụng phương pháp đặt lại ... không vẽ lại.

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

Rockin tốt. Làm việc tuyệt vời. Cảm ơn. –

4

Tôi gặp phải vấn đề tương tự, tôi đã thực hiện một số bản vá cho tập lệnh jquery-dropkick-1.0.0 để giải quyết vấn đề này. Tôi đã thêm một phương thức forceSyncWithSelect vào đối tượng dropkick.

Dưới đây là danh sách các thay đổi mà tôi thực hiện:

  • thêm hỗ trợ cho thẻ
  • thêm các thiết lập autoWidth rời rộng để css
  • add phương pháp để mở, đóng, forceSyncWithSelect và isDropkicked
  • giữ tabindex mặc định 0
  • thêm tùy chọn lớp tùy chọn nhóm với thuộc tính data-dkgroupclass trên phần tử optgroup
  • f phương pháp ix forceSyncWithSelect nếu giá trị xuất hiện nhiều thời gian, mất sự xuất hiện đầu tiên chỉ
  • chuyển đổi trên nhấp chuột vào menu lựa chọn
  • ngăn chặn IE từ đóng menu trên tương tác thanh cuộn (một sự kiện mờ được đưa ra trên tương tác thanh cuộn, đây hành vi này rất sai)

Bạn có thể không muốn tất cả những thay đổi đó, nhưng bạn có thể tạo bản vá khác và thực hiện những gì bạn cần (vui lòng ghi nhật ký thay đổi hoặc thêm nguồn vào tiêu đề, Tôi muốn đề xuất những thay đổi đó với Jamie Lottering, nhưng tôi cần phải tạo một tài khoản git hub để làm như vậy.

/** 
* 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

Bạn có thể cắt bớt mã của mình xuống những gì cần thiết để hiểu câu hỏi không? –

14

Tôi thừa hưởng câu trả lời Diode để thay đổi mã dropkick để làm điều này một chút bụi:

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

Thêm mã trên ngay sau khi đoạn sau trong dropkick.js:

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

Sau đó, bạn có thể sử dụng chương trình khác:

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

Như đã nêu trong các bình luận bên dưới, bây giờ bạn có thể gọi $ (selector) .dropkick ('reset') mà không cần sửa đổi lõi; –

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

vui lòng đặt chi tiết ngắn gọn – Muhammed

+0

Cảm ơn vì điều này. Đây là một cách gọn gàng và gọn gàng hơn không có trong tài liệu chính thức. – MountainAsh

Các vấn đề liên quan