【问题标题】:simple_form custom input with content_for javascript head?带有 content_for javascript 头的 simple_form 自定义输入?
【发布时间】:2019-02-12 21:19:04
【问题描述】:

我正在使用datepicker 并想创建一个自定义的 simple_form 输入

目前我在每个表单上都这样做:

<link rel="stylesheet" href="/datepicker/master/dist/datepicker.min.css">
<script src="/datepicker/master/dist/datepicker.min.js"></script>

<%= simple_form_for(myobj) do |f| %>
  <%= f.input :some_date, as: :string, input_html: {class: "datepicker", onchange: "this.form.submit();", autocomplete: "off"} %>
<% end %>

<script>
  $(function() {
    $(".datepicker").datepicker({format: "yyyy-mm-dd"});
  });
</script>

第一次之后这很烦人,所以我创建了一个自定义输入:

# app/inputs/datepicker_input.rb
class DatepickerInput < SimpleForm::Inputs::Base
  def input(wrapper_options={})
    wrapper_options.symbolize_keys!
    wrapper_options[:input_html] ||= {class: 'datepicker', onchange: 'this.form.submit();', autocomplete: 'off'}
    merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)

    template.content_for(:head) do
      [
        template.stylesheet_link_tag('https://rawgit.com/fengyuanchen/datepicker/master/dist/datepicker.min.css'),
        template.javascript_include_tag('https://rawgit.com/fengyuanchen/datepicker/master/dist/datepicker.min.js')
      ].join.html_safe
    end

    js = <<JS
<script type="text/javascript">
$(function() {$(".datepicker").datepicker({format: "yyyy-mm-dd"});});
</script>
JS

    template.content_for(:javascript) { js.html_safe }
    @builder.text_field(attribute_name, merged_input_options).html_safe
  end
end

这让我可以:

<%= simple_form_for(myobj) do |f| %>
  <%= f.input :some_date, as: :my_datepicker %>
<% end %>

不幸的是,它多次包含 JS/CSS,但还没有找到合适的解决方案来防止它。

【问题讨论】:

    标签: ruby-on-rails simple-form


    【解决方案1】:

    这是一个 simple_form 日期选择器自定义输入:

    # app/inputs/datepicker_input.rb
    class DatepickerInput < SimpleForm::Inputs::Base
      def input(wrapper_options={})
        wrapper_options.symbolize_keys!
        wrapper_options[:input_html] ||= {class: 'datepicker', onchange: 'this.form.submit();', autocomplete: 'off'}
        merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)
    
        unless template.instance_variable_get(:@submitted_content_for_head)
          # prevents from being inserted twice
          template.instance_variable_set(:@submitted_content_for_head, true)
          template.content_for(:head) do
            [
              template.stylesheet_link_tag('https://rawgit.com/fengyuanchen/datepicker/master/dist/datepicker.min.css'),
              template.javascript_include_tag('https://rawgit.com/fengyuanchen/datepicker/master/dist/datepicker.min.js')
            ].join.html_safe
          end
        end
    
        unless template.instance_variable_get(:@submitted_content_for_footer)
          # prevents from being inserted twice
          template.instance_variable_set(:@submitted_content_for_footer, true)
    
          js = <<JS
    <script type="text/javascript">
    $(function() {$(".datepicker").datepicker({format: "yyyy-mm-dd"});});
    </script>
    JS
    
          template.content_for(:javascript) { js.html_safe }
        end
    
        @builder.text_field(attribute_name, merged_input_options).html_safe
      end
    end
    

    【讨论】:

      【解决方案2】:

      我会简单地在主模板中移动 CSS/JS 文件以及 JavaScript sn-p,而不用担心通过自定义输入添加这些文件。甚至将它们编译到主 CSS 和 JS 文件中以避免页面加载时的额外调用。

      【讨论】:

      • 如果只有 1% 的人使用包含的日期选择器访问 FORM,那么在每个页面加载时都包含 JS 和 CSS 是很浪费的
      • 浪费什么?介意解释吗?如果你想走这条路,你可能想看看 jQuery 本身。显然你正在使用它。当你使用的概率低于 10% 时,在每次页面加载时加载整个 jQuery 是多么“浪费”。
      猜你喜欢
      • 1970-01-01
      • 2014-10-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-12
      • 2010-09-21
      • 1970-01-01
      相关资源
      最近更新 更多