2013-03-14 11 views
14

Próbuję dodać pole daty do mojego formularza.Zmiany w formularzu nie są zapisywane w bazie danych

Dodałem klejnot bootstrap-datepicker-rails, wszystkie wymagane css i javascript.

Po wybraniu daty w kalendarzu i kliknięciu Zapisz, nie jest ona aktualizowana w bazie danych.

Oto kod w postaci:

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

myślę, że może to mieć związek z formatów, ale nie wiem gdzie patrzeć.

Aktualizacja

Działa przy zmianie domyślnego formatu do rrrr-mm-dd (domyślnie jest dd/mm/rrrr):

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

Odpowiedz

5

I napotkał podobny problem i format konwersji w tworzenie działanie rozwiązać go dla mnie:

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

po prostu odpowiedział na podobne pytanie here i obejmowały moją odpowiedź poniżej:


Musiałem także uzyskać tej pracy i wspierać wiele języków, które nie korzystają US centric formaty dat, np: en-AU (Australia), który ma format daty dd/mm/rrrr.

problem

Rails spodziewa format daty, aby być yyyy-mm-dd z przeglądarki, ale chcesz wyświetlić datę w lokalizacji użytkownika. Podczas gdy kontrola daty pozwala ci określić format wyświetlania, NIE pozwala ci osobno określać formatu, który ma być odesłany do serwera.

Rozwiązanie

Zbuduj pole wejściowe ukryte który wysyła odpowiedni format z powrotem do serwera szyn. Robię to za pomocą niestandardowego formantu wejściowego simple_form, który buduje zarówno pole wejściowe do wyboru daty, jak i ukryte pole, i używa niektórych javascript do konwersji na datę rails, kiedy zmienia się kontrola wprowadzania.

Skutek jest taki, można mieć ładny bootstrap Date-próbnik w szynach i używać go z simple_form następująco:

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

Albo użyć długiego formatu daty:

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

Wdrożenie

Utwórz lub edytuj następujące pliki:

Gemfile

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

config/locales/pl-UA.yml

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

config/locales/pl-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/stylów/application.css.scss

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

app/assets/javascripts/application.js.coffee

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

Alternatywnie APP/obrotowe/JavaScript/application.js

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

APP/obrotowe/JavaScript/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

Niesamowite odpowiedź, dziękuję za to, po prostu wskazując się, że format daty w lokalizacji powinna być następująca: '' ' data: datepicker: default: "% m /% d /% Y" długo: "% B% d,% Y" formaty: domyślnie: "% m /% d /% Y" long:! "% B% d,% Y" '' ' Zobacz http://apidock.com/ruby/DateTime/strftime – X2theZ

+0

Dzięki, zredagowaliśmy odpowiedź, aby odzwierciedlić poprawny ciąg znaków –

0

Odpowiedź Andrew Hackinga była dla mnie dobra, z dwoma drobnymi zmianami na app/inputs/bootstrap_datepicker_input.rb. Używam Rails 4.2.0. Ignorował wartość w ukrytym polu jako duplikat (ponieważ dane wejściowe i ukryte dane wejściowe mają identyczne atrybuty "nazwa"). Przeszedłem:

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

... do tego:

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

Również traciłem opcje otoki, więc dodałem argument do input i połączyła opcje otoki do opcji html.

to:

def input 
    text_field_options = input_html_options.with_indifferent_access 
    ... 

... stała:

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

Ive użył anwser z Andrew. Udało mi się to dobrze, tyle tylko, że nie wyświetlało poprawnych zlokalizowanych nazw miesięcy (na przykład lipiec zamiast Juli).

Oto moje podejście, jeśli chcesz użyć zlokalizowanej wersji swojego date_picker.

Domyślnie gem-datepicker gem ładuje wszystkie wersje językowe.

Jeśli chcesz na przykład załadować tylko wersję angielską i niemiecką, musisz zmienić aplikację .js

z

//= require bootstrap-datepicker 

do

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

kroku Nest jest zmiana BootstrapDatepickerInput

Co chcemy teraz jest to, że język jest dynamicznie wybrane dane parametr.

więc dodać poniższy wiersz do ciebie klasę wejściowe wewnątrz metody wprowadzania

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

Naszym zdaniem możemy nazwać teraz postać z

= f.input :your_attribute_name, as: :bootstrap_datepicker, input_html: { locale: locale } 
Powiązane problemy