Get the value of <option> from views to the controller - ruby-on-rails

Since 'HTML' do not have the attribute 'name',I am looking for a way to accept the value, which I populated in views, in the controller and assign it a variable name for another use.
This is sample of my code:`
enter code here<form action="<%=url_for(:action =>:make_comment) %>">
<fieldset>
<select>
<%#category.each {|x|%>
<option id="label"> <%=x%></option>
<%}%>
</select>
</fieldset>
<input type="submit" value="submit"/>
</form>`

Are you saying that your html doesn't have a name attribute? If so, why?
The name attribute is what the server will interpret as the "key" for the value that you are sending. I don't know what other way you could try to go about doing this.
Maybe if you paste some code from your controller and your view, I could give a better answer.
Edit: After seeing your edited question, what you want to do is have your select tag with the name attribute, and your option tags have a value attribute with the value you want to send.
Hope this helps.

This example show how you create a select tag:
select("post", "person_id", Person.all.collect {|p| [ p.name, p.id ] }, {})
In this case, you would be able to get (in your controller) the value of the selected option through
params[:post][:person_id]
Is this what you want? Let me know if I misunderstood your question.

Related

Filtering displayed records by form input

I'm super new to programming and am stuck... again,
I'm using rails 3 and currently have a venue model where each venue belongs to an area and a type (which are each thier own models) all of the venues in the database are displayed at the index page in partitions displaying the venue name, and its area and type.
How can I go about having a form with 2 dropdowns (areas and types) on the index page which filter the venue records shown depending on what is selected in the dropdowns. e.g. select pubs as type and Manchester as area and only the pubs in Manchester are shown or select pubs as type and all as area and all the pubs from all areas are shown.
I have tried installing sphinx and thinking_sphinx but can't seem to get them working on my windows 7. I got as far as a 1067 error on service startup and a "Failed to start searchd daemon." from thinking_sphinx on rake ts:start, which im presuming is from the sevice not running, so I'm hoping the answer to this won't involve sphinx.
I've had a look at scopes and am thinking this could possibly be the way to go? Although I haven't got the first idea as to how to include a dropdown to select the scope needed or indeed how to write a scope which will satisfy the kind of filter I want.
Thanks very much for any help, its much appreciated!
In your controller you should be able to do something as simple as:
#filtered_venues = Venue.where(:area => params[:venue][:area], :type => params[:venue][:type]).all
That should give you the filtered results that you want.
And then in your view you should be able to use form helpers to create the select elements:
select("venue", "area", ['New York', 'London', 'Amsterdam'], {}, { :prompt => 'Select Area' })
select("venue", "type", ['Pub', 'Outdoor', 'Hall'], {}, { :prompt => 'Select Type' })
Should output something like:
<select name="venue[area]">
<option value="">Select Area</option>
<option value="New York">New York</option>
<option value="London">London</option>
<option value="Amsterdam">Amsterdam</option>
</select>
<select name="venue[:type]">
<option value="">Select Type</option>
<option value="Pub">Pub</option>
<option value="Outdoor">Outdoor</option>
<option value="Hall">Hall</option>
</select>
There are a lot of other ways to get the options in there dynamically if you have collections ready for area or type. Check out the following for more information: http://api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html
You can do this in several ways, depending on how exactly you want to filter. The best is to build the filter into a .find(:conditions => ...) call and let the database do the hard work. If you don't know beforehand on what parameters you are going to filter, it's easier but less efficient to do it in code. Assuming you have search parameters venue_area and venue_type, you could do something like this in the controller:
def index
#venues = Venue.all # Or whatever criteria you might have here
#venues = #venues.select { |v| v.area_id == params[:venue_area] } if !params[:venue_area].blank?
#venues = #venues.select { |v| v.type_id == params[:venue_type] } if !params[:venue_type].blank?
...
end
You then create dropdowns containing all type and area ID:s in your search form. There are several helpers you can use for this, such as select_tag. The #options would be better populated in the controller, of course, but this shows the relationship clearer:
<form method="get">
<% #options = Area.all.map { |a| [ a.name, a.id ] } %>
<%= select_tag("venue_area", options_for_select(#options)) %>
<input type="submit" value="Filter" />
</form>
This type of filtering could be done in either JavaScript, Ruby, or both.
If the HTML itself contains all the metadata you need to determine which items match which filters, then it could be done entirely in JavaScript by hiding and showing elements in response to a change in the form.
If the user is required to click a submit button for their chosen filters to take effect, then the form could simply submit and you could repopulate the form on the back end with Rails.
If the HTML doesn't have all the metadata and you don't want them to have to submit a form, you can use AJAX to send the chosen filters to the back end, have Rails construct the new form and send it back to the client, and then use JavaScript to update the front end.
You may get a few ideas from the Railscasts episode Search, Sort, Paginate with AJAX. It's not exactly your situation, but it might point you in the right direction for how these types of operations work in general.

How do I allow a user to select zero options from a multiple selection box in rails?

I have a settings model with a column options, and set it to serialize with serialize :options. In my view, I have a multiple selection box, using select("settings", "options", ['option1','option2','option3'], {}, :multiple => true) which works fine so long as the user selects at least one option. However, if they don't select any options, no options are submitted and so the options aren't updated.
How do I allow the user to select zero options from a multiple selection box in rails?
That has nothing to do with rails: html form won't send such parameter to server if nothing is chosen in 'select' element. But you should be able to fix it in controller. Something like this
if params[:settings] == nil
params[:settings] = [];
end
Not sure if there's more elegant solution.
Add a hidden field after the select box, that posts an empty value to "settings[options]"
It's same trick that rails uses to make sure unchecked checkboxes get posted as false.
I do not like assuming a value is empty if the attribute is not posted. It breaks the way Rails expects to update attributes, and it can present problems if you are using your controller actions also for APIs as well as HTML. My preferred way of handling this is by adding a hidden input field before multiselects.
<input type="hidden" value="" name="parent_model[my_attribute_ids][]">
If you use JQuery you can automate the addition of these hidden input fields:
$('select[multiple="multiple"]').each(function(i){
$(this).before('<input type="hidden" name="'+this.name+'" value="" />')
});
I realize this answer is not very timely, but I hope this will help someone with a similar question.
You could provide a "None" option.
Example from: http://api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html
select("post", "person_id", Person.all.collect {|p| [ p.name, p.id ] }, {:include_blank => 'None'}, {:multiple => true})
Would become
<select name="post[person_id]" multiple="multiple">
<option value="">None</option>
<option value="1">David</option>
<option value="2" selected="selected">Sam</option>
<option value="3">Tobias</option>
</select>

In MVC 2, how to bind a Html.TextBox to a Model property

My model has a property of "output" and my form has a TextBox named "output", both spelled exactly the same. When I fill out the form and post it, the returning view has unexpected results.
Specifically, I receive the posted "output" form variable which is then bound to my Model in the Controller Method, then I change this variable to a different value before I pass the Model back to the view.
the posted output property is "one thing"
my Model property is set to "another"
I have this in my code: <%= Html.TextBox("output") %>
Which renders to this: <input id="output" name="output" type="text" value="one thing" />
However, when debugging, the Model does contain the correct value ("another").
Its using the posted value rather than the value assigned in the controller. Any ideas why and how to fix it?
Assuming you're using a strongly typed view like so:
<%# Page ... Inherits="System.Web.Mvc.ViewPage<...TestModel>" %>
And having an EditorFor replacing your
<%= Html.TextBox("output") %> like so <%= Html.EditorFor(p=>p.output) %>
you can do in your Controller
ModelState.SetModelValue("output", new ValueProviderResult("Some string", string.Empty, new CultureInfo("en-US")));
A similar question has been asked here

ASP .Net MVC, problem with checkboxes!

Basically I have a set of checkboxes that are dynamically created from view data like so:
<input type="checkbox" name="Calendars" value="<%= c.ID %>" /><%= c.Name %>
The value being the Calendar Id.
I can get what checkbox has been brought back using the FormsCollection its messy but it works!
(There also seems to be a bug with the checkbox helper that renders a hidden field next to the checkbox which means true is actually returned as "true,false"! I can work around this so its not an issue just thought Id mention it)
The problem comes when trying to hook the checkboxes up on an edit page!
I have a schedule class which can have multiple calendars and I want to show which calendars a schedule has by checking them on the edit!
My view is strongly typed but MVC magic can't map this!
Any ideas on whats the best way to do this??
I had tried passing the calendar ids in ViewData and do some inline code to check the appropriate checkbox but this is getting messy!
Thanks!!
UPDATE:
Done this
s.ID == c.ID).Select(s => s).Count() > 0) ? "checked=checked" : "" %>
You need to add "checked" tag manually to every check box:
<input type="checkbox" name="Calendars" value="<%= c.ID %>" checked="checked" /><%= c.Name %>
You dont need <input type="checkbox" - use Html.Checkbox(). It renders a hidden field next to the checkbox - but it is not a bug. From ASP.NET MVC source, InputExtensions.cs, line 201:
// Render an additional <input type="hidden".../> for checkboxes. This
// addresses scenarios where unchecked checkboxes are not sent in the request.
// Sending a hidden input makes it possible to know that the checkbox was present
// on the page when the request was submitted.
Use this:
<%= Html.CheckBox("Calendars", c.ID) %>

