I am trying to display the error message inline below the form elements in my rails application.
I did the following.
Controller
def create
@faculty = Faculty.new(faculty_params)
respond_to do |format|
if @faculty.save
format.html { redirect_to admin_faculties_path, notice: 'Faculty was successfully created.'}
format.json {render json: @faculty, status: :created, location: @faculty}
else
format.html {render '_form'}
format.json {render json: @faculty.errors, status: :unprocessable_entity }
end
end
end
Form
<% form_with(model: [:admin, @faculty]) do |f| %>
<div class="card-title">Add Faculty</div>
<div class="form-group">
<%= f.label :faculty_name, class: "form-label" do %>
Faculty Name <span class="form-required">*</span>
<% end %>
<%= f.text_field :faculty_name, class: "form-control", placeholder: "Faculty Name", required: true %>
</div>
<%= f.submit class: "btn btn-primary" %>
As I have some validations rules in Model, it checks the validations and stop the form from submitting if the validations occurs. As, this is the form_with form all the requests are handled by Ajax. So, I am looking to display the validations errors below the each form elements. Please suggest me with examples so that I can complete this task.
You could check for every attribute's errors on your form fields and if that attribute has any error just show them
<% form_with(model: [:admin, @faculty]) do |f| %>
<div class="card-title">Add Faculty</div>
<div class="form-group">
<%= f.label :faculty_name, class: "form-label" do %>
Faculty Name <span class="form-required">*</span>
<% end %>
<%= f.text_field :faculty_name, class: "form-control", placeholder: "Faculty Name", required: true %>
<% if @faculty.errors[:name].any? %>
<ul>
<% @faculty.errors[:name].each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
<% end %>
</div>
<%= f.submit class: "btn btn-primary" %>
A better solution could be refactor that on a helper :
Helper
module FacultyHelper
def inline_errors(model, model_attribute)
result = ""
if model.errors[model_attribute].any?
model.errors[model_attribute].each do |message|
result += "<li>#{message}</li>"
end
end
return "<ul>#{result}</ul>".html_safe
end
end
View [UPDATE: wrapper for name errors]
<% form_with(model: [:admin, @faculty]) do |f| %>
<div class="card-title">Add Faculty</div>
<div class="form-group">
<%= f.label :faculty_name, class: "form-label" do %>
Faculty Name <span class="form-required">*</span>
<% end %>
<%= f.text_field :faculty_name, class: "form-control", placeholder: "Faculty Name", required: true %>
<div id="user_name_errors">
<%= inline_errors(@faculty, :name) %>
</div>
</div>
<%= f.submit class: "btn btn-primary" %>
For remote: true, you need to define on your controller format.js
Controller
def create
@faculty = Faculty.new(faculty_params)
respond_to do |format|
if @faculty.save
format.html { redirect_to admin_faculties_path, notice: 'Faculty was successfully created.'}
format.json {render json: @faculty, status: :created, location: @faculty}
format.js
else
format.html {render '_form'}
format.json {render json: @faculty.errors, status: :unprocessable_entity }
format.js
end
end
end
Create a corresponding js.erb view
create.js.erb
$("#user_name_errors").html("<%= inline_errors(@faculty, :name) %>");
You can automate that by overriding ActionView::Base.field_error_proc
1 - Create an initializer: config/initializers/fields_with_errors.rb
2 - Add this code to it.
ActionView::Base.field_error_proc = proc do |html_tag, instance|
html_doc = Nokogiri::HTML::DocumentFragment.parse(html_tag, Encoding::UTF_8.to_s)
element = html_doc.children[0]
if element
element.add_class('is-invalid')
if %w[input select textarea select].include? element.name
instance.raw %(#{html_doc.to_html} <div class="invalid-feedback">#{[*instance.error_message].to_sentence}</div>)
else
instance.raw html_doc.to_html
end
else
html_tag
end
end
Read more about it how it works https://dev.to/etoundi_1er/show-rails-validation-errors-inline-with-bootstrap-4-4ga6
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.