Rails 4 + simple_form和jQuery UI。通过turbolinks,日期选择器无法工作

10

我有一个表单需要调用日期选择器:

...
<%= f.input :expiration_date, as: :datepicker, required: false %>
...

简单表单包装器: app/inputs/datepicker_input.rb

class DatepickerInput < SimpleForm::Inputs::Base
  def input
    @builder.text_field(attribute_name, input_html_options) + \
    @builder.hidden_field(attribute_name, { :class => attribute_name.to_s + "-alt"})
  end
end

当页面从头开始加载时($(document).ready事件),会生成以下html:

<input class="datepicker optional form-control hasDatepicker" id="order_expiration_date" name="order[expiration_date]" type="text">

然而,当使用 turbolinks(通过侧边栏,“page:load”事件加载页面)加载页面时,渲染的 HTML 如下:

<input class="datepicker optional form-control" id="order_expiration_date" name="order[expiration_date]" type="text">

当然,我可以在.html.erb文件或application.js文件中简单地添加hasDatepicker类,但我想知道是否可能通过Rails功能来实现它。

3个回答

13

我终于找到了一个合适的解决方法:

app/inputs/datepicker_input.rb 保持不变,包装器工作正常。

assets/javascripts/application.js

//= require jquery
//= require jquery_ujs
//= require turbolinks
//= require bootstrap.js
//= require_tree .

$(document).on("page:load ready", function(){
    $("input.datepicker").datepicker();
});

由于 :datepicker 输入类型会将 ".datepicker" 类添加到渲染的 HTML 中,只需将 datepicker() 绑定到具有该类的所有元素即可。这样做可以用最少的代码实现目的。

重要的是要指定 "input.datepicker",因为 ".datepicker" 类会同时添加到标签和输入标记中。

turbolinks 会抛出 page:load 事件,因此我已经为两种情况添加了处理程序 - 当页面从 turbolinks 加载时以及当页面从头开始加载时(窗口刷新、链接保存在收藏夹中等)。

现在,以下 .html.erb 渲染出的内容符合我的期望:

<%= f.input :expiration_date, as: :datepicker, required: false,
    :placeholder => 'Select date', input_html: {class: "form-control"},
    label: "Expiration date: " %>

输出:

<div class="control-group datepicker optional order_expiration_date">
  <label class="datepicker optional control-label" for="order_expiration_date">Expiration date: </label>
  <div class="controls">
    <input class="datepicker optional form-control hasDatepicker" id="order_expiration_date" name="order[expiration_date]" placeholder="Select date" type="text">
    <input class="expiration_date-alt" id="order_expiration_date" name="order[expiration_date]" type="hidden">
  </div>
</div>

page:load ready 对我没有起作用。 反而page:change 起了作用。 - Anwar
简单表单已废除没有使用wrapper_options输入的自定义输入。这是一个更新版本的 datepicker_input.rb,支持包装器:https://gist.github.com/shrmnk/e5577b2a2176193cfbd6b92462cf5923 - shrmn

3
以下是我在简单表单和jquery-ui中的解决方法:
js: $('input#date_field').datepicker();
表格: <%= f.text_field :expiration_date,:placeholder =>'选择日期'%> 这样做不需要使用as: datepicker。

1

试试这个:

<%= f.text_field :expiration_date, as: :datepicker, :placeholder => 'Select Expiration Date' %>

JavaScript
 $(document).ready(function() {
    $('#order_expiration_date').datepicker({
        changeMonth: true,
        changeYear: true,
        yearRange: '-70:-18'
    });
  });

"

app/assets/javascript/application.js应该是:

"
//= require jquery
//= require jquery.turbolinks
//= require jquery_ujs
//= require jquery.ui.all
//= require turbolinks

这基本上就是我最初的想法。我在 turbolinks 的 page:load 事件上遇到了问题,我试图避免为单个元素调用 datepicker(),因为我有几个表单需要出现 datepicker。 - Extrapolator

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接