Changes in the form are not saved to database

后端 未结 4 1305
轻奢々
轻奢々 2020-12-08 03:16

I\'m trying to add a date field to my form.

I added bootstrap-datepicker-rails gem, all required css and javascript.

When I choose the date in the calendar a

相关标签:
4条回答
  • 2020-12-08 03:52

    Andrew Hacking's answer worked great for me, with two small changes to app/inputs/bootstrap_datepicker_input.rb. I'm using Rails 4.2.0. It was ignoring the value in the hidden field as a duplicate (since the text input and hidden input have identical "name" attributes). I switched:

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

    ... to this:

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

    Also, I was losing wrapper options, so I added an argument to input and merged the wrapper options into the html options.

    This:

    def input
        text_field_options = input_html_options.with_indifferent_access
        ...
    

    ... became:

    def input(wrapper_options)
        merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)
        text_field_options = merged_input_options.with_indifferent_access
        ...
    
    0 讨论(0)
  • 2020-12-08 04:06

    I encountered similar problem and converting format in create action solved it for me:

    def create
         .....
         @person.dob = DateTime.strptime(params[:person][:dob], '%m/%d/%Y').to_date
         .....
         @person.save
         .....
    end
    
    0 讨论(0)
  • I just answered a similar question here and have included my answer below:


    I also needed to get this working and support multiple locales that do not use US centric date formats, eg: en-AU (Australia) which has the date format dd/mm/yyyy.

    The Problem

    Rails expects the date format to be yyyy-mm-dd from the browser, yet you want to display the date in the user's locale. Whilst the date control allows you to specify the format for display it does NOT allow you to separately specify the format to be sent back to the server.

    The Solution

    Build a hidden input field that sends the correct format back to your rails server. I do this with with a custom simple_form input control that builds both the date-picker input field and a hidden field, and use some javascript to convert to the rails date when the input control changes.

    The upshot is you can have a nice bootstrap date-picker in rails and use it with simple_form as follows:

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

    Or to use a long date format:

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

    Implementation

    Create or edit the following files:

    Gemfile

    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
    

    Alternatively, 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
    
    0 讨论(0)
  • 2020-12-08 04:11

    I´ve used the anwser from Andrew. It worked well for me, except that it not displayed the localized month names correct (For example July instead of Juli).

    Here is my approach, if you want to use a localized version for your date_picker.

    By default the bootsrap-datepicker gem loads all language versions.

    If you want for example to load only the english and german version you have to change application.js

    from

    //= require bootstrap-datepicker
    

    to

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

    Nest step is to change BootstrapDatepickerInput

    What we want now is that the language is dynamically choosen from a given parameter.

    so add the following line to you Input class inside of the input method

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

    In our view we can call now the form with

    = f.input :your_attribute_name, as: :bootstrap_datepicker, input_html: { locale: locale }
    
    0 讨论(0)
提交回复
热议问题