【问题标题】:Changes in the form are not saved to database表单中的更改不会保存到数据库
【发布时间】:2013-03-02 14:11:33
【问题描述】:

我正在尝试将日期字段添加到我的表单中。

我添加了 bootstrap-datepicker-rails gem,所有必需的 css 和 javascript。

当我在日历中选择日期并单击保存时,它不会在数据库中更新。

这是表单的代码:

= simple_form_for @model
  = f.input :date_last, :required => true, 
            :input_html => { data: {behaviour: "datepicker"}}, 
            :as => :string
  = f.button :submit, 'Save', :class => 'btn btn-primary'

我认为这可能与格式有关,但不确定在哪里查看。

更新

当我将默认格式更改为 yyyy-mm-dd(默认为 mm/dd/yyyy)时,它可以工作:

$('[data-behaviour~=datepicker]').datepicker({"format": "yyyy-mm-dd", "weekStart": 1, "autoclose": true});

【问题讨论】:

    标签: ruby-on-rails-3 twitter-bootstrap datepicker simple-form


    【解决方案1】:

    我刚刚回答了一个类似的问题here,并在下面包含了我的答案:


    我还需要让它工作并支持不使用以美国为中心的日期格式的多个区域设置,例如:日期格式为 dd/mm/yyyy 的 en-AU(澳大利亚)。

    问题

    Rails 期望浏览器的日期格式为yyyy-mm-dd,但您希望在用户的区域设置中显示日期。虽然日期控件允许您指定显示格式,但它不允许您单独指定要发送回服务器的格式。

    解决方案

    构建一个隐藏的输入字段,将正确的格式发送回您的 Rails 服务器。我使用自定义 simple_form 输入控件执行此操作,该控件构建日期选择器输入字段和隐藏字段,并在输入控件更改时使用一些 javascript 转换为 rails 日期。

    结果是您可以在 rails 中拥有一个不错的引导日期选择器,并将其与 simple_form 一起使用,如下所示:

    <%= f.input :date, as: :bootstrap_datepicker %>
    

    或者使用长日期格式:

    <%= f.input :date, as: :bootstrap_datepicker, input_html: { format: :long } %>
    

    实施

    创建或编辑以下文件:

    宝石文件

    gem 'bootstrap-sass'
    gem 'bootstrap-datepicker-rails'
    

    config/locales/en-AU.yml

    en-AU:
      date:
        datepicker:
          default: "dd/mm/yyyy"
          long: "dd MM, yyyy"
        formats:
          default: ! '%d/%m/%Y'
          long: ! '%d %B, %Y'
    

    config/locales/en-US.yml

    en-US:
      date:
        datepicker:
          default: "mm/dd/yyyy"
          long: "MM dd, yyyy"
        formats:
          default: "%m/%d/%Y"
          long: ! '%B %d, %Y'
    

    app/assets/stylesheets/application.css.scss

    @import "bootstrap-responsive";
    @import "bootstrap-datepicker";
    

    app/assets/javascripts/application.js.coffee

    #= require bootstrap
    #= require bootstrap-datepicker
    #= require bootstrap-datepicker-rails
    

    或者,app/assets/javascripts/application.js

    //= require bootstrap
    //= require bootstrap-datepicker
    //= require bootstrap-datepicker-rails
    

    app/assets/javascripts/bootstrap-datepicker-rails.js.coffee

    $ ->
      # convert bootstrap-datepicker value to rails date format (yyyy-mm-dd) on our hidden field
      $(document).on 'changeDate', '.bootstrap-datepicker', (evt) ->
        rails_date = evt.date.getFullYear() + '-' + ('0' + (evt.date.getMonth() + 1)).slice(-2) + '-' + ('0' + evt.date.getDate()).slice(-2)
        $(this).next("input[type=hidden]").val(rails_date)
    

    app/inputs/bootstrap_datepicker_input.rb

    class BootstrapDatepickerInput < SimpleForm::Inputs::Base
      def input
        text_field_options = input_html_options.with_indifferent_access
        format =  text_field_options.delete(:format)
        hidden_field_options = text_field_options.dup
        hidden_field_options[:class] = text_field_options[:class].dup # so they won't work with same array object
        hidden_field_options[:id] = "#{attribute_name}_hidden"
        text_field_options[:class] << 'bootstrap-datepicker'
        text_field_options[:type] = 'text'
        text_field_options[:value] ||= format_date(value(object), format)
        set_data_option text_field_options, 'date-format', I18n.t(format, scope: [:date, :datepicker], default: :default)
        default_data_option text_field_options, 'provide', 'datepicker'
    
        return_string =
          "#{@builder.text_field(attribute_name, text_field_options.to_hash)}\n" +
          "#{@builder.hidden_field(attribute_name, hidden_field_options.to_hash)}\n"
        return return_string.html_safe
      end
    
    protected
    
      def default_data_option(hash, key, value)
        set_data_option(hash,key,value) unless data_option(hash, key)
      end
    
      def data_option(hash, key)
        hash[:data].try(:[],key) || hash["data-#{key}"]
      end
    
      def set_data_option(hash, key, value)
        hash[:data].try(:[]=,key,value) || (hash["data-#{key}"] = value)
      end
    
      def value(object)
        object.send @attribute_name if object
      end
    
      def format_date(value, format=nil)
        value.try(:strftime, I18n.t(format, scope: [ :date, :formats ], default: :default))
      end
    end
    

    【讨论】:

    • 很棒的答案,谢谢,只是指出语言环境中的日期格式应如下所示:``` date: datepicker: default: "%m/%d/%Y" long : "%B %d, %Y" 格式: 默认: "%m/%d/%Y" long: ! '%B %d, %Y' ``` 见apidock.com/ruby/DateTime/strftime
    • 谢谢,编辑答案以反映正确的格式字符串
    【解决方案2】:

    我遇到了类似的问题,在创建操作中转换格式为我解决了这个问题:

    def create
         .....
         @person.dob = DateTime.strptime(params[:person][:dob], '%m/%d/%Y').to_date
         .....
         @person.save
         .....
    end
    

    【讨论】:

      【解决方案3】:

      Andrew Hacking 的回答对我很有帮助,对 app/inputs/bootstrap_datepicker_input.rb 做了两个小改动。我正在使用 Rails 4.2.0。它忽略了隐藏字段中的值作为重复项(因为文本输入和隐藏输入具有相同的“名称”属性)。我换了:

      "#{@builder.text_field(attribute_name, text_field_options.to_hash)}\n"
      

      ...对此:

      "#{@builder.text_field(attribute_name.to_s+'_box',text_field_options.to_hash)}\n" +
      

      另外,我丢失了包装器选项,因此我向input 添加了一个参数,并将包装器选项合并到 html 选项中。

      这个:

      def input
          text_field_options = input_html_options.with_indifferent_access
          ...
      

      ...变成:

      def input(wrapper_options)
          merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)
          text_field_options = merged_input_options.with_indifferent_access
          ...
      

      【讨论】:

        【解决方案4】:

        我使用了 Andrew 的 anwser。它对我来说效果很好,只是它没有正确显示本地化的月份名称(例如 July 而不是 Juli)。

        如果您想为 date_picker 使用本地化版本,这是我的方法。

        默认情况下,bootsrap-datepicker gem 会加载所有语言版本。

        例如,如果您只想加载英文和德文版本,则必须更改 application.js

        来自

        //= require bootstrap-datepicker
        

        //= require bootstrap-datepicker/core
        //= require bootstrap-datepicker/locales/bootstrap-datepicker.en-GB.js
        //= require bootstrap-datepicker/locales/bootstrap-datepicker.de.js
        

        嵌套步骤是更改 BootstrapDatepickerInput

        我们现在想要的是从给定参数中动态选择语言。

        所以在输入法里面添加下面一行到你的Input类

        set_data_option text_field_options, 'date-language', input_html_options[:locale]
        

        在我们看来,我们现在可以调用表单

        = f.input :your_attribute_name, as: :bootstrap_datepicker, input_html: { locale: locale }
        

        【讨论】:

          猜你喜欢
          • 2019-01-22
          • 2020-08-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-10-07
          • 2012-07-16
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多