HTML.CheckBox(string) evaluates to two HTML elements instead of one

The code
<%=Html.CheckBox("SendEmail") %>
evaluates to two HTML elements when it's rendered
<input id="SendEmail" name="SendEmail" type="checkbox" value="true" />
<input name="SendEmail" type="hidden" value="false" />
Is this by a bug? Or by design? If it's by design, why?
I was having some trouble this morning with retrieving selected values from a checkbox group in my MVC app. I sent this out to my team and thought I'd share it with everyone else.
When posting back values for checkboxes, the standard behaviour of all browsers is to completely leave out un-checked checkboxes from the post back. So if you have a checkbox that isn’t checked then nothing shows up for this in Request.Form. This is a fairly well-known phenomenon that most developers account for.
In ASP.Net MVC when you use Html.Checkbox, it attempts to get around this and ensure that you have a value posted back (in this case ‘false’) for un-checked checkboxes. This is done by adding a hidden field containing the value ‘false’.
Eg.
<%= Html.CheckBox("Sites", s.Selected, new { value = s.Value })%>
Produces the HTML
<input id="Sites" name="Sites" type="checkbox" value="1" /><input name="Sites" type="hidden" value="false" />
This is all good and well, until you attempt to use checkbox groups. That is more than one checkbox with the same name where the values are sent back in a single comma separated string.
MVC can split this string up for you automatically if you define the value as an array (string[] Sites).
Here’s the view code:
<% foreach(var s in Model) { %>
<li><%= Html.CheckBox("Sites", s.Selected, new { value = s.Value })%>
<label><%= s.Name %></label>
</li>
<% } %>
The appropriate controller action:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(int Id, string Name, string SubmissionUrl, string[] Sites)
Unfortunately, because the Html.Checkbox produces this hidden field value as well, the resulting array contains not only values for the selected checkboxes but also ‘false’ for every un-checked checkbox. You get an array that looks something like this:
[0] 'false'
[1] 'false'
[2] '110'
[3] '50'
[4] 'false'
Where 'false' is for checkboxes that are not selected, and integers are the values for the checkboxes that are selected.
This can throw your code out quite a bit if you have only integers for the values of your checkboxes and want to define the result as an array of integers, like so:
public ActionResult Edit(int Id, string Name, string SubmissionUrl, int[] Sites)
Which results in an exception being thrown because it can’t convert the string value ‘false’ to an integer.
The solution is very simple, just avoid Html.Checkbox and manually create the checkboxes in your view code like this:
<% foreach(var s in Model) { %>
<li><input type="checkbox" name="Sites" value="<%=s.Value%>" <% if (s.Selected) { %>checked="checked"<% } %> />
<label><%= s.Name %></label>
</li>
<% } %>
Hope this helps someone else!
When all else fails, read the source code. :) this is from HtmlHelper.cs:
// Render an additional <input type="hidden".../> for checkboxes. This
// addresses scenarios where unchecked checkboxes are not sent in the request.
// Sending a hidden input makes it possible to know that the checkbox was present
// on the page when the request was submitted.
I'm not exactly sure how useful that is, but at least you know the intention.
I think I found something on the web that is directly related to my question.

Resources