Separating year, month and day in rails forms - ruby-on-rails

Normally, in order to get a date select in rails, I write this:
<%= form_for(:buddy, :url => {:action => :create}) do |f| %>
<%= f.date_select(:dob) %>
<%= f.submit("HI") %>
<% end %>
and get this html as a result:
<form action="/buddy/create" accept-charset="UTF-8" method="post"><input name="utf8" type="hidden" value="✓" /><input type="hidden" name="authenticity_token" value="Qs8RK+6gEt9ZoycMbMHwX4xMyoFpRvjA/El3cLnO30RXddr864WmEXzyAgYtXBe5Y9l0zC3UDw4ggRw1xYW1sg==" />
<select id="buddy_dob_1i" name="buddy[dob(1i)]">
<option value="2010">2010</option>
<!-- ETC -->
<select id="buddy_dob_2i" name="buddy[dob(2i)]">
<option value="1" selected="selected">January</option>
<!-- ETC -->
<select id="buddy_dob_3i" name="buddy[dob(3i)]">
<option value="1">1</option>
<!-- ETC -->
<input type="submit" name="commit" value="HI" />
But now I'm using bootstrap. If I use the bootstrap_form_for gem, I run into the problem that on small screens, the three selects get placed on top of each other, which is unacceptable. So I came up with what I thought was a good solution: to place each of the selects in a different field of a table, which prevents the behaviour. So I have written this code:
<%= form_for(:buddy, {:action => :create, :role => 'form'}) do |f| %>
<div class="form-group">
<label for="buddy_dob">Date of Birth</label>
<table class="table functional-table">
<tr>
<td>
<%= select_year(Date.today, {:start_year => DateTime.now.year, :end_year => DateTime.now.year - 117}, {:name => 'buddy[dob(1i)]', :id => 'buddy_dob_1i', :class => 'form-control'}) %>
</td>
<td>
<%= select_month(Date.today, {}, {:name => 'buddy[dob(2i)]', :id => 'buddy_dob_2i', :class => 'form-control'}) %>
</td>
<td>
<%= select_day(1, {}, {:name => 'buddy[dob(3i)]', :id => 'buddy_dob_3i', :class => 'form-control'}) %>
</td>
</tr>
</table>
</div>
<div class="form-group">
<%= f.submit("HI") %>
</div>
<% end %>
which produces this result:
<form role="form" action="/buddy/new" accept-charset="UTF-8" method="post"><input name="utf8" type="hidden" value="✓" /><input type="hidden" name="authenticity_token" value="6Ek01J6PIgzHl/NLpjI6V+kolUVCpw7jrQTF8eYT3ef98/8Dm6qWwuLG1kHnr92xBr0rCAY1+S1xzK60mli3EQ==" />
<div class="form-group">
<label for="buddy_dob">Date of Birth</label>
<table class="table functional-table">
<tr>
<td>
<select id="buddy_dob_1i" name="buddy[dob(1i)]" class="form-control">
<option value="2015" selected="selected">2015</option>
<!-- ETC -->
</td>
</tr>
</table>
<table class="table functional-table">
<tr>
<td>
<select id="buddy_dob_2i" name="buddy[dob(2i)]" class="form-control">
<option value="1" selected="selected">January</option>
<!-- ETC -->
</td>
</tr>
</table>
<table class="table functional-table">
<tr>
<td>
<select id="buddy_dob_3i" name="buddy[dob(3i)]" class="form-control">
<option value="1" selected="selected">1</option>
<!-- ETC -->
</td>
</tr>
</table>
<div class="form-group">
<input type="submit" name="commit" value="HI" />
</div>
</form>
The display for this works exactly as I want, however when I try to submit the form I am redirected to the action :new with no errors registered by rails and no entry created. I never reach :create. I suspect this might be because I've manually separated the date fields which date_select separates and then pieces back together and rails cannot handle this, but I am not sure. How can I fix this and get the form working?

