style a Rails form_for with radio buttons to Bootstrap - ruby-on-rails

This is type of button that interests me:
<div class="btn-group" data-toggle="buttons">
<label class="btn btn-primary active">
<input type="radio" name="options" id="option1" autocomplete="off" checked> Radio 1 (preselected)
</label>
</div>
And currently my form in Rails looks like this
<%= form_for [current_user, rsvp], remote: true do |f| %>
<%= f.hidden_field :event_id %>
<%= f.radio_button :status, "attending", :onclick => "this.form.submit();" %>
<%= f.radio_button :status, "interested", :onclick => "this.form.submit();"%>
<%= f.radio_button :status, "not_interested", :onclick => "this.form.submit();" %>
<% end %>
HTML that the form above produces:
<form class="edit_rsvp" id="edit_rsvp_10" action="/users/1/rsvps/10" accept-charset="UTF-8" method="post"><input name="utf8" type="hidden" value="✓" /><input type="hidden" name="_method" value="patch" /><input type="hidden" name="authenticity_token" value="MIbWTIdE3/6MJ5ly3oWleBRIvit5WA0CeFm/+caKj049svqPVG8h+uf76NVjxr31d69jlbMWNIIB4Eo7a6R9cw==" />
<input type="hidden" value="17" name="rsvp[event_id]" id="rsvp_event_id" />
<input onclick="this.form.submit();" type="radio" value="attending" name="rsvp[status]" id="rsvp_status_attending" />
<input onclick="this.form.submit();" type="radio" value="interested" checked="checked" name="rsvp[status]" id="rsvp_status_interested" />
<input onclick="this.form.submit();" type="radio" value="not_interested" name="rsvp[status]" id="rsvp_status_not_interested" />
</form>
Sticking the btn class at the end like this <%= f.radio_button :status, "attending", :onclick => "this.form.submit();", :class => "btn btn-primary" %>, produces what looks like a standard Rails radio button.
Doing it the other way around produces Bootstrap buttons that don't change anything when you click them
<label class="btn btn-primary">
<input onclick="this.form.submit();" type="radio" value="attending" name="rsvp[status]" id="rsvp_status_attending" autocomplete="off"> Attending
</label>
UPDATE 1
It looks like in Taryn's solution the original Rails radio button just got veiled underneath the new Bootstrap button, a click anywhere on the Bootstrap button produces no controller action.
and here's the HTML her code produces:
<form class="edit_rsvp" id="edit_rsvp_10" action="/users/1/rsvps/10" accept-charset="UTF-8" method="post"><input name="utf8" type="hidden" value="✓" /><input type="hidden" name="_method" value="patch" /><input type="hidden" name="authenticity_token" value="qqtfAy+xZmnklDe+IXVGg2sFbhLC5laWQn4jRBb+RT+nn3PA/JqYbY9IRhmcNl4OCOKzrAiobxY7x9aGu9C3Ag==" />
<input type="hidden" value="17" name="rsvp[event_id]" id="rsvp_event_id" />
<div class="btn-group" data-toggle="buttons">
<label class="btn btn-primary">
<input onclick="this.form.submit();" type="radio" value="attending" name="rsvp[status]" id="rsvp_status_attending" />
Attending
</label>
<label class="btn btn-primary">
<input onclick="this.form.submit();" type="radio" value="interested" checked="checked" name="rsvp[status]" id="rsvp_status_interested" />
Interested
</label>
<label class="btn btn-primary">
<input onclick="this.form.submit();" type="radio" value="not_interested" name="rsvp[status]" id="rsvp_status_not_interested" />
Not Interested
</label>
</div>
</form>
UPDATE 2
trying a submit button like so
<label class="btn btn-primary">
<%= f.submit :status => "attending", :onclick => "this.form.submit();" %>
Attending
</label>
still produces overlap and two separate buttons, one from Bootstrap and one from Rails. Only clicking the Rails' grey area triggers the controller action.

