2013-09-02 6 views
13

Sto cercando di integrare bootstrap 3 con simple_forms (dal master).caselle di controllo Bootstrap 3 + simple_forms

In questo momento, ho le seguenti:

config/inizializzatori/simple_form.rb:

SimpleForm.setup do |config| 
    config.wrappers :default, class: :input, 
    hint_class: :field_with_hint, error_class: :field_with_errors do |b| 
    b.use :html5 
    b.use :placeholder 
    b.optional :maxlength 
    b.optional :pattern 
    b.optional :min_max 
    b.optional :readonly 
    b.use :label_input 
    b.use :hint, wrap_with: { tag: :span, class: :hint } 
    b.use :error, wrap_with: { tag: :span, class: :error } 
    end 

    config.default_wrapper = :default 
    config.boolean_style = :nested 
    config.button_class = 'btn' 
end 

config/inizializzatori/simple_form_bootstrap.rb:

SimpleForm.setup do |config| 
    config.input_class = 'form-control' 

    config.wrappers :bootstrap, tag: 'div', class: 'form-group', error_class: 'error' do |b| 
    b.use :html5 
    b.use :placeholder 
    b.use :label 
    b.wrapper tag: 'div', class: 'controls' do |ba| 
     ba.use :input 
     ba.use :error, wrap_with: { tag: 'span', class: 'help-inline' } 
     ba.use :hint, wrap_with: { tag: 'p', class: 'help-block' } 
    end 
    end 

    config.wrappers :prepend, tag: 'div', class: "form-group", error_class: 'error' do |b| 
    b.use :html5 
    b.use :placeholder 
    b.use :label 
    b.wrapper tag: 'div', class: 'controls' do |input| 
     input.wrapper tag: 'div', class: 'input-prepend' do |prepend| 
     prepend.use :input 
     end 
     input.use :hint, wrap_with: { tag: 'span', class: 'help-block' } 
     input.use :error, wrap_with: { tag: 'span', class: 'help-inline' } 
    end 
    end 

    config.wrappers :append, tag: 'div', class: "form-group", error_class: 'error' do |b| 
    b.use :html5 
    b.use :placeholder 
    b.use :label 
    b.wrapper tag: 'div', class: 'controls' do |input| 
     input.wrapper tag: 'div', class: 'input-append' do |append| 
     append.use :input 
     end 
     input.use :hint, wrap_with: { tag: 'span', class: 'help-block' } 
     input.use :error, wrap_with: { tag: 'span', class: 'help-inline' } 
    end 
    end 

    config.default_wrapper = :bootstrap 
end 

app/views/devise/sessions/new.html.haml

%div.panel.panel-auth 
    %div.panel-heading 
    %h3.panel-title Sign in 
    %div.panel-body 
    = simple_form_for(resource, :as => resource_name, :url => session_path(resource_name)) do |f| 
     .form-inputs 
     = f.input :email, :required => false, :autofocus => true 
     = f.input :password, :required => false 
     = f.input :remember_me, :as => :boolean if devise_mapping.rememberable? 
     .form-actions 
     = f.button :submit, "Sign in" 
     %hr 
    = render "devise/shared/links" 

Ma l'HTML generato è sbagliato. Bene, è giusto secondo BS2, ma sbagliato in BS3. Eccolo:

<div class="form-group boolean optional user_remember_me"> 
    <label class="boolean optional control-label" for="user_remember_me"> 
    Remember me 
    </label> 
    <div class="controls"> 
    <input name="user[remember_me]" type="hidden" value="0"> 
    <label class="checkbox"> 
     <input class="boolean optional form-control" id="user_remember_me" name="user[remember_me]" type="checkbox" value="1"> 
    </label> 
    </div> 
</div> 

Ma in realtà dovrebbe essere qualcosa di simile:

<div class="checkbox"> 
    <label> 
     <input type="checkbox"> Check me out 
    </label> 
    </div> 

E 'probabilmente possibile fissare questa incisione intorno involucri, ma non riesco a farlo funzionare. Qualcuno può darmi qualche consiglio a riguardo?

Acclamazioni

risposta

12

Come hai detto tu, è possibile farlo funzionare con un wrapper personalizzato:

config.wrappers :checkbox, tag: :div, class: "checkbox", error_class: "has-error" do |b| 

    # Form extensions 
    b.use :html5 

    # Form components 
    b.wrapper tag: :label do |ba| 
     ba.use :input 
     ba.use :label_text 
    end 

    b.use :hint, wrap_with: { tag: :p, class: "help-block" } 
    b.use :error, wrap_with: { tag: :span, class: "help-block text-danger" } 
    end 

che poi fa riferimento in ingresso:

= f.input :remember_me, :as => :boolean, :wrapper => :checkbox if devise_mapping.rememberable? 

Nota tuttavia questo ha vinto' t lavoro per collection_check_boxes:

= f.input :roles, as: :check_boxes, wrapper: :checkbox, collection: @employee_roles, label: false 

