ruby-on-rails Select2 with acrons使用Rails turbolinks事件初始化多次

az31mfrm  于 12个月前  发布在  Ruby
关注(0)|答案(7)|浏览(172)

我正在使用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>

字符串
表单包含Select 2元素,这些元素通过AJAX获取数据

= 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'

  • Select 2元素目前在Rails Trubolinks事件“page:load page:update”中被“激活”,但我也尝试过“page:change”
  • 获取表单时:select 2元素正常(正确激活):

x1c 0d1x的数据
当我尝试输入使用AJAX获取数据的Select 2时,出现了我的问题:所有的Select 2都是重复的:



下面是我如何初始化Select 2:

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


我希望Select 2元素只初始化一次(当表单被获取时),而不是在AJAX响应时获取它们的数据。我已经尝试过jQuery.not(“.select2-hidden-accessible”)在不使用Select 2的元素上(select 2-hidden-accessible是Select 2添加到初始化的Select 2元素中的类),但它不起作用。
非常感谢您的帮助!

unftdfkk

unftdfkk1#

当使用Turbolinks 5和select 2时,当使用后退按钮返回到页面时,select2对象不再附加到<select>(参见下面的测试)。返回后会创建一个新的select2对象并附加,但它无法使用。
jack的回答对我不起作用,因为当新的select2对象被添加时,<select>仍然有**class='select2-hidden-accessible',其中,设置了width: 1px !important。当新的select2对象被创建时,它基本上是不可见的。
对我来说,关键是
在TL缓存页面之前销毁所有select 2对象**。以下是对我有效的解决方案:

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

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

字符串

查看详情

我相信这是正确的方法,给出了Turbolinks文档(强调我的):

准备缓存页面

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

测试select2兼容性

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

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

2vuwiymt

2vuwiymt2#

2021年更新

使用turbolinks:before-cache

document.addEventListener('turbolinks:before-cache', function () {
  // removing the select2 from all selects
  $("select").select2('destroy');
});

字符串
并在turbolinks:load时加载select2:

document.addEventListener("turbolinks:load", function () {
  // applying select2 to all selects
  $("select").select2({
    theme: 'bootstrap4' // if you want to pass some custom config
  });
});


当然,您可以创建一个自定义的.select2-binder类或data-select2-binder来选择将受影响的选择。
我遇到了同样的问题,我通过这样做来解决:

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

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


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

d6kp6zgx

d6kp6zgx3#

我也有同样的问题,我发现当你按下后退按钮时,selectselect2元素都被渲染,但它们没有绑定在一起,所以当你用$('select).select2()重新初始化它时,它会在它旁边创建另一个全新的select2元素。
下面是我在初始化select2之前所做的:
如果select不是select2(即$(el).data('select2') == undefined),但它旁边已经有一个select2元素,则删除它。

if ($(el).data('select2') == undefined && $(el).next().hasClass('select2-container')) {
  $(el).next().remove();
}
$(el).select2();

字符串

wydwbb8l

wydwbb8l4#

rails 7和select2.js用户注意事项。

在rails 7版本中,turbo-links被弃用。新库的名称是turbo. https://turbo.hotwired.dev/handbook/drive您可以将下面的标记添加到html的head部分以防止缓存。因此select2.js现在可以正常工作。文档

<meta name="turbo-visit-control" content="reload">

字符串

qlckcl4x

qlckcl4x5#

这里没有什么对我有用。
我能够通过不缓存带有select的页面来完全解决这个问题。
我在页面顶部使用了select:<% provide(:no_cache, true) %>
我在application.html.erb上使用这个:

<% if yield(:no_cache) %>
  <meta name="turbolinks-cache-control" content="no-cache">
<% end %>

字符串

q9rjltbz

q9rjltbz6#

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

document.addEventListener("turbolinks:load", function() {
  $('.select2-container').remove() // this will remove all the select2 containers
  $('.select2-input').select2(); // and this will reinit the select2 again
})

字符串

更新

我看到了一些很好的建议here,你可以选择其中之一。我选择将所有的JavaScript移动到标签中,而不是将它们放在body标签中。

brtdzjyr

brtdzjyr7#

Rails 7缓存更新

这里的很多东西在Rails 7中都不起作用,特别是turbolinks:before-cache事件。您正在寻找的新事件是turbo:before-cache,和turbo:load,因此它看起来像这样:

$(document).on("turbo:before-cache", function() {
    $("#select_id").select2('destroy');
});

$(document).on('turbo:load', function() {
    $('#select_id').select2();
});

字符串

相关问题