You'll need a combination of erb and html to make it look like bootstrap.
I haven't tested this, but something like this might work for your buttons:
<%= form_for [current_user, rsvp], remote: true do |f| %>
<%= f.hidden_field :event_id %>
<div class="btn-group" data-toggle="buttons">
<label class="btn btn-primary active"><%= f.radio_button :status, "attending", :onclick => "this.form.submit();" %></label>
<label class="btn btn-primary active"><%= f.radio_button :status, "interested", :onclick => "this.form.submit();"%></label>
<label class="btn btn-primary active"><%= f.radio_button :status, "not_interested", :onclick => "this.form.submit();" %></label>
</div>
<% end %>
You may need to tweak it a bit - I am just combining the two snippets you gave.

Related

Calling method in rails

In my application I have an form to create new company. Here I have to enter company name and company url.Here is my code for the from.
<%= form_tag(controller: "/company", action: "add_startup_to_index", method: "post") do %>
<div class="modal-body">
<div class="form-group">
<label class="control-label">Company Name</label>
<input type="text" class="form-control" id="name" name="name" placeholder="Enter the name of the company..." required />
</div>
<div class="form-group">
<label class="control-label">Company URL</label>
<input type="text" class="form-control" id="url" name="url" placeholder="e.g. http://www.company.com..." required />
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default btn-conf" data-dismiss="modal">Cancel</button>
<button type="submit" class="btn btn-primary btn-conf">Add Company</button>
</div>
<% end %>
This is my method for saving above data.
def add_startup_to_index
#url = api_version_root + 'startups/new'
response = RestClient.post #url,
{ startup: { friendly_name: params[:name],
url: params[:url]
}
}, api_token_hash
record = JSON.parse(response.body)
flash[:info] = 'Startup has been added and Crunchbase sync started.'
redirect_to('/startups/' + record['company_id']) && return
rescue RestClient::ExceptionWithResponse => err
handle_rest_error http_code: err.http_code
end
This is working fine and I can save the companies. Now I want to validate the URL. For that I have below method.
def valid_url?(url)
return false if url.include?("<script")
url_regexp = /^(http|https):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?$/ix
url =~ url_regexp ? true : false
end
Since I am new for rails I have no idea how to call that method within my form. I had tried nested form_tag. But it is now allowed.
I tried as below.
<%= form_tag(controller: "/company", action: "add_startup_to_index", method: "post") do %>
<div class="modal-body">
<div class="form-group">
<label class="control-label">Company Name</label>
<input type="text" class="form-control" id="name" name="name" placeholder="Enter the name of the company..." required />
</div>
<%= form_tag(controller: "/company", action: "valid_url", method: "post") do %>
<div class="form-group">
<label class="control-label">Company URL</label>
<input type="text" class="form-control" id="url" name="url" placeholder="e.g. http://www.company.com..." required />
</div>
<% end %>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default btn-conf" data-dismiss="modal">Cancel</button>
<button type="submit" class="btn btn-primary btn-conf">Add Company</button>
</div>
<% end %>
Can any one help me for this.
Lanka, if I understand you correctly, what you are looking for is client side form validation. Before HTML5 this was a tedious task involving JS. With HTML5, url validation is baked right in. Simply try to change the type of the input to url, i.e. change
<input type="text" id="url" name="url" ...>
to
<input type="url" id="url" name="url" ...>
Then, when a non-conforming url string is entered, the browser will not submit the form and automatically indicate the issue. This even works out of the box with a default url pattern. See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/url for more information on custom patterns, placeholders and much more.

Checkboxes in horizontal form, and on the right side of the label

