Display error message on invalid special field - ruby-on-rails

I would know how display a error message on my invalid field
I have a simple form
<%= simple_form_for #bien do |f| %>
<div class="col-md-6 col-md-offset-3 text-center">
<div class="row">
<div class="form-group">
<%= f.input :adress, :input_html =>{:id => 'address'}, placeholder: 'Adresse', label: "Adresse" %>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12 text-center">
<div class="form-group">
<h5><b>Type de mandat</b></h5>
<div class="btn-group" data-toggle="buttons">
<label class="btn btn-danger active" style="margin-right: 10px;">
<input id="bien_mandat_type_true" name="bien[mandat_type]" type="radio" autocomplete="off" value="Simple"/> Simple
</label>
<label class="btn btn-danger" style="margin-right: 10px;">
<input id="bien_mandat_type_true" name="bien[mandat_type]" type="radio" autocomplete="off" value="Exclusif" /> Exclusif
</label>
<label class="btn btn-danger">
<input id="bien_mandat_type_true" name="bien[mandat_type]" type="radio" autocomplete="off" value="Délégation" /> Délégation
</label>
</div>
</div>
</div>
</div>
<div class="col-xs-12 col-sm-12 text-center">
<%= f.button :submit, "Valider", class: "btn btn-fill callpremium btn-danger btn-lg" %>
</div>
<% end %>
And i would display a error message when my input is empty like i do with the normal adress field, i wont use flash messages

Simple form error messages are driven by your model's validations. Add a presence validation to the fields you want to have errors when empty and simple form will respond accordingly automatically. For example, you could add this to your model to give an error when address is empty:
validates :address, presence: true

Related

Concatenate asp-validation-for result with an Icon

I have an ASP MVC view that contains only a Textbox that takes a string, and a submit button to submit the value.
I want to add the validation error message with an Icon before it as in the following snippet:
<div class="form-group row">
<label class="col-sm-4 col-form-label">Check User Id</label>
<div class="col-sm-8">
<input asp-for="#Model.userId" type="text" class="form-control" />
</div>
</div>
<div class="form-group row">
<label class="col-sm-4 col-form-label"></label>
<div class="col-sm-8">
<input type="submit" class="btn btn-primary" value="Check" asp-action="Index" asp-controller="UserController" />
<div class="col-sm-8">
<i asp-validation-for="userId" class="fa fa-info-circle"></i>
<span asp-validation-for="userId" class="text-dark"></span>
</div>
</div>
</div>
My Problem now is that the info Icon is always showing, and I want it to show ONLY if there is an error/validation message. Is there a way to achieve that from the view only with no changes to the Business logic?

Capybara Unable to find field

