simple_form validations with Bootstrap in Rails - ruby-on-rails

I have the following simple_form in my rails app:
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title center">Add New Customer</h3>
</div>
<div class="panel-body">
<%= simple_form_for(#customer, html: {class:'form-horizontal'}, wrapper: :horizontal_form) do |f| %>
<%= f.input :first_name, input_html: {class:'form-control'} %>
<%= f.input :last_name, input_html: {class:'form-control'} %>
<%= f.input :phone_number, as: :tel, input_html: {class:'form-control'} %>
<%= f.input :email_address, as: :email, input_html: {class:'form-control'} %>
<%= f.input :address, input_html: {class:'form-control'} %>
<%= f.input :city, input_html: {class:'form-control'} %>
<%= f.input :postal_code, input_html: {class:'form-control'} %>
<%= f.input :customer_type, collection: ["Retail", "Contractor", "Dealer"], input_html: {class:'form-control'}, prompt: "Select Customer Type" %>
<br />
<%= f.button :submit, "Create Customer", class: "col-md-3 bump-right" %>
<% end %>
</div>
</div>
As you can see, I'm using bootstrap styling on the form elements. When I submit the form, I want the following to happen:
Validate email
Validate phone number
Require all fields
As it stands now, when I submit the form, none of the above three happen. Looking through the docs for simple_form (https://github.com/plataformatec/simple_form) I can't discern what I need to do to achieve my end result. I have tried adding f.error fields for each input but that does not seem to do anything.
There is this 2 year old question: simple_form & bootstrap validations not working - but this is foreign to me and given the 2.5 year old versions I'm sure something has changed.
If anyone has any ideas, or can help me demystify the docs I would be grateful.

Use validations in the models (specifically the customer model) which would happen before the data is saved to the database. See the docs here.
Example:
class Person < ActiveRecord::Base
validates :name, presence: true
end
Person.create(name: "John Doe").valid? # => true
Person.create(name: nil).valid? # => false

Related

Is it possible to create two objects from two forms in 1 view and have them related?

I know the title sounded a bit wonky, but this is what I am trying to do.
I have two models - Job and Company. Someone can create a Job listing, but before the listing is saved, it should be associated with a company. This company can be newly created, or should be populated from companies the current_user has previously created.
A job belongs_to :company, and a company has_many :jobs.
I know I could do two different views, and just send the user to two different actions on two different controllers, but I would like to simplify it and just have everything done in one view.
When they go to /jobs/new, they should see the normal jobs/_form.html.erb partial, but I would love to be able to show either a Company dropdown for existing companies or new company creation fields that the user fills out and that new company gets associated with this new job that is being created.
This is what my jobs/_form.html.erb partial looks like:
<%= simple_form_for(#job) do |f| %>
<%= f.input_field :title %>
<%= f.input_field :salary %>
<%= f.input_field :description, as: :text %>
<%= f.input_field :apply_description, as: :text %>
<%= f.input_field :language %>
<%= f.input :premium, as: :boolean, inline_label: true, label: "Make this listing stand out", class: "form-control" %>
<%= f.button :submit, class: "btn btn-lg btn-primary pull-right" %>
<% end %>
This is what my companies/_form.html.erb looks like:
<%= simple_form_for(#company) do |f| %>
<%= f.input :name %>
<%= f.input :logo %>
<%= f.input :description %>
<%= f.input :city %>
<%= f.input :state %>
<%= f.input :country %>
<%= f.input :email %>
<%= f.button :submit %>
<% end %>
How can I combine them into 1 form, or some other unified workflow within 1 view where it works seamlessly to the user?
Edit 1
Based on Jay-Ar's answer, this is what is happening now.
When I select New Company in the Company Dropdown, it doesn't show the fields in the <fieldset>. I believe that's the case because there is no value=0 in the select tags rendered in the HTML, as can be seen in the screenshot below.
Edit 2
After attempting the latest update from Jay-Ar, the JS still doesn't work and the form is no longer hidden.
This is what it looks like on first load, and always:
Ideally I would like for this form not to show up until they have chosen "New Company" from the dropdown.
This is what the HTML looks like now:
The JS does appear in the source, so I know it is being loaded in the asset pipeline correctly.
UPDATED & TESTED WORKING
Now supports Turbolinks
views/jobs/_form.html.erb
<%= simple_form_for(#job) do |f| %>
<%# IMPORTANT: use `include_blank` below instead of `prompt` because prompt does not seem to work when updating, but only works when creating %>
<%= f.association :company, collection: [['New Company', nil]] + Company.pluck(:name, :id), include_blank: 'Please Select Company', input_html: { id: 'company-select' } %>
<fieldset id='job-fields'>
<%= f.simple_fields_for :company, #job.build_company do |ff| %>
<%= ff.input :name %>
<%= ff.input :logo %>
<%= ff.input :description %>
<%= ff.input :city %>
<%= ff.input :state %>
<%= ff.input :country %>
<%= ff.input :email %>
<% end %>
</fieldset>
<%= f.input_field :title %>
<%= f.input_field :salary %>
<%= f.input_field :description, as: :text %>
<%= f.input_field :apply_description, as: :text %>
<%= f.input_field :language %>
<%= f.input :premium, as: :boolean, inline_label: true, label: "Make this listing stand out", class: "form-control" %>
<%= f.button :submit, class: "btn btn-lg btn-primary pull-right" %>
<% end %>
JS
// for Rails 5, use turbolinks:load instead of page:change below
$(document).on('page:change', function(){
var companySelect = $('#company-select');
var jobFields = $('#job-fields');
companySelect.change(function(){
// if selected option is the second option
if ($(this).find('option:selected').index() == 1)
jobFields.show().find(':input').prop('disabled', false);
else
jobFields.hide().find(':input').prop('disabled', true);
})
// call change immediately so this still works when already updating and not just creating.
companySelect.change();
})
controllers/jobs_controller.rb
class JobsController < ApplicationController
...
def create
#job = Job.new(job_params)
...
end
def update
#job = Job.find(params[:id]) # not needed if using before_action #set_job
if #job.update(job_params)
...
end
private
def job_params
params.require(:job).permit(:id, :title, :salary, :description, :apply_description, :language, :premium, :company_id, company_attributes: [:name, :logo, :description, :city, :state, :country, :email]
end
end
models/job.rb
class Job < ActiveRecord::Base
accepts_nested_attributes_for :company
validates :company, presence: true
...
end
You should get something like the following:
On fresh load:
After selecting 'New Company' option':
You should use nested model forms, I suggest you watch this video it has a very detailed explanation of the steps to do it for a question / answer models but its the same thing.

Rails 4 - Acts as Taggable on gem - set up errors

I am trying to make an app with Rails 4.
I am trying to use gem 'acts-as-taggable-on', '~> 3.4'
I found this tutorial showing how to set it up:
https://www.reddit.com/r/rails/comments/2chtgw/tagging_in_rails_4/
I have an articles controller, which has included tag_list in the strong params:
def article_params
params[:article].permit(:user_id, :body, :title, :image, :tag_list,
comment_attributes: [:opinion])
end
I have an articles form, with:
<%= simple_form_for(#article) do |f| %>
<%= f.error_notification %>
<div class="form-inputs">
<%= f.input :title, autofocus: true %>
<%= f.input :body, :label => "Post", :input_html => {:rows => 10} %>
<%= f.input :image, :label => "Add an image" %>
<%= f.input :tag_list, :label => "Add tags" %>
</div>
<div class="form-actions">
<%= f.button :submit, "Submit & Publish", :class => 'formsubmit' %>
</div>
<% end %>
I have the table in my schema and have completed all the steps prior to the view integration in the reddit post.
When I try to check the form is working, I get this error:
undefined method `tag_list' for #<Article:0x007fad26cd9f30>
Can anyone see what's going wrong?

Simple Form Gem - How to display the name of a model in an association - Rails 4

I'm new to rails & I know this may be a very simple question, but I'm unsure how to display the name of a company using 'simple form' association?
In my schema I've a table companies with the columns name & content
In my schema I also have a table users with the columns first name, last name & company_id:integer
A company has_many :users
A user belongs_to :company
Everything works perfectly in my views expect the display of the name of my company
in my views:
<h2>Sign up Primary Admin</h2>
<%= simple_form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
<%= f.error_notification %>
<div class="form-inputs">
<%= f.association :company, collection: Company.all.order(:name), prompt: "please select your company", label: 'Company' %>
<%= f.input :firstname, required: true, autofocus: true %>
<%= f.input :lastname, required: true, autofocus: true %>
<%= f.input :email, required: true, autofocus: true %>
<%= f.input :password, required: true, hint: ("#{#minimum_password_length} characters minimum" if #minimum_password_length) %>
<%= f.input :password_confirmation, required: true %>
</div>
<div class="form-actions">
<%= f.button :submit, "Sign up" %>
</div>
<% end %>
<%= render "users/shared/links" %>
i get the below display:
label_method => the label method to be applied to the collection to
retrieve the label (use this instead of the text_method option in
collection_select)
You should define the label_method to name to display the company names.
<%= f.association :company, collection: Company.all.order(:name), prompt: "please select your company", label_method: :name, label: 'Company' %>
SimpleForm uses to_s method for association labels, so you have to define your own to_s method for your company model.
i. e:
class Company < ActiveRecord::Base
def to_s
name
end
end

How to check existence using parsley?

I want to check existence of "Name", "Email" input field, but I can't find the method(or function) in parsleyjs.org...
This is my simple-form and parsley code:
<%= simple_form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
<%= render 'devise/shared/error_messages', object: f.object %>
<div class="form-inputs">
<%= f.input :name, required: true, autofocus: true%>
<%= f.input :email, required: true %>
<%= f.input :password, required: true, placeholder: "min. 6 characters",
input_html: {"parsley-minlength" => 6, "error-container" =>"#errorBlock"} %>
<%= f.input :password_confirmation, required: true,
input_html: {"parsley-equalto" => "#user_password"} %>
<%= f.collection_select :role, User::ROLES, :to_s, :humanize %>
</div>
<div class="form-actions">
<%= f.button :submit, "회원 가입" %>
</div>
<% end %>
<%= render "devise/shared/links" %>
<script>
$("#new_user").parsley({trigger: "keyup",
errors: {
errorsWrapper: '<div></div>',
errorTemplate: '<span></span>'
}
});
</script>
If I understand correctly your question looking at the comments, it seems that you want to leverage Parsley validation to check in your database if email or name is already taken and display a Parsley error accordingly.
To achieve that, you'll need to use Parsley Remote plugin, and its documentation here: http://parsleyjs.org/doc/index.html#remote
You'll need to work on your APIs to be able to check backend if these fields values already exist in database, and than integrate parsley.remote.js on top of that.
Best

How do I translate an HTML input field to "simple_form"?

I have the following HTML input field:
<input type="text" class="login-field" value="" placeholder="Enter your name" id="login-name" />
<label class="login-field-icon fui-user" for="login-name"></label>
I want to translate it into my simple_form field so it will have the same properties like classes, id's etc.
<%= f.input :email%>
Is there a way to add HTML properties inside the simple_form field?
Extracted from simple_form documentation on Github:
<%= simple_form_for #user do |f| %>
<%= f.input :username, label: 'Your username please' %>
<%= f.input :password, hint: 'No special characters.' %>
<%= f.input :email, placeholder: 'user#domain.com' %>
<%= f.input :remember_me, inline_label: 'Yes, remember me' %>
<%= f.button :submit %>
<% end %>
By default it contains labels.
Also, specific options in input call will overwrite the defaults:
<%= f.input :username, input_html: { class: 'special' } %>
Have a look at their Github page, everything is there.

Resources