Is it possible to have the checkbox labels on the left like the others, and the checkbox on the right like the other inputs with a horizontal form?
My current setup
It looks pretty awful.
EDIT:
<%= simple_form_for :apartment, :html => {:multipart => true, :class => 'form-horizontal'}, wrapper: :horizontal_form do |f| %>
<%= f.input :pets, as: :boolean, label: 'Husdyr tilladt' %>
<% end %>
which generates the following html in the view:
<div class="form-group boolean optional apartment_pets">
<div class="checkbox"><input value="0" type="hidden" name="apartment[pets]">
<label class="boolean optional" for="apartment_pets"><input class="boolean optional" type="checkbox" value="1" name="apartment[pets]" id="apartment_pets">
Husdyr tilladt
</label>
</div>
</div>
You can add pull-right to the class of your checkbox element like so:
<input name="uh" id="uhhuh" type="checkbox" class="pull-right" />
Updated answer with user provided code:
<div class="form-group boolean optional apartment_pets">
<div class="checkbox"><input value="0" type="hidden" name="apartment[pets]">
<label class="boolean optional" for="apartment_pets">Husdyr tilladt</label>
<input class="boolean optional" type="checkbox" value="1" name="apartment[pets]" id="apartment_pets" class="pull-right">
</div>
</div>
I never used simple_form but from browsing the documentation, it looks like you should use a combination of :label => false and :inline_label => true to position your label.

Rails form_for layout links in line

I have the layout presently using nested_form_for as:
with the code as simply:
<%= f.label :monday %>
<%= f.check_box :monday %>
<%= f.label :tuesday %>
<%= f.check_box :tuesday %>
<%= f.label :wednesday %>
<%= f.check_box :wednesday %>
<%= f.label :thursday %>
<%= f.check_box :thursday %>
But I would like if these attributes could like listed in a straight line with breaks such as:
Monday | Tuesday | Wednesday | Thursday ....
Is there a setting in nested_form_for to allow this?
Note below is the HTML generated from the first response
<hr>
<strong>Day(s) special Will Appear</strong>
<ul id="dayForm">
<label for="campaign_monday">Monday</label>
<input name="campaign[monday]" type="hidden" value="0" /><input id="campaign_monday" name="campaign[monday]" type="checkbox" value="1" />
<label for="campaign_tuesday">Tuesday</label>
<input name="campaign[tuesday]" type="hidden" value="0" /><input id="campaign_tuesday" name="campaign[tuesday]" type="checkbox" value="1" />
<label for="campaign_wednesday">Wednesday</label>
<input name="campaign[wednesday]" type="hidden" value="0" /><input id="campaign_wednesday" name="campaign[wednesday]" type="checkbox" value="1" />
<label for="campaign_thursday">Thursday</label>
<input name="campaign[thursday]" type="hidden" value="0" /><input id="campaign_thursday" name="campaign[thursday]" type="checkbox" value="1" />
<label for="campaign_friday">Friday</label>
<input name="campaign[friday]" type="hidden" value="0" /><input id="campaign_friday" name="campaign[friday]" type="checkbox" value="1" />
<label for="campaign_saturday">Saturday</label>
<input name="campaign[saturday]" type="hidden" value="0" /><input id="campaign_saturday" name="campaign[saturday]" type="checkbox" value="1" />
<label for="campaign_sunday">Sunday</label>
<input name="campaign[sunday]" type="hidden" value="0" /><input id="campaign_sunday" name="campaign[sunday]" type="checkbox" value="1" />
</ul>
Rails form_for helpers help you generate HTML; the HTML generated is still subject to the same rules as other HTML elements. Rails offers ways to add HTML/CSS to the form fields themselves, which may be what you are looking for. For example,
<%= f.label :monday, :class => 'inline' %>
The :class => 'inline' adds the class 'inline' to the HTML form element on the page and you can add styling thereafter to .inline {} in your css file.
But you could also simply do something like:
Wrap the form fields with a <ul> tag,
<ul id="dayForm">
<%= f.label :monday %>
<%= f.check_box :monday %>
<%= f.label :tuesday %>
<%= f.check_box :tuesday %>
<%= f.label :wednesday %>
<%= f.check_box :wednesday %>
<%= f.label :thursday %>
<%= f.check_box :thursday %>
</ul>
And in your css file,
ul#dayForm {
list-style: none;
}
ul#dayForm input {
display: list-item;
float: left;
width: 100px; /* adjust depending on desired size */
}
ul#dayForm label {
display: list-item;
float: left;
width: 100px; /* adjust depending on desired size */
}
To create the inline effect that you are looking for.