Hello I am doing my very first tests and I would need your help. I am using Rails5.
The problem is because of the nested fields I believe...(used Cocoon gem)
Capybara returns this error:
Capybara::ElementNotFound:
Unable to find field "event_participants_attributes_1489697584487_first_name"
my html looks like this:
<div class="nested-fields">
<div class="form-group string optional event_participants_first_name"><label class="control-label string optional" for="event_participants_attributes_1489697584487_first_name">Participant's first name</label><input class="form-control string optional" type="text" name="event[participants_attributes][1489697584487][first_name]" id="event_participants_attributes_1489697584487_first_name" data-com.agilebits.onepassword.user-edited="yes"></div>
<div class="form-group integer optional event_participants_salary"><label class="control-label integer optional" for="event_participants_attributes_1489697584487_salary">Participant's monthly pay</label><input class="form-control numeric integer optional" type="number" step="1" name="event[participants_attributes][1489697584487][salary]" id="event_participants_attributes_1489697584487_salary"></div>
<div class="links">
<input type="hidden" name="event[participants_attributes][1489697584487][_destroy]" id="event_participants_attributes_1489697584487__destroy" value="false"><a class="btn btn-danger btn-xs btn-remove-friend remove_fields dynamic" href="#">Remove this friend</a>
</div>
</div>
and here is my features/events/create_event.spec.rb
require 'spec_helper'
require 'rails_helper'
describe "Creating an event" do
it "redirects on result page on success" do
visit "/"
click_link "Create a new event"
expect(page).to have_content('Wanna share fair?')
fill_in :name, with: 'Rent a plane'
fill_in "What is the total price", with: 200
click_link "Add a participant"
fill_in "event_participants_attributes_1489697584487_first_name", with: "John"
enter code here
fill_in ":event_participants_attributes_1489697584487_salary", with: 2300
click_button "See result"
expect(page).to have_content('Your salary together:')
end
end
And here are my simple_forms:
_form.html.erb
<%= simple_form_for #event do |f| %>
<div class="col-xs-12 col-md-10 col-md-offset-1">
<h1>Wanna share fair?</h1>
<p>Create an event, enter the bill to share.</p>
<%= f.input :name, label: "Event's name" %>
<%= f.input :total_price, label: "What is the total price" %>
<p>Add the participants.</p>
<div id="participants">
<%= f.simple_fields_for :participants do |participant| %>
<%= render "participants_fields", f: participant %>
<% end %>
<div class="links text-center">
<%= link_to_add_association "Add a participant", f, :participants, partial: "participants_fields", class:"btn btn-primary btn-sm btn-add-friend" %>
</div>
</div>
</div>
<div class="col-xs-12 col-md-10 col-md-offset-1 text-center">
<%= f.submit "See result" , class:"btn btn-success btn-lg btn-event" %>
</div>
<% end %>
_participants_fields.html.erb
<div class="nested-fields">
<%= f.input :first_name, label: "Participant's first name" %>
<%= f.input :salary, label: "Participant's monthly pay" %>
<div class="links">
<%= link_to_remove_association "Remove this friend", f , class: "btn btn-danger btn-xs btn-remove-friend" %>
</div>
</div>
edit more html
<form novalidate="novalidate" class="simple_form new_event" id="new_event" action="/events" accept-charset="UTF-8" method="post"><input name="utf8" type="hidden" value="✓"><input type="hidden" name="authenticity_token" value="O5XM0JMiVBbpPNaKF1apw7rdtC/XEBhasZQoK6POycZQ2Zp14Td1ljoJyIUKTwtl91LlBHeDkKFtcWRnNu+iEQ==">
<div class="col-xs-12 col-md-10 col-md-offset-1">
<h1>Wanna share fair?</h1>
<p>Create an event, enter the bill to share.</p>
<div class="form-group string optional event_name"><label class="control-label string optional" for="event_name">Event's name</label><input class="form-control string optional" type="text" name="event[name]" id="event_name" data-com.agilebits.onepassword.user-edited="yes"></div>
<div class="form-group integer optional event_total_price"><label class="control-label integer optional" for="event_total_price">What is the total price</label><input class="form-control numeric integer optional" type="number" step="1" name="event[total_price]" id="event_total_price" data-com.agilebits.onepassword.user-edited="yes"></div>
<p>Add the participants.</p>
<div id="participants">
<div class="nested-fields">
<div class="form-group string optional event_participants_first_name"><label class="control-label string optional" for="event_participants_attributes_1489705438668_first_name">Participant's first name</label><input class="form-control string optional" type="text" name="event[participants_attributes][1489705438668][first_name]" id="event_participants_attributes_1489705438668_first_name" data-com.agilebits.onepassword.user-edited="yes"></div>
<div class="form-group integer optional event_participants_salary"><label class="control-label integer optional" for="event_participants_attributes_1489705438668_salary">Participant's monthly pay</label><input class="form-control numeric integer optional" type="number" step="1" name="event[participants_attributes][1489705438668][salary]" id="event_participants_attributes_1489705438668_salary" data-com.agilebits.onepassword.user-edited="yes"></div>
<div class="links">
<input type="hidden" name="event[participants_attributes][1489705438668][_destroy]" id="event_participants_attributes_1489705438668__destroy" value="false"><a class="btn btn-danger btn-xs btn-remove-friend remove_fields dynamic" href="#">Remove this friend</a>
</div>
</div><div class="nested-fields">
<div class="form-group string optional event_participants_first_name"><label class="control-label string optional" for="event_participants_attributes_1489705443842_first_name">Participant's first name</label><input class="form-control string optional" type="text" name="event[participants_attributes][1489705443842][first_name]" id="event_participants_attributes_1489705443842_first_name" data-com.agilebits.onepassword.user-edited="yes"></div>
<div class="form-group integer optional event_participants_salary"><label class="control-label integer optional" for="event_participants_attributes_1489705443842_salary">Participant's monthly pay</label><input class="form-control numeric integer optional" type="number" step="1" name="event[participants_attributes][1489705443842][salary]" id="event_participants_attributes_1489705443842_salary" data-com.agilebits.onepassword.user-edited="yes"></div>
<div class="links">
<input type="hidden" name="event[participants_attributes][1489705443842][_destroy]" id="event_participants_attributes_1489705443842__destroy" value="false"><a class="btn btn-danger btn-xs btn-remove-friend remove_fields dynamic" href="#">Remove this friend</a>
</div>
</div><div class="links text-center">
<a class="btn btn-primary btn-sm btn-add-friend add_fields" data-association="participant" data-associations="participants" data-association-insertion-template="<div class="nested-fields">
<div class="form-group string optional event_participants_first_name"><label class="control-label string optional" for="event_participants_attributes_new_participants_first_name">Participant&#39;s first name</label><input class="form-control string optional" type="text" name="event[participants_attributes][new_participants][first_name]" id="event_participants_attributes_new_participants_first_name" /></div>
<div class="form-group integer optional event_participants_salary"><label class="control-label integer optional" for="event_participants_attributes_new_participants_salary">Participant&#39;s monthly pay</label><input class="form-control numeric integer optional" type="number" step="1" name="event[participants_attributes][new_participants][salary]" id="event_participants_attributes_new_participants_salary" /></div>
<div class="links">
<input type="hidden" name="event[participants_attributes][new_participants][_destroy]" id="event_participants_attributes_new_participants__destroy" value="false" /><a class="btn btn-danger btn-xs btn-remove-friend remove_fields dynamic" href="#">Remove this friend</a>
</div>
</div>
" href="#">Add a participant</a>
</div>
</div>
</div>
<div class="col-xs-12 col-md-10 col-md-offset-1 text-center">
<input type="submit" name="commit" value="See result" class="btn btn-success btn-lg btn-event" data-disable-with="See result">
</div>
</form>
IIRC the "1489697584487" part of the ids you show is created by Cocoon based on the current timestamp. That means every time you run your test the number will be different so you're not going to be able to select those elements by id.
Instead if you're only adding one participant you should be able to do something like
fill_in "Participant's first name", with: "John"
fill_in "Participant's monthly pay", with: "2300"
If you are adding multiple participants then depending on the exact layout you can use nth-child/nth-of-type CSS selectors to scope the fill_in or use all and select the one you want, etc.
find('.nested-fields:nth-child(2)').fill_in ...
all(:field, "Participant's first name", minimum: 2)[1].set("John") # 0 based index so minimum should be 1 more than the index you want
Also - For any of this to work you need to be using a JS capable driver (Cocoon requires JS). You haven't tagged your spec with js: true metadata so either you've overridden the default driver, or you're not currently using a JS capable driver - see https://github.com/teamcapybara/capybara#selecting-the-driver. Also see https://github.com/teamcapybara/capybara#transactions-and-database-setup and https://github.com/DatabaseCleaner/database_cleaner#rspec-with-capybara-example if you haven't yet configure database_cleaner for use with JS capable drivers