Si potrebbe provare a hackerare insieme un input personalizzato per quest'ultimo caso, ma è un po 'caotico. Forse qualcun altro conosce un modo migliore ... e forse simple_form raggiungerà presto Bootstrap 3.

+4

non ha funzionato. Aggiunge ancora la classe 'form-control', che rovina tutto. :/ – caarlos0

+0

Aggiunge una classe "form-control"? Non lo vedo nel tuo inizializzatore ... a meno che tu non intendessi "form-group"? In caso contrario, potrebbe accadere qualcos'altro (forse un input personalizzato?). Assicurati di riavviare il server dopo aver modificato l'inizializzatore simple_form_bootstrap.rb, altrimenti la modifica non avrà effetto. Appena testato di nuovo sul mio capo e funziona bene con "wrapper:: checkbox" nella riga di input. – mwalsher

+0

Ricorda che sto usando anche il ramo master di simple_form (versione 3.0.0) ... è possibile che ci sia stato un cambiamento dalla versione a cui fa riferimento rubygems (2.1.0). Prova a cambiare il tuo riferimento su gemfile a: "gem 'simple_form', github: 'plataformatec/simple_form'" e l'aggiornamento gem corrente – mwalsher

2

configurazione seguente funziona perfettamente per me con bootstrap 3:

SimpleForm.setup do |config| 
    ... 
    config.boolean_style = :inline 
    ... 
end 

semplice wrapper personalizzato

config.wrappers :inline_checkbox, :tag => 'div', :class => 'checkbox', :error_class => 'has-error' do |b| 
    b.use :html5 
    b.use :placeholder 
    b.use :label_input 
end 

Usage:

= f.input :remember_me, :label => t('user.remember_me'), :as => :boolean, :wrapper => :inline_checkbox 
+0

Utilizzando la versione di rilascio di Bootstrap 3 e Simple Form 3.0.0 questo funziona perfettamente, dove la risposta accettata da @mwalsher ora funziona. –

+0

Lo metti in simple_form.rb o simple_form_bootstrap.rb? – ahnbizcad

0

Ho prossimi requisiti per la mia casella di controllo:

<div class="checkbox"> 
    <input type="hidden" value="0" name="..."> 
    <label> 
     <input type="checkbox" value="1" name="..."> Label text 
    </label> 
</div> 

L'input nascosto è stato estratto dall'etichetta poiché non seleziona la casella di spunta sull'etichetta. Non so perché, ma non ero in grado di generare, quali HTML usando solo config ecco config + abitudine classe di ingresso

# Config 
config.wrappers :checkbox, tag: :div, class: "checkbox", error_class: "has-error" do |b| 
    # Form extensions 
    b.use :html5 
    b.use :placeholder 

    b.use :input 

    b.use :hint, wrap_with: { tag: :p, class: "help-block" } 
    b.use :error, wrap_with: { tag: :span, class: "help-block text-danger" } 
end 

# Input goes to app/inputs/inline_checkbox_input.rb 
class InlineCheckboxInput < SimpleForm::Inputs::Base 
    def input 
    out = '' 
    out << @builder.hidden_field(attribute_name, value: 0).html_safe 
    out << "<label>" 
    out << @builder.check_box(attribute_name, {}, 1, nil) 
    out << "#{options[:label]}</label>" 
    out 
    end 
end 

# Usage 
= f.input :name, :label => 'Label text', :wrapper => :checkbox, :as => :inline_checkbox 
+0

inline_checkbox genera errori. – ahnbizcad

0

Si può semplicemente utilizzare questo:

<%= f.input :remember_me, as: :boolean, :label => false, :inline_label => "Remember me" if devise_mapping.rememberable? %> 
+0

Tutti continuano a consigliare questa soluzione, ma non funziona per me. – ahnbizcad

1

ho trovato davvero un semplice soluzione per le caselle di controllo Bootstrap 3. Supponendo che hai già il wrapper bootstrap 3 configurato, tutto quello che dovevo fare è aggiungere un ingresso personalizzato in app/inputs come checkbox_input.rb:

class CheckboxInput < SimpleForm::Inputs::BooleanInput 
    # this exists to make the default 'boolean' css class in the form-group to be 'checkbox' instead 
end 

e usarlo tramite: = f.input :remember_me, :as => :checkbox if devise_mapping.rememberable?

Questo cambierà il css boolean su il form-group deve essere checkbox invece, che otterrà lo stile corretto.

Allo stesso modo, qui è una versione per radio-inline

class RadioInlineInput < SimpleForm::Inputs::CollectionRadioButtonsInput 

    # by default, this omits labels. You should use f.label before this to stick a label where you would like. 
    def initialize(builder, attribute_name, column, input_type, options = {}) 
    super(builder, attribute_name, column, :radio_buttons, {label: false}.merge(options)) 
    end 

    def item_wrapper_class 
    'radio-inline' 
    end 
end 

Usato come:

= f.label :frequency 
= f.input :frequency, collection: @membership_plan.interval_frequencies, as: :radio_inline