带有ajax的Select2使用Rails turbolinks事件多次初始化

时间:2016-04-08 10:46:46

标签: javascript ruby-on-rails jquery-select2

我正在使用Rails 4.2.6开发Ruby On Rails应用程序。我正在使用Turbolinks和jquery.turbolinks(抱歉,我可以发布这些元素的链接,因为我是网站上的新手)。我的问题很简单,但我无法解决。这里是: 我有一个通过AJAX获取的表单

<div class="card-footer">
  <a class="btn btn-sm btn-primary-outline" data-remote="true"  href="/profiles/Mke5kA/positions/new"><i class="fa fa-plus"></i> Nouvelle expérience professionnelle</a>
  <div id="new_position_form"></div>
</div>

表单包含通过AJAX获取数据的Select2元素

= simple_form_for [profile, position], remote: true, html: {id: 'positionForm', class: 'm-b-1'} do |f|
  = f.input :company_id, as: :select, input_html: {:'data-behaviour' => 'company-select2', :'data-kind' => 'company'}
  = f.input :title
  = f.input :summary
  - location = f.object.build_location
  = f.simple_fields_for :location do |l|
    = render 'locations/fields', l: l, city: position.city
  = render "profiles/shared/date_fields", f: f, model: position
  = f.input :skill_list, as: :select, input_html: {multiple: true, :data => {:behaviour => 'acts-as-taggable', :'taggable-context' => 'skills'}}
  %button.btn.btn-primary{:type => "submit"}= icon('check-square-o', 'Enregistrer')
  = link_to icon('remove', 'Annuler'), 'javascript:void(0)', 
        data: {:'lgnk-behaviour' => "remove-form", :'lgnk-target' => "#positionForm" }, class: 'btn btn-secondary'
  • Select2元素被激活&#34;目前正在Rails Trubolinks活动&#34;页面:加载页面:更新&#34;,但我也尝试了&#34;页面:更改&#34;
  • 获取表单时:select2元素正常(正确激活):

Initial form (after AJAX fetch

当我尝试输入使用AJAX获取数据的Select2时出现我的问题:所有select2都是重复的:

enter image description here

以下是我如何初始化Select2:

var loc_tag = function() {
  $('[data-behaviour="acts-as-taggable"]').not('.select2-hidden-accessible').each (function (index, element) {
    if ($(element).data('value')) {
      var options = $(element).data('value').split(', ');
      $.each(options, function(key, tag){
        $(element).append($('<option selected></option>').val(tag).text(tag));
      });
    }

    $(element).select2({
      ajax: {
        url: "/tags?context="+$(element).data('taggable-context'),
        dataType: 'json',
        headers: {
         "Accept": "application/json"
        },
       delay: 250,
       data: function (params) {
         return {
           q: params.term, // search term
           page: params.page
         };
       },
       processResults: function (data, page) {
         return {
           results: data
         };
      },
      cache: true
    },
    escapeMarkup: function (markup) { return markup; }, // let our custom formatter work
    minimumInputLength: 2,
    tags: true,
    language: "fr",
    theme: "bootstrap",
    width: "100%",
    placeholder: 'Mots clés...'
    });
  });

};
$(document).on('page:load page:update', loc_tag);

我希望Select2元素只被初始化一次(当获取表单时)而不是AJAX响应它们获取它们的数据。我已经尝试了jQuery.not(&#34; .select2-hiden-accessible&#34;)对未使用Select2的元素(select2-hidden-accessible是Select2类添加到初始化的Select2元素),但它不起作用。

非常感谢您的帮助!

5 个答案:

答案 0 :(得分:26)

使用Turbolinks 5和select2时,使用后退按钮返回页面时,select2对象不再附加到<select>(见下面的测试)。返回后创建并附加了一个新的select2对象,但它无法使用。

jack的答案对我不起作用,因为添加了新的select2对象后,<select>仍然有 class='select2-hidden-accessible' ,除其他外,设置width: 1px !important。当创建新的select2对象时,它基本上是不可见的。

对我而言,关键是在TL缓存页面之前销毁所有select2对象。以下是适用于我的解决方案:

$(document).on("turbolinks:before-cache", function() {
  $('.select2-input').select2('destroy');
});

$(document).on('turbolinks:load', function() {
  $('.select2-input').select2();
});

更多详情

我认为这是Turbolinks documentation(强调我的)的正确方法:

  

准备要缓存的页面

     

如果您需要准备,请收听turbolinks:before-cache事件   Turbolinks缓存之前的文档。您可以使用此事件   重置表单,折叠扩展的UI元素,或拆除任何   第三方小部件,以便页面可以再次显示。

测试select2存在

要测试select2对象是否附加到<select>,您可以在控制台中执行以下操作:

('.select2-input').first().data('select2')

答案 1 :(得分:4)

我遇到了同样的问题,我发现按下后退按钮时,selectselect2元素都会被渲染,但它们没有被绑定在一起所以当你用{重新初始化它时{1}}它会在其旁边创建另一个全新的$('select).select2()元素。

所以这是我在初始化select2之前所做的:

如果select2不是select(即select2),但旁边已有$(el).data('select2') == undefined元素,则将其删除。

select2

答案 2 :(得分:2)

我有同样的问题,我通过这样做解决了:

// init.js (you can pass an container instead of using document

$( document ).on('turbolinks:load', function() {
  $( document ).find('select').not('.select2-hidden-accessible').select2();
});

现在我没有那些重复的选择:)

答案 3 :(得分:1)

这里没有什么对我有用。

我完全可以通过使用select缓存页面来解决这个问题。

我在页面顶部使用此选项:<% provide(:no_cache, true) %>

我在application.html.erb

上使用此功能
<% if yield(:no_cache) %>
  <meta name="turbolinks-cache-control" content="no-cache">
<% end %>

答案 4 :(得分:0)

对我有用。即使单击后退,前进或单击其他链接并返回到初始化select2的页面,也不会重复。

Intent.ACTION_HEADSET_PLUG

更新

我看到一些不错的建议here,您可以选择其中之一。我选择将所有javascript移至标记中,而不是将其置于body标记中。