I have started using Simple-form and Bootstrap and I have tried to follow this reference: Simple form + Bootstrap but I don't know what is going on because when a field is failing, here is what happens:
Regarding this screenshot I have a question:
1) As you see, the Price field is not being red surrounded. How can I do that?
Here is my code for the form:
<%= simple_form_for #lesson, :html => { :class => 'well' } do |lesson_form| %>
<% if lesson_form.error_notification %>
<div class="alert alert-error fade in">
<a class="close" data-dismiss="alert" href="#">×</a>
<%= lesson_form.error_notification %>
</div>
<% end %>
<%= lesson_form.input :title %>
<%= lesson_form.input :category %>
<%= lesson_form.input :description %>
<%= lesson_form.input :price %>
<%= lesson_form.button :submit, :label => 'Create', :class => 'btn btn-primary btn-large' %>
<% end -%>
I believe the code in your reference is somewhat misleading and incorrect insofar as error notifications go.
Change:
<% if lesson_form.error_notification %>
<div class="alert alert-error fade in">
<a class="close" data-dismiss="alert" href="#">×</a>
<%= lesson_form.error_notification %>
</div>
<% end %>
to, simply:
<%= lesson_form.error_notification %>
Then, in config/locals/simple_form.en.yml, change default_message to:
default_message: '<a class="close" data-dismiss="alert">×</a>Some errors were found, please take a look:'
This will fix the asymmetry in the error alert box (by fixing the resultant markup).
In order to troubleshoot the issue with your validation error not displaying in red, you'll have to share the markup so we can see what's going on.
Look at the text next to the price field. Simple for puts the errors next to the field.
To clean up your forms look trying the follow:
Remove this, its not needed with simple-form gem:
<% if lesson_form.error_notification %>
<div class="alert alert-error fade in">
<a class="close" data-dismiss="alert" href="#">×</a>
<%= lesson_form.error_notification %>
</div>
<% end %>
Change your :html => { :class => 'well' } to :html => { :class => 'well form-horizontal' }
This will layout your form better and apply bootstrap css to error fields and text.
Related
I'm maintaining an older Rails 3.2.22 app and I'm trying to add a modal to pop up with a simple form to add a note.
Here is my view (cut down for readability)
<% #assigned.each do |call| %>
<%= link_to "Notes", '#ajax-modal', data: { toggle: "modal", target: "#note-modal" }, class: 'btn btn-small btn-inverse' %>
<%= render 'layouts/note_modal', :call => call %>
<% end %>
Here is my modal app/views/layouts/_note_modal.html.erb
<div id="note-modal" class="modal hide fade" tabindex="-1">
<div class='modal-header'>
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3 class="modal-title"><%= call.incident_number %> Notes</h3>
</div>
<div class='modal-body'>
<div class="modal-body-content">
<%= form_for(#note, url: call_note_calls_path, html: {class: "form-inline"}) do |f| %>
<%= f.text_field :message, :maxlength => 255 %>
<%= f.hidden_field :call_id, value: call.id %>
<%= f.hidden_field :user_id, value: current_user.id %>
<%= f.button "Add Note", class: 'btn btn-info btn-small', data: {disable_with: "<i class='icon-spinner'></i>Posting..."} %>
<% end %></div>
<div class="ajax-loader">
</div>
</div>
<div class='modal-footer'>
<button type="button" data-dismiss="modal" class="btn">Close</button>
</div>
</div>
When I load the page and there are several calls I click on the notes link, the partial renders in a modal and I can submit a note. The problem is if I have 10 calls on the screen no matter which notes link I click on it adds a note to the first call on the screen.
Am I passing locals incorrectly? I know this code is inside of the block so it should pull the call object and pass it as a local to the partial in the modal but it's not.
Any help is greatly appreciated.
I think the issue is that you render the modal each time for a note but they all have the same id. So you are always opening the first modal. Actually IMHO you just need to render the modal once and pass the note_id via an data attribute on the link which triggers the modal. So basically configure the modal via the caller.
I was able to figure this out on my own and still render the partial within the loop by calling an index as part of the target ID for the modal. Working code below.
<% #assigned.each_with_index do |call, index| %>
<%= link_to "Notes", '#note-modal', data: {toggle: "modal", target: "#note-modal#{index}" }, class: 'btn btn-small btn-inverse' %>
<%= render 'layouts/note_modal', call: call, index: index %>
<% end %>
<div id="note-modal<%= index %>" class="modal hide fade" tabindex="-1">
<div class='modal-header'>
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3 class="modal-title"><%= call.incident_number %> Notes</h3>
</div>
<div class='modal-body'>
<div class="modal-body-content">
<%= form_for(#note, url: call_note_calls_path, html: {class: "form-inline"}) do |f| %>
<%= f.text_field :message, :maxlength => 255 %>
<%= f.hidden_field :call_id, value: call.id %>
<%= f.hidden_field :user_id, value: current_user.id %>
<%= f.button "Add Note", class: 'btn btn-info btn-small', data: {disable_with: "<i class='icon-spinner'></i>Posting..."} %>
<% end %></div>
<% call.notes.each do |n| %>
<li><%= n.message %> added by <%= n.user.username %></li>
<% end %>
<div class="ajax-loader">
</div>
</div>
<div class='modal-footer'>
<button type="button" data-dismiss="modal" class="btn">Close</button>
</div>
</div>
I want to add navigation to a series of div, which are loaded dynamically.
For this I am using link to covering the div and passing it the attribute to the method.
The problem is that when I press on the div the attribute does not correspond.
I put the code.
With this code all it's ok, but i don't have the link in the div.
<%for i in inicio..final %>
<div class="col-md-3">
<div class="tarjeta_comercio">
<%= link_to 'mezcla/mostrar_institucion', {:controller => "mezcla", :action => "mostrar_institucion", :institucion_actual => #institucions[azar[i]].id} %>
<div class="foto">
<%= image_tag #institucions[azar[i]].logo.url(:original) %>
</div>
<div class="titulo">
<%= #institucions[azar[i]].nombre %>
</div>
<% end %>
But the problem is when i do a block with "link_to...do-div-end". If i do this the parameter don't run. I don't explain why this happen. This is the wrong code.
<%for i in inicio..final %>
<div class="col-md-3">
<div class="tarjeta_comercio">
<%= link_to 'mezcla/mostrar_institucion', {:controller => "mezcla", :action => "mostrar_institucion", :institucion_actual => #institucions[azar[i]].id} do %>
<div class="foto">
<%= image_tag #institucions[azar[i]].logo.url(:original) %>
</div>
<div class="titulo">
<%= #institucions[azar[i]].nombre %>
</div>
<% end %>
<% end %>
In :institucion_actual each time put 0 (when i pulsed over).
Thanks.
I've got a page showing details for every #user. Each user has an enrolment, which can has a comment. When I e.g. do this:
<% #user.each do |u| %>
<% the_enrolment = Enrolment.where(user_id: u).first %>
<% end %>
Then in every iteration the enrolment is a different enrolment, as the user changes in every iteration. So far, so simple.
But when I pass this enrolment variable (while looping through) to a partial which contains a form, like this:
<%= render 'the_partial', enrolment: the_enrolment %>
With this form (in the partial view):
<%= form_for enrolment, :url => the_path, remote: true do |f| %>
<%= f.hidden_field :id %>
<%= f.text_area :comment %>
<%= f.submit "Save" %>
Then, in the finally rendered page, every form uses the same enrolment. (They all have the same id and every text_are is pre filled with the content of one of them. What am I doing wrong here?
The complete iteration looks like this:
#user.each do |u|
the_enrolment = Enrolment.where(user_id: u).first
<%= the_enrolment %> # correct id
<%= render 'the_partial', enrolment: the_enrolment %>
end
Thank you very much!
Update
Here is an update with the newest informations. The problem seems to be that the form is placed inside a twitter bootstrap modal. Here is the whole partial:
<%= enrolment.id %> # here it's the correct id
<div id="myModal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3 id="myModalLabel">Admin Comment</h3>
</div>
<%= form_for enrolment, :url => the_path, remote: true do |f| %>
<div class="modal-body">
<p>
<%= "enrolment in modal: #{enrolment.id}" %> # at this place the id is ALWAYS the id of the very first enrolment
<%= f.hidden_field :id %>
<%= f.text_area :comment_admin %>
<button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
<%= f.submit "Save", class: "btn btn-success", id: "admin-comment-submit-button" %>
</p>
</div>
<% end %>
</div>
If I delete everything on this page concerning the modal, the form works.
When a users clicks forgot password, it takes them to the forgot password page with a field for them to input their email address. If their email address is in the database, everything is peachy, but if the email address does NOT exist in the database, it just redirects to the same page, but does not show an error message.
How can I get the error message to appear?
/view/devise/passwords/new.html.erb
...
<%= form_for(resource, :as => resource_name, :url => password_path(resource_name), :html => { :method => :post }) do |f| %>
<h1>Reset Password</h1>
<div class="login-fields">
<p>Instructions on resetting your password will be emailed to you.</p>
<%= render :partial => '/shared/messages' %>
<div class="field">
<%= f.label :email %>
<%= f.email_field :email, :placeholder => 'Email', :class => 'login username-field' %>
</div> <!-- /field -->
</div> <!-- /login-fields -->
<div class="login-actions">
<%= content_tag(:button, :type=>:submit, :class => "button btn btn-secondary btn-large") do %>
Send me reset password instructions
<% end %>
</div> <!-- .actions -->
<div class="login-social">
<%= render "devise/shared/links" %>
</div>
<% end %>
...
/views/shared/_messages.html.erb
<% if alert || flash[:alert] || flash[:error] %>
<div class="alert alert-error">
<a class="close" data-dismiss="alert" href="#">x</a>
<h4 class="alert-heading">Error!</h4>
<%= alert %>
<%= flash[:error] %>
</div>
<% end %>
<% if flash[:success] || notice || flash[:notice]%>
<div class="alert alert-success">
<a class="close" data-dismiss="alert" href="#">x</a>
<h4 class="alert-heading">Success!</h4>
<%= flash[:success] %>
<%= notice %>
</div>
<% end %>
In your shared messages partial you are only displaying errors from the controllers. You need to include errors that are attached to your model. In this case the error message is attached to the User model. You /views/shared/_messages.html.erb should actually look like:
<% if alert || flash[:alert] || flash[:error] %>
<div class="alert alert-error">
<a class="close" data-dismiss="alert" href="#">x</a>
<h4 class="alert-heading">Error!</h4>
<%= alert %>
<%= flash[:error] %>
</div>
<% end %>
<% if model.errors.any? %>
<div class="alert alert-error">
<a class="close" data-dismiss="alert" href="#">x</a>
<h4 class="alert-heading">Error!</h4>
<ul>
<% model.errors.full_messages.each do |msg| %>
<li>* <%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<% if flash[:success] || notice || flash[:notice]%>
<div class="alert alert-success">
<a class="close" data-dismiss="alert" href="#">x</a>
<h4 class="alert-heading">Success!</h4>
<%= flash[:success] %>
<%= notice %>
</div>
<% end %>
and while rendering the partial, you need to pass in the model.
<%= render '/shared/messages', model: resource %>
If you look at the default passwords/new.html.erb view that comes with devise, you'll see that it includes a call to
<%= devise_error_messages! %>
You can use that same helper in your view, if you like, to render the error messages attached to the user object (as was pointed out in Anurag's answer, the messages are attached to the model object rather than in the flash).
This helper will return markup that looks like:
<div id="error_explanation">
<h2>1 error prohibited this user from being saved</h2>
<ul><li>email not found</li></ul>
</div>
if you want to customize this, you can do so easily. Just don't use the helper, and instead add your own custom markup that accesses resource.errors.full_messages to get the "email not found" message. Or honestly since that's the only error you're going to get on this page, you could just do:
<% unless resource.errors.empty? %>
<div>email not found</div>
<% end %>
The form is calling the create method at the password_path. Make sure that the create.html.erb displays a flash message on error as well as success, if any exists.
I'm creating a form using the simple_form gem on Rails 3.2.
The problem I'm having is that I wish to add a font-awesome icon to the f.button :submit line of my form. Since the output is of type input I can't embed the icon element inside of it.
I could simply hardcode a submit button into the form that contains the icon but I am not sure how to fetch the button value - Create %model/Update %model.
My code is posted below:
<div id="form">
<%= simple_form_for #program, :html => { :class => 'form-horizontal' } do |f| %>
<%= f.input :name %>
<%= f.input :url %>
<%= f.input :description, :input_html => { :class => "span5", :rows => 10 } %>
*********************
<%= f.button :submit do %>
<i class="icon-save"></i> What Here??? <--- Doesn't work since output is type input
<% end %>
*********************
<button class="btn">
<i class="icon-save"></i> <%= f.button(:submit).label %> <--- Doesn't work, alternative?
</button>
<% end %>
</div>
Expected output:
<button type="submit" class="btn">
<i class="icon-plus-sign"></i> Create *ModelName*
</button>
Or Update ModelName, depending on controller action.
<%= f.button do %>
<i class="icon-save"></i> <%= "#{f.object.new_record? ? 'Create' : 'Update'} #{f.object.class.model_name.human}" %>
<% end %>
It would be better to make some helper method for this. If you want to use I18n take a look at source code (button and submit_default_value methods, lines 1763 and 1776). It's pretty clear.