rails is processing trash html codes

This is the rails form helper code,
<%= form_tag({ :action => "create"}, :method => "POST", :id=>"login") do -%>
<h1>Log In</h1>
<fieldset id="inputs">
<%= text_field :username, :placeholder => 'Username', :autofocus=>true%>
<%= password_field_tag :userpass, params[:userpass], placeholder: 'Password', id:'password'%>
</fieldset>
<fieldset id="actions">
<input type="submit" id="submit" value="Log in">
Register
</fieldset>
<% end %>
and this is the html code, what i want,
<form action="/login/create" method="post" id="login" >
<h1>LogIn</h1>
<fieldset id="inputs">
<input id="username" type="text" name ="username" placeholder="Username" autofocus required>
<input id="password" type="password" name="userpass" placeholder="Password" required>
</fieldset>
<fieldset id="actions">
<input type="submit" id="submit" value="Log in" name="apply">
Register
</fieldset>
</form>
However, if i run the rails code, it makes the code like this,
<input id="username_{:placeholder=>"Username", :autofocus=>true}" name="username[{:placeholder=>"Username", :autofocus=>true}]" size="30" type="text">
Somebody knows what the problem is?
You'll want to use text_field_tag in your form, not just text_field:
<%= form_tag({ :action => "create"}, :method => "POST", :id=>"login") do -%>
<h1>Log In</h1>
<fieldset id="inputs">
<%= text_field_tag :username, params[:username], { :placeholder => 'Username', :autofocus => true } %>
<%= password_field_tag :userpass, params[:userpass], placeholder: 'Password', id:'password'%>
</fieldset>
<fieldset id="actions">
<input type="submit" id="submit" value="Log in">
Register
</fieldset>
<% end %>
You should also look into field_set_tag - that may save you some headaches if you're expecting to use the HTML fieldset tag.

Why isn't my signup form working until all of the form fields are filled?