Bootstrap submit button not aligning within form on non-mobile devices

Within my rails form: I am using form-horizontal. I can't seem to figure out how to line my submit button up within my form.
The submit button does line up when accessing the form from a mobile devise:
But the submit button is not aligned when accessing the form from a tablet/computer:
Here is my code for the form:
Search Providers
<%= form_tag providers_index_search_results_path, {class: 'form-horizontal'} do |f| %>
<div class="form-group">
<%= label_tag :title, nil, class: "control-label col-sm-2" %>
<div class="col-sm-5">
<%= text_field_tag :title, nil, class: "form-control col-sm-5" %>
</div>
</div>
<div class="form-group">
<%= label_tag :name, nil, class: "control-label col-sm-2" %>
<div class="col-sm-5">
<%= text_field_tag :name, nil, class: "form-control col-sm-5" %>
</div>
<div class="col-sm-5"></div>
</div>
<%= button_tag('Submit', class: "btn btn-primary") %>
<% end %>
How can I make it so that the submit button lines up?
You have to put your button inside of a div.form-group, and subsequently in the grid.
Here is the example from the bootstrap docs:
<form class="form-horizontal">
<div class="form-group">
<label for="inputEmail3" class="col-sm-2 control-label">Email</label>
<div class="col-sm-10">
<input type="email" class="form-control" id="inputEmail3" placeholder="Email">
</div>
</div>
<div class="form-group">
<label for="inputPassword3" class="col-sm-2 control-label">Password</label>
<div class="col-sm-10">
<input type="password" class="form-control" id="inputPassword3" placeholder="Password">
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<div class="checkbox">
<label>
<input type="checkbox"> Remember me
</label>
</div>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-default">Sign in</button>
</div>
</div>
</form>
Always check the docs first: http://getbootstrap.com/css/#forms-horizontal

