rails is processing trash html codes - ruby-on-rails

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.

Related

style a Rails form_for with radio buttons to Bootstrap

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.

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.

capybara cant find simple_form field with collection

I have simple_form form with fields
<%= simple_form_for(#menu) do |f| %>
<%= f.error_notification %>
<div class="form-inputs">enter code here
<%= f.input :order_date, :input_html => { :value => Time.now.strftime("%A") } %>
<%= f.input :title %>
<%= f.input :dish_category, input_html: {id: "dish_category"}, as: :radio_buttons, collection: ["First course", "Main course", "Drink"] %>
<%= f.input :description %>
<%= f.input :price %>
</div>
<div class="form-actions">
<%= f.button :submit %>
</div>
<% end %>
And it works fine. But when I testing it with capybara, it gives me an error:
Failures:
1) Lunches Admin create menu lunches admin can create new menu only for today
Failure/Error: fill_in 'Dish category', :with => 'First course'
Capybara::ElementNotFound:
Unable to find field "Dish category"
Test itself:
scenario "lunches admin can create new menu only for today" do
admin = FactoryGirl.create(:lunches_admin)
login_as(admin)
visit new_menu_path
fill_in "Order date", :with => Time.now.strftime("%A")
fill_in "Title", :with => "Borsh"
fill_in "Description", :with => "Mmm, yamy"
fill_in "Price", :with => 99.99
fill_in 'Dish category', :wit`enter code here`h => 'First course'
click_button 'Create Menu'
expect(page).to have_content "Menu was successfully created."
end
The HTML itself: (I have to write something more, because the program says that it's to many code and not enough words)
<form novalidate="novalidate" class="simple_form new_menu" id="new_menu" action="/menus" accept-charset="UTF-8" method="post"><input name="utf8" type="hidden" value="✓" /><input type="hidden" name="authenticity_token" value="Dgh1T4kP0h/bqnXo6blYSu8lBPLwbM/3XD8sKVijc61YTYPmjVlwdHFfPZuaqwARambyChdOVstRQuO6WmgPbQ==" />
<div class="form-inputs">
<div class="form-group string optional menu_order_date"><label class="string optional control-label" for="menu_order_date">Order date</label><input value="Friday" class="string optional form-control" type="text" name="menu[order_date]" id="menu_order_date" /></div>
<div class="form-group string required menu_title"><label class="string required control-label" for="menu_title"><abbr title="required">*</abbr> Title</label><input class="string required form-control" type="text" name="menu[title]" id="menu_title" /></div>
<div class="form-group radio_buttons required menu_dish_category"><label class="radio_buttons required control-label" for="dish_category"><abbr title="required">*</abbr> Dish category</label><span class="radio"><label for="menu_dish_category_first_course"><input id="dish_category" class="radio_buttons required" type="radio" value="First course" name="menu[dish_category]" />First course</label></span><span class="radio"><label for="menu_dish_category_main_course"><input id="dish_category" class="radio_buttons required" type="radio" value="Main course" name="menu[dish_category]" />Main course</label></span><span class="radio"><label for="menu_dish_category_drink"><input id="dish_category" class="radio_buttons required" type="radio" value="Drink" name="menu[dish_category]" />Drink</label></span></div>
<div class="form-group text required menu_description"><label class="text required control-label" for="menu_description"><abbr title="required">*</abbr> Description</label><textarea class="text required form-control" name="menu[description]" id="menu_description">
</textarea></div>
<div class="form-group decimal required menu_price"><label class="decimal required control-label" for="menu_price"><abbr title="required">*</abbr> Price</label><input class="numeric decimal required form-control" type="number" step="any" name="menu[price]" id="menu_price" /></div>
</div>
<div class="form-actions">
<input type="submit" name="commit" value="Create Menu" class="btn btn-default" />
</div>
</form>
Since dish_category is a radio button, you need to use another capybara selector in order to interact with it.
Change
fill_in 'Dish category', :with => 'First course'
to:
choose('First course')
and that should do the trick.
You can read more about capybara selectors for forms here: https://github.com/jnicklas/capybara#interacting-with-forms

How do I create an interactive form with Simple Form?

I have a model (Listing) that has many, many attributes (say 25).
I would like to create an AJAX form that is dynamic based on the input in the form.
Meaning that if a user chooses type=b, they will see other fields that they should see and not ones they shouldn't.
Ideally they should load immediately, with the right content from the db - i.e. in an AJAXy way.
What's the best way to approach this?
Thanks.
Edit: Here is an example of my _form.html.erb. You will notice that I have included 2 if statements that indicate which fields should show if the property_type value chosen is one of those specified:
<%= simple_form_for(#listing) do |f| %>
<%= f.error_notification %>
<div class="form-inputs">
<%= f.input :headline %>
<%= f.input :price %>
<%= f.association :property_type %>
If property_type == "coop"
<%= f.input :maintenance %>
<%= f.input :coop_deductible %>
<%= f.input :flip_tax %>
if property_type == "condo"
<%= f.input :common_charges %>
<%= f.input :taxes %>
</div>
<div class="form-actions">
<%= f.button :submit %>
</div>
<% end %>
Edit 2:
This is the Rails form helper that I used - powered by the gem Simple_Form:
<%= simple_form_for #listing, :defaults => { :wrapper_html => { :class => 'form-horizontal' } } do |f| %>
<%= f.error_notification %>
<fieldset>
<%= f.association :listing_category, :label => "Category: ", :label_html => { :class => "control-label"}, :wrapper_html => { :class => "controls"} %>
<div style="display: none;" data-show-for="Exclusive">
<%= f.association :listing_type %>
<%= f.association :user %>
<%= f.association :boro %>
</div>
<div style="display: none;" data-show-for="Open">
<%= f.association :neighborhood %>
<%= f.association :building %>
<%= f.association :term %>
<%= f.association :property_type %>
</div>
<div class="form-actions">
<%= f.button :submit, :class => "btn btn-primary" %>
<!-- <button type="submit" class="btn btn-primary">Save and Continue</button>
<button type="reset" class="btn">Cancel</button> -->
</div>
</fieldset>
<% end %>
This is the HTML it produced:
<form accept-charset="UTF-8" action="/listings" class="simple_form new_listing" id="new_listing" method="post" novalidate="novalidate"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="✓" /><input name="authenticity_token" type="hidden" value="1oDfg41Wx/SiPCsvf4qTAcxhFUGSNlhlLfkMy8nHW1E=" /></div>
<fieldset>
<div class="control-group select optional controls"><label class="select optional control-label control-label" for="listing_listing_category_id">Category:</label><div class="controls"><select class="select optional" id="listing_listing_category_id" name="listing[listing_category_id]"><option value=""></option>
<option value="1">Exclusive</option>
<option value="2">Open</option></select></div></div>
<div style="display: none;" data-show-for="Exclusive">
<div class="control-group select optional form-horizontal"><label class="select optional control-label" for="listing_listing_type_id">Listing type</label><div class="controls"><select class="select optional" id="listing_listing_type_id" name="listing[listing_type_id]"><option value=""></option>
</select></div></div>
<div class="control-group select optional form-horizontal"><label class="select optional control-label" for="listing_user_id">User</label><div class="controls"><select class="select optional" id="listing_user_id" name="listing[user_id]"><option value=""></option>
<option value="1">First User</option>
<option value="2">Second User</option>
<option value="3">Third User</option>
<option value="4">Fourth User</option>
<option value="5">Fifth User</option></select></div></div>
<div class="control-group select optional form-horizontal"><label class="select optional control-label" for="listing_boro_id">Boro</label><div class="controls"><select class="select optional" id="listing_boro_id" name="listing[boro_id]"><option value=""></option>
<option value="1">Brooklyn</option></select></div></div>
</div>
<div style="display: none;" data-show-for="Open">
<div class="control-group select optional form-horizontal"><label class="select optional control-label" for="listing_neighborhood_id">Neighborhood</label><div class="controls"><select class="select optional" id="listing_neighborhood_id" name="listing[neighborhood_id]"><option value=""></option>
<option value="1">Prospect Heights</option></select></div></div>
<div class="control-group select optional form-horizontal"><label class="select optional control-label" for="listing_building_id">Building</label><div class="controls"><select class="select optional" id="listing_building_id" name="listing[building_id]"><option value=""></option>
<option value="1">Trump Towers</option></select></div></div>
<div class="control-group select optional form-horizontal"><label class="select optional control-label" for="listing_term_id">Term</label><div class="controls"><select class="select optional" id="listing_term_id" name="listing[term_id]"><option value=""></option>
</select></div></div>
<div class="control-group select optional form-horizontal"><label class="select optional control-label" for="listing_property_type_id">Property type</label><div class="controls"><select class="select optional" id="listing_property_type_id" name="listing[property_type_id]"><option value=""></option>
<option value="1">Coop</option></select></div></div>
</div>
<div class="form-actions">
<input class="btn btn btn-primary" name="commit" type="submit" value="Create Listing" />
<!-- <button type="submit" class="btn btn-primary">Save and Continue</button>
<button type="reset" class="btn">Cancel</button> -->
</div>
</fieldset>
</form>
This is the JS that I included in my listing.js - which corresponds to the file that this form is on app/views/listings/new.html.erb
$(document).ready(function({
$('#listing_listing_category_id').on('change', function(){
var option = $(this).find(':selected');
$('[data-show-for]').hide(); //And maybe reset?
$('[data-show-for="+ option.text +"]').show()
});
});
When I chose the option I want, it doesn't show me the fields I want to see.
Personally I wouldn't use AJAX, just straight JS/JQuery to show/hide on click using data attributes.
See fiddle: http://jsfiddle.net/XnPZF/
First, add the data attributes to the sections you want to hide/show:
<div style="display: none;" data-show-for="coop">
<%= f.input :maintenance %>
<%= f.input :coop_deductible %>
<%= f.input :flip_tax %>
</div>
<div style="display: none;" data-show-for="condo">
<%= f.input :common_charges %>
<%= f.input :taxes %>
</div>
Then create a change event on the select:
$('#listing_property_type').on('change', function(){
var option = $(this).find(':selected');
$('[data-show-for]').hide(); //And maybe reset?
$('[data-show-for='+ option.text() +']').show()
});
For data-show-for, you can use Option text or value, just be sure to make sure the event knows which. If you plan to use this a lot of times, you could generalize it, but that would mean building your options.

How do you specify that you do not want the default <br> created after a form tag Ruby on Rails?

Right now when I create a form using a form_for Ruby on Rails creates an extra <br> tag after the form. Is there an option to not have RoR create this for me? Here is the code for creating the form:
<%= form_for(:user, :url => create_user_path) do |f| %>
<div class="field">
<%= f.label :email %>
<%= f.text_field :email %>
</div>
<div class="field">
<%= f.label :password %>
<%= f.password_field :password %>
</div>
<div class="actions">
<%= f.submit "Submit" %>
</div>
<% end %>
Output:
<form method="post" action="http://localhost:3000/users" accept-charset="UTF-8"><div style="margin:0;padding:0;display:inline"><input type="hidden" value="✓" name="utf8"><input type="hidden" value="fsdfsdf+rgJKoc5sdQvsqvT2s=" name="authenticity_token"></div>
<div class="field">
<input type="text" size="30" name="user[password_clear]" id="user_password_clear" class="text_box">
</div>
<div class="field">
<input type="text" size="30" name="user[password]" id="user_password" class="text_box">
</div>
<div class="actions">
<input type="submit" value="Sign Up" name="commit" class="button button_medium button_green">
</div>
</form>
<br>
Thank you!
As long as you don't plan on creating a new form you could refrain from closing the form until you want a to appear, just don't add the <% end %> tag until you want a br and keep the following code inside the current form.
It's not very ellegant but it will probably work the way you want it to.

Resources