You have nested forms - this is illegal! Most of the browsers will simply ignore the inner form tag, so you'll end up with a DOM structure as presented. The outer form does not specify the action attribute, so browsers will append the current path as an action, in this case - /buddy/new. I'm a little bit surprised you're not getting routing error here - did you by any chance use match /buddy/new without specifying the verb?
Anyway - the solution is to get rid of surrounding form (the one with the role) and instead attach this role to your form_for call:
<%= form_for(:buddy, url: {action: :create}, html: {role: :form) do |f| %>

SOLVED! I just changed form_for to form_tag and it now works as expected. Thanks to BroiSatse for the information about ActionDispatch knowing how to convert the params; it encouraged me to look elsewhere for problems.

Your select names are not "standard". buddy[dob(3i)] is not a valid name.
When the query is sent to Rails, a first module changes all the received names into params. Here, it can't, and fail.
You should set somethink like this : buddy[dob_month].

Related

How to display data for nested objects in a check box in Rails?

I'm having this issue where I want to display the correct answer in a check box in Rails, to no avail.
The structure is further complicated by the fact that my models are nested into one another so that Survey not only has_many, but also accepts_nested_attributes_for Questions and Questions has_many Choices similarly. The problem is that I'm simply not able to get the box checked for the correct answer.
The data are saved to the database as a boolean in a column called correct_choice and this code for the show action shows the check boxes, but the correct choice is not checked:
<table class="col-md-10">
<thead>
<tr>
<% for question in #survey.questions do %>
<li><%= h question.content %></li>
<% for choice in question.choices do %>
<li><%= h choice.content %>
<%= h check_box(:choice, :correct_choice ) %>
<% end %>
</li>
</li>
<% end %>
</tr>
</thead>
</table>
I've read the documentation, but I cannot figure out how to apply it to my case. Can anybody point me in the right direction?
EDIT
This is the HTML that I get out:
<table class="col-md-10">
<thead>
<tr>
<li>Is this a question?</li>
<li>I'm not big. I'm having a breakdown.
<input name="correct_choice[content]" type="hidden" value="0" /><input type="checkbox" value="1" name="correct_choice[content]" id="correct_answer_content" />
<li>Come on, I'm not big.
<input name="correct_choice[content]" type="hidden" value="0" /><input type="checkbox" value="1" name="correct_choice[content]" id="correct_choice_content" />
<li>Who is hungry?
<input name="correct_choice[content]" type="hidden" value="0" /><input type="checkbox" value="1" name="correct_choice[content]" id="correct_choice_content" />
<li>Pass the cheese, please.
<input name="correct_choice[content]" type="hidden" value="0" /><input type="checkbox" value="1" name="correct_choice[content]" id="correct_choice_content" />
</li>
</li>
</tr>
</thead>
</table>
I figured it out thanks to advice from #davidwessman. What he told me was to display the html and inspect. I did and compared to the html from the edit action (the one that works).
It then became clear that I needed to use the check_box_tag command instead of check_box. This is the code that I now use:
<thead>
<tr>
<% for question in #survey.questions do %>
<li><%= h question.content %></li>
<% for choice in question.choices do %>
<li><%= h choice.content %>
<%= check_box_tag "correct_choice", "yes", answer.correct_choice %>
<% end %>
</li>
</li>
<% end %>
</tr>
</thead>

getting form value into controller in ruby on rails

I have a "search" page that have some controls and below is the search page code:
<%= form_for :search, :url => { :method => :get, :action => :search } do |f| %>
<table>
<tr>
<td align="center" style="vertical-align:top;">
<h2 style="color:Black; font-size: x-large;">Specs</h2>
<table>
<tr>
<td align="center">
<input type="text" name="tf_Zip" Style="text-align: left;" BackColor="#e5e5e5" Width="180px" ForeColor="Gray" Font-Size="Large">
</td>
</tr>
</table>
<table>
<tr>
<td>
<div class="button">
<input type="submit" name="search" value="Search" class="buttonSearch">
</div>
</td>
</tr>
</table>
</td>
<td align="center" style="vertical-align:top;">
<h2 style="color:Black; font-size: x-large;">
Result
</h2>
<% #user_zip.each do |uzr_zip| %>
<h1><%= uzr_zip.First_Name %></h1>
<% end %>
<table id="searchResult" width="100%" runat="server">
<tr>
<td bgcolor="#CCDBE0">
Image:
</td>
<td bgcolor="#CCDBE0">
<%= f.label(:zip, "Mentor") %>
</td>
</tr>
</table>
</td>
</tr>
</table>
<% end %>
And when I am trying to get the textbox value into the controllers page like below
def search
#students=Students.all
#blah = params[:search][:tf_Zip]
end
render 'search'
end
Then it gave me an error below, at this line #blah = params[:search][:tf_Zip]
undefined method `[]' for nil:NilClass
Kindle help me. Thanks
I think your params[:search] is nil?
so for this you can use
#blah = params[:tf_Zip]
or change your input field like this
<%= f.text_field :tf_Zip %>
or you can use like this
<input type="text" name="search[tf_Zip]" Style="text-align: left;"
BackColor="#e5e5e5" Width="180px" ForeColor="Gray" Font-Size="Large">
Look at your log: you will see what is coming through in params, then you'll see why params[:search][:tf_Zip] doesn't work.
The error is telling you, effectively, that params[:search] is nil, and that you can't call [tf_Zip] on nil.
Your problem is this line:
<input type="text" name="tf_Zip" Style="text-align: left;" BackColor="#e5e5e5" Width="180px" ForeColor="Gray" Font-Size="Large">
It will populate params[:tf_Zip] because it's name is "tf_Zip". If you want it to populate params[:search][:tf_Zip] then you should set the name attribute to search[tf_Zip].
What would be nicer though is to use the rails form field helpers. I don't know why you have so much raw html inside a form_for.
<input type="text" name="tf_Zip" Style="text-align: left;" BackColor="#e5e5e5" Width="180px" ForeColor="Gray" Font-Size="Large">
can be replaced with
<%= f.text_field :tf_Zip %>
which will populate params[:search][:tf_Zip]
For the other attributes (Style etc) you should set these with css. Rails will probably put a class on the field automatically which you can use to do this. The "style" (note lowercase) attribute can be used instead but it's clumsy as it doesn't allow you to restyle the field (and more generally, your site) with css.
Have you checked to see if params[:search] is nil? If it is, then trying to pull [:tf_Zip] will cause that error.
Usually you'd submit the form from one controller action and handle the result in another action.
And your statement end looks misplaced.

Rails form_for html being set to display: none

I have a standard rails form_for tag for creating and editing a new hotel. This renders just fine when visited via the edit_hotels_path, however when visting the new_hotels_path the html form tag is being set to display: none; causing the form to not show only in the "new" view.
I have restarted the server, emptied the cache, made sure they are using the same CSS but it still renders with display set to none.
Here are the styles as seen using developer tools
<form accept-charset="UTF-8" action="/hotels" class="new_hotel" id="new_hotel" method="post" style="display: none; "><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="✓"><input name="authenticity_token" type="hidden" value="pDlR3gV2tm+Z7xRFdC0uclNY13FlzxUSOjOrHs2ttO0="></div>
element.style {
display: none;
}
below is the html source being rendered, which doesn't include display: none;
<form accept-charset="UTF-8" action="/hotels" class="new_hotel" id="new_hotel" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="✓" /><input name="authenticity_token" type="hidden" value="pDlR3gV2tm+Z7xRFdC0uclNY13FlzxUSOjOrHs2ttO0=" /></div>
<div class="control-group">
<div class="controls">
<input id="hotel_name" name="hotel[name]" placeholder="Name..." size="30" type="text" /><br>
<select id="hotel_year" name="hotel[year]"><option value="2012">2012</option>
<option value="2013">2013</option>
<option value="2014">2014</option>
<option value="2015">2015</option></select><br>
<select id="hotel_month" name="hotel[month]"><option value="January">January</option>
<option value="February">February</option>
<option value="March">March</option>
<option value="April">April</option>
<option value="May">May</option>
<option value="June">June</option>
<option value="July">July</option>
<option value="August">August</option>
<option value="September">September</option>
<option value="October">October</option>
<option value="November">November</option>
<option value="December">December</option></select><br>
<textarea cols="40" id="hotel_body" name="hotel[body]" placeholder="Hotel info up to 1000 words..." rows="20">
</textarea><br>
<input id="hotel_meta_tags" name="hotel[meta_tags]" placeholder="Enter meta tags for image, as a comma separated list..." size="30" type="text" /><br>
<legend>Winner</legend>
<input name="hotel[winner]" type="hidden" value="0" /><input id="hotel_winner" name="hotel[winner]" type="checkbox" value="1" />
<br/>
</div>
<div class="form-actions">
<input class="btn-large btn-success" name="commit" type="submit" value="create" />
</div>
</div>
</form>
below is the code, would appreciated any help.
_form.html.erb
<%= form_for #hotel do |f| %>
<% if #hotel.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#hotel.errors.count, "error") %> prohibited this article from being saved:</h2>
<ul>
<% #hotel.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<%= render partial: "shared/code_sheet" %>
<div class="control-group">
<div class="controls">
<%= f.text_field :name, placeholder: "Name..." %><br>
<%= f.select :year, [2012, 2013, 2014, 2015] %><br>
<%= f.select :month, ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"] %><br>
<%= f.text_area :body, placeholder: "Hotel info up to 1000 words..." %><br>
<%= f.text_field :meta_tags, placeholder: "Enter meta tags for image, as a comma separated list..." %><br>
<legend>Winner</legend>
<%= f.check_box :winner %>
<br/>
</div>
<div class="form-actions">
<%= f.submit "create", class: "btn-large btn-success" %>
</div>
</div>
<% end %>
edit.html.erb
<div class="container">
<h1>Editing hotel</h1>
<%= render "form" %>
<%= link_to 'hotels index', hotels_path %>
</div>
new.html.erb
<div class="container">
<h1>New hotel</h1>
<%= render "form" %>
<%= link_to 'hotels index', hotels_path %>
</div>
It could be anything. You must know what is in your CSS. Did you search for 'display: none;' in your CSS files and checked the matches? element.style is usually set directly on the HTML tag. Search the view also place debugging string to make sure it is pulling the appropriate .html.

form_tag with :remote => true does not update div, skips to separate page

I am trying to update a div based on a form submit. I am on Rails 3.1.1. I am trying to adapt someone else's recipe. My code in the view is something like this in main.html.erb:
<%= javascript_include_tag :defaults %>
<div id='seq_search'>
<%= form_tag(:remote => true, :update => 'seq_select', :action => 'select') do %>
<p>
<%= search_field_tag :query, '', :size => 45 %>
</p>
<p>
<%=submit_tag "Submit", :disable_wth => "Adding ..."%>
</p>
<% end %>
</div>
<div id='seq_select'>
</div>
The controller looks like
class SearchAjaxController < ApplicationController
def main
end
def select
render :text => '<li> '+params[:query] + ' </li>'
end
end
However, when I enter something in the text box and press submit, instead of updating the div, it goes off to another page rendering just the output of the select method of the controller.
If I look at the page source of the form, it is something like this:
<div id='seq_search'>
<form accept-charset="UTF-8" action="/search_ajax/select?remote=true&update=seq_select" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="✓" /><input name="authenticity_token" type="hidden" value="wlOm4H7GvZAQoIVpjxPLqHAQLOIpJ4V5r0WYEpvCCrQ=" /></div>
<p>
<input id="query" name="query" size="45" type="search" value="" />
</p>
<p>
<input disable_wth="Adding ..." name="commit" type="submit" value="Submit" />
</p>
</form></div>
<div id='seq_select'>
</div>
It seems that the form is simply passing remote=true&update=seq_select as arguments to the controller's method/function. Is this what is supposed to happen?
Update:
So I tried to add to follow Mike Campbell's sugggestion and added the following code to my view (`.html.erb') file
<SCRIPT type='text/Javascript'>
$(function(){
$('#form-id').bind('ajax:success', function(xhr, data, status){
$('#seq_select').html(data);
});
}
</SCRIPT>
and also gave an id to the form:
<%= form_tag(:remote => true, :update => 'seq_select', :action => 'select', :id => 'form-id') do %>
Submitting the form still doesn't update the page. It simply skips to a new rendered view as before. The generated HTML reads:
<SCRIPT type='text/Javascript'>
$(function(){
$('#form-id').bind('ajax:success', function(xhr, data, status){
$('#seq_select').html(data);
});
}
</SCRIPT>
<div id='seq_search'>
<form accept-charset="UTF-8" action="/ajax_search/select/form-id?remote=true&update=seq_select" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="✓" /><input name="authenticity_token" type="hidden" value="wlOm4H7GvZAQoIVpjxPLqHAQLOIpJ4V5r0WYEpvCCrQ=" /></div>
<p>
<label> Search by identifiers, accessions, and gene names.. </label>
</p>
<p>
<input id="query" name="query" size="45" type="search" value="" />
</p>
<p>
<input disable_wth="Adding ..." name="commit" type="submit" value="Submit" />
</p>
</form></div>
<div id='seq_select'>
</div>
Update:
It seems that the syntax for form_tag was wrong, and the first argument has to be the name of the action. I now have <%= form_tag( 'select', :remote => true, :id => 'form_id') do %> which generates the associated HTML <form accept-charset="UTF-8" action="select" data-remote="true" id="form_id" method="post">. Which is better, but my Ajax is still not working.
I think this has to do with respond to xhr in the controller. you should specify this is a xhr request.
See here for a question on that.

Adding a background image or an image tag to Formtastic radio buttons with a collection

I have this formtastic field in a form where an user input his credit card data:
<%= form.input :credit_card_type, :as => :radio, :collection => User.credit_card_types %>
User.credit_card_types look like this:
def self.credit_card_types
{'Visa' => VISA, 'Master Card' => MASTER_CARD, 'American Express' => AMERICAN_EXPRESS}
end
Which give me the following html:
<li id="user_credit_card_type_input" class="radio optional">
<fieldset>
<legend class="label">
<label>Tipo de tarjeta</label>
</legend>
<ol>
<li>
<label for="user_credit_card_type_1">
<input type="radio" value="1" name="user[credit_card_type]" id="user_credit_card_type_1"> Master Card
</label>
</li>
<li>
<label for="user_credit_card_type_0">
<input type="radio" value="0" name="user[credit_card_type]" id="user_credit_card_type_0"> Visa</label>
</li>
<li>
<label for="user_credit_card_type_2">
<input type="radio" value="2" name="user[credit_card_type]" id="user_credit_card_type_2"> American Express</label>
</li>
</ol>
</fieldset>
</li>
Given that, my question is, how can I add an specific background image to each radio button label? I can't do it with CSS because the labels have not any id and I can't (or I don't know how) put one to then. I tried to add an image_tag but it escapes the html. Any suggestion ?
Formtastic can be customized for your needs. You should be able to find Formtastic configuration file in config/initializers. Add a line like this:
Formtastic::SemanticFormHelper.builder = SemanticCustomFormBuilder
Then create in your lib directory a file named semantic_custom_form_builder.rb
class SemanticCustomFormBuilder < Formtastic::SemanticFormBuilder
def cicloon_special_radio_button_input
#define your radiobuttons here
end
end
You can use your custom definition like this in your forms:
<%= form.input :credit_card_type, :as => :cicloon_special_radio_button %>

Resources