A few days ago, my signup form for an app I'm building was working fine. The 'create my account' button would work even if no form fields were filled, and an error message would be displayed right away. Now, when I try to submit the form, the form only will submit or show error messages when all of the fields have been filled. If I try to submit the form without filling all of the fields, nothing happens. The signup button doesn't work correctly.
The only significant change that I made that I can think of is switching the stripe plan I was using to a free trial plan instead of a plan where the purchaser of the application pays up-front. I have no idea what could be causing this problem, so I don't know what code I should post. Any help you can provide would be appreciated.
The signup form I have in rails is as follows(minus some javascript that I'm using for Stripe):
<div class="row">
<div class="span6 offset4">
<%= form_for(#user) do |f| %>
<%= render 'shared/error_messages' %>
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.label :email %>
<%= f.text_field :email %>
<%= f.label :password %>
<%= f.password_field :password %>
<%= f.label :password_confirmation, "Password confirmation" %>
<%= f.password_field :password_confirmation %>
<%= f.label :morning_meds, "Do you take medications in the morning?" %>
<%= f.select :morning_meds, [['Yes'], ['No']] %>
<%= f.label :lunch_meds, "Do you take medications at lunch?" %>
<%= f.select :lunch_meds, [['Yes'], ['No']] %>
<%= f.label :night_meds, "Do you take medications in the evening?" %>
<%= f.select :night_meds, [['Yes'], ['No']] %>
<%= f.label :time_zone, "Choose your time zone" %>
<%= f.select :time_zone, [['Eastern'], ['Central'], ['Mountain'], ['Pacific']] %>
<%= f.label :phone_number, "Your cell phone number" %>
<%= f.text_field :phone_number %>
<div class="form-row">
<label>Card Number</label>
<input type="text" size="20" autocomplete="off" class="card-number" />
</div>
<div class="form-row">
<label>CVC</label>
<input type="text" size="4" autocomplete="off" class="card-cvc" />
</div>
<div class="form-row">
<label>Expiration Date</label>
<%= select_month nil, {add_month_numbers: true}, {name: nil, class: 'card-expiry-month' } %>
<span> / </span>
<%= select_year nil, {start_year: Date.today.year, end_year: Date.today.year+15}, {name: nil, class: 'card-expiry-year' } %>
</div>
<%= f.submit "Create my account", class: "btn btn-large btn-primary" %>
<% end %>
</div>
</div>
<div class="row">
<div class="span6 offset4">
<form accept-charset="UTF-8" action="/users" class="new_user" id="new_user" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="✓" /><input name="authenticity_token" type="hidden" value="QqrFVykfeY1+9jImvp8VjTzrQxq8VlBF+vC6V85klw0=" /></div>
<label for="user_name">Name</label>
<input id="user_name" name="user[name]" size="30" type="text" />
<label for="user_email">Email</label>
<input id="user_email" name="user[email]" size="30" type="text" />
<label for="user_password">Password</label>
<input id="user_password" name="user[password]" size="30" type="password" />
<label for="user_password_confirmation">Password confirmation</label>
<input id="user_password_confirmation" name="user[password_confirmation]" size="30" type="password" />
<label for="user_morning_meds">Do you take medications in the morning?</label>
<select id="user_morning_meds" name="user[morning_meds]"><option value="Yes">Yes</option>
<option value="No">No</option></select>
<label for="user_lunch_meds">Do you take medications at lunch?</label>
<select id="user_lunch_meds" name="user[lunch_meds]"><option value="Yes">Yes</option>
<option value="No">No</option></select>
<label for="user_night_meds">Do you take medications in the evening?</label>
<select id="user_night_meds" name="user[night_meds]"><option value="Yes">Yes</option>
<option value="No">No</option></select>
<label for="user_time_zone">Choose your time zone</label>
<select id="user_time_zone" name="user[time_zone]"><option value="Eastern">Eastern</option>
<option value="Central">Central</option>
<option value="Mountain">Mountain</option>
<option value="Pacific">Pacific</option></select>
<label for="user_phone_number">Your cell phone number</label>
<input id="user_phone_number" name="user[phone_number]" size="30" type="text" />
<div class="form-row">
<label>Card Number</label>
<input type="text" size="20" autocomplete="off" class="card-number" />
</div>
<div class="form-row">
<label>CVC</label>
<input type="text" size="4" autocomplete="off" class="card-cvc" />
</div>
<div class="form-row">
<label>Expiration Date</label>
<select class="card-expiry-month" id="date_month">
<option value="1">1 - January</option>
<option value="2">2 - February</option>
<option value="3">3 - March</option>
<option value="4">4 - April</option>
<option value="5">5 - May</option>
<option value="6">6 - June</option>
<option value="7">7 - July</option>
<option value="8">8 - August</option>
<option value="9">9 - September</option>
<option value="10">10 - October</option>
<option value="11">11 - November</option>
<option value="12">12 - December</option>
</select>
<span> / </span>
<select class="card-expiry-year" id="date_year">
<option value="2012">2012</option>
<option value="2013">2013</option>
<option value="2014">2014</option>
<option value="2015">2015</option>
<option value="2016">2016</option>
<option value="2017">2017</option>
<option value="2018">2018</option>
<option value="2019">2019</option>
<option value="2020">2020</option>
<option value="2021">2021</option>
<option value="2022">2022</option>
<option value="2023">2023</option>
<option value="2024">2024</option>
<option value="2025">2025</option>
<option value="2026">2026</option>
<option value="2027">2027</option>
</select>
</div>
<input class="btn btn-large btn-primary" name="commit" type="submit" value="Create my account" />
</form>
It'd be helpful to see the HTML source your view generates, but you likely have 1+ fields with the HTML5 required attribute that you are leaving blank.
By default, newer browsers like Chrome will not allow the form to submit until all fields flagged with the required attribute have a value. To stop this you can add the novalidate attribute to the <form ... tag.
<%= form_for(#user, { :novalidate => true }) do |f| %>

Resources