I have a customized form but whatever written on the form is not saved in database

I have a form that uses styles of twitter/bootstrap
however the content of the form is not saved.
May I please know what am I missing?
<%= form_for #customer_detail, url: { action: "create" } do |f| %>
<div class="form-group">
<div class="row">
<div class='col-sm-3'>
<label for="Check in">Check in:</label><br>
<div class='input-group date' id='datetimepicker1'>
<input class="form-control" type='text'>
<span class="input-group-addon"><span class=
"glyphicon glyphicon-calendar"></span></span>
</div>
</div><label for="Check out">Check out:</label><br>
<div class='col-sm-3'>
<div class='input-group date' id='datetimepicker2'>
<input class="form-control" type='text'>
<span class="input-group-addon"><span class=
"glyphicon glyphicon-calendar"></span></span>
</div>
</div>
</div>
<% end %>
Seems like you should read this article. It describe to create form use Rails helpers and action for save to database.

Twitter Bootstrap modals: inputs are invisible

What's wrong with this code? No inputs show up, but the buttons in the modal footer do. Any idea what's going on here?
<div class="modal" style="display: none;" id="customArticleModal">
<div class="modal-header">
<h3>Add your own article</h3>
</div>
<%= form_for(#custom_article) do |f| %>
<div class="modal-body">
<%= f.text_field :name %>
<%= f.text_field :description %>
</div>
<div class="modal-footer">
<%= f.submit "Create", :class => 'btn btn-primary' %>
</div>
<% end %>
</div>
EDIT
Here's the rendered source:
<div class="modal hide fade" id="customArticleModal">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">x</button>
<h3>Add your own article</h3>
</div>
<form accept-charset="UTF-8" action="/components" class="new_component" enctype="multipart/form-data" id="new_component" method="post">
<div class="modal-body">
<input id="component_name" name="component[name]" size="30" type="text" />
<input id="component_description" name="component[description]" size="30" type="text" />
</div>
<div class="modal-footer">
<input class="btn btn-primary" name="commit" type="submit" value="Create article" />
</div>
</form>
</div>
<div class="modal" style="display: none;" id="customArticleModal">
Here you have manually added the style as display: none. Instead of that try using bootstrap class. e.g.
<div class="modal hide fade" id="customArticleModal">
I wrote a bit of jQuery to override whatever Bootstrap was doing here.
$(document).ready(function() {
$('#custom_article_form .control-group .controls input').css('display', 'block');
$('#custom_article_form .control-group .controls textarea').css('display', 'block');
});
No idea why it was happening.

Resources