I need to add options to a HTML-selector combobox inside an ERB template. First I create an array named var_arr with <option value="foo">Foo</option>-items out of an array with items/values like foo and then I try to write it between the <select></select>-tags with each
<% var_arr.each do |option| %>
<%= option %>
<% end %>
What it generates is
<option value="article">Article</option> <option value="link">Link</option> <option value="photo">Photo</option> <option value="treenode">TreeNode</option>
But it's not treated as HTML. The options aren't displayed as options in the dropdown menu.
Where's the hidden caveat here?
Yours
von Spotz
ERB treats the text from variables as text and not as html you need to mark the options as html_safe to treat it as html like this.
<% var_arr.each do |option| %>
<%= option.html_safe %>
<% end %>
Related
I have a rails 4 app that has a form that looks like:
<%= form_for #store, :html => {:multipart => true} do |f| %>
<%= f.fields_for :products do |product| %>
<%= render partial: "edit_product_fields", locals: {product:product} %>
<% end %>
<%= f.submit %>
<% end %>
and the edit_product_fields partial looks like:
<select>
<option value="Textbook" <% if product.type_of == "Textbook" %>selected<% end %>>Textbook</option>
<option value="Magazine" <% if product.type_of == "Magazine" %>selected<% end %>>Magazine</option>
<option value="Book" <% if product.type_of == "Book" %>selected<% end %>>Book</option>
</select>
When I have the code like this, I get the error:
undefined method `type_of' for #<NestedForm::Builder:0x00000102304f78>
but if I change the render line to (I just made it less explicit by taking out partial:):
<%= render "edit_product_fields", locals: {product:product} %>
I get the error:
undefined local variable or method `product' for #<#<Class:0x0000010235a248>:0x0000010684b3c0>
In your first code block, you have a Builder object being stored as product.
Fortunately, Builder provides an object method so you can access the actual object that it's representing in the form:
<select>
<option value="Textbook" <%= 'selected' if product.object.type_of == "Textbook" %>>Textbook</option>
<option value="Magazine" <%= 'selected' if product.object.type_of == "Magazine" %>>Magazine</option>
<option value="Book" <%= 'selected' if product.object.type_of == "Book" %>>Book</option>
</select>
Well type_of is not a ruby method. It looks like it's an attempt to type check though... But type checking is generally frowned upon in duck-typed languages. At any rate, we can take advantage of a Rails Form Helper instead and make this code a one-liner. But first...
The reason the render is complaining about undefined local variable or methodproduct'` after your change is because the render call expects either the first argument to be a partial name and the second to be a hash of locals:
<%= render "partial_name", local1: "a", local2: "b" %>
... or it expects the the whole thing to be a hash:
<%= render partial: "partial_name", locals: { local1: "a", local2: "b" } %>
Now, back to the form helper.
What you're looking for here is the select helper. This makes the following possible:
<%= product.select :type_of, %w[Textbook Magazine Book] %>
And this will render all of the same html as you've put into your _edit_product_field.html.erb partial. So you should probably just get rid of the partial to save on rendering time and put this directly into your form.
One other, minor point. It may be less confusing to call the fields_for block variable product_form instead of product. This is to help keep in mind that this is not a Product object you're dealing with, but rather a Form Generator object. Also, you don't need to specify :multipart => true in Rails 4 forms -- Rails knows to make the form multi-part if you have a file upload element within the form body.
So putting it all together:
<%= form_for #store do |f| %>
<%= f.fields_for :products do |product_form| %>
<%= product_form.select :product, %w[Textbook Magazine Book] %>
<% end %>
<%= f.submit %>
<% end %>
Is there a way to convert select to select_tag of this statement:
<%= select "invoice_product_code",
#invoice_product_array.each_with_index.map {
|jsondata, index|
[jsondata["invoice_product_code"],
index]},
{:selected => item["invoice_product_code"]},
:style => "width:110px"
%>
Bare in mind,
I want to define each the option value and option text from the array
selected option
style
just like the above.
this is the generated HTML:
<select id="invoice_product_code_invoice_product_code" name="invoice_product_code[invoice_product_code]" style="width:110px"><option value="0">INVPRODA</option>
<option value="1">INVPRODB</option>
<option selected="selected" value="2">INVPRODC</option>
<option value="3">INVPRODD</option>
<option value="4">INVPRODE</option>
<option value="5">INVPRODF</option>
<option value="6">INVPRODG</option></select>
I have a feeling its impossible. Cant find a suitable example from the API http://apidock.com/rails/ActionView/Helpers/FormTagHelper/select_tag
This didnt work:
<%= select_tag "invoice_product_code",
#invoice_product_array.each_with_index.map {
|jsondata, index|
[jsondata["invoice_product_code"],
index]}
%>
And this didnt work:
Its in correct because value and display text is a json string instead of a particular key value from the array item.
<%= select_tag "invoice_product_code",
options_for_select(#invoice_product_array)
%>
options_for_select takes an extra argument to specify the selected value and each option can have HTML attributes as the last element.
<%= select_tag "invoice_product_code", options_for_select(
#invoice_product_array.each_with_index.map {
|jsondata, index|
[jsondata["invoice_product_code"],
index,
style: 'width: 110px;']},
item["invoice_product_code"])
%>
I am using Perl (and Dancer) with HTML to create a form. On my form I have some fields like so:
<input type="text" name="keywords" id="keywords" value="<% keywords | html %>"/>
<select multiple="multiple" id="sentences" name="sentences" size="3"/>
<% IF list_of_sentences %>
<% FOREACH sentence IN list_of_sentences %>
<option value=<% sentence %>/>
<% END %>
<% END %>
</select>
These are, of course, inside their own divisions and there is more code around, but these are the essentials of what I've got.
These are in main.tt which is interacted with using myApp.pm and there are parameters which are passed back and forth (e.g. keywords and list_of_sentences here). The code is set up with two divs, one with the form and the other purely to show the output. When the form is submitted the output shows correctly, but the select field selections are not retained.
So therefore, what I want to do is make it so that the chosen selection(s) from the 'multiple select' are kept selected.
As an example, in my 'input' keywords field I have the value retained because it has been passed back from the .pm file using param("keywords") using template 'main' .... This works with value="<% keywords | html %>" in the html code.
I have tried to do the same for the multiple select using param("sentences"), but this returns a blank field.
To hazard a guess at the problem it is because there is more than one option and maybe because I am getting the options from the .pm file to start with, but I haven't found the solution yet, so any help would be welcome.
You want to use the selected="selected" attribute on the option element. I would suggest passing both the name of the sentence and flag stating if the option should be in the selected state. For example:
<% IF list_of_sentences %>
<% FOREACH sentence IN list_of_sentences %>
<option value="<% sentence.value %>"<% IF sentence.is_selected %> selected="selected"<% END %> />
<% END %>
<% END %>
And use the following data structure for your sentences:
{ value => $value, is_selected => 0|1 }
When writing an HTML file, why use <%= INSERT RAILS HERE %> vs. <% INSERT RAILS HERE %>
<%= %> emits a string, <% %> runs code.
On the pedantic side, you're writing an ERb template, not an HTML file--the syntax is the same whether it's a template for HTML, JS, or whatever.
The ERB docs provide additional (but not complete) information.
<%= %> will return value and display in your page. Assume that you have person.name = 'Dark'
<%= person.name %>
will display Dark in your web page.
<% %> will not return any value to your page. It just embed simple ruby code. Usually used with `control statement'.
<% if person.present? %>
<span><%= person.name %></span>
<% end %>
When we use <%= %> it simply displays the value returned, on the html page.
<% %> executed the code but doesn't dispaly it on the html page.
I don't get the point how can I do that code with an select helper?
<select name="cube_name">
<% #cube_names.each do |cube| %>
<option value="<%= cube %>" <% if #cube_name == cube %> selected="selected"<% end %>><%= cube %></option>
<% end %>
</select>
I have a list (#cube_names) and want a HTML select box width all values of the list and the default value (param #cube_name) should be selected.
thanks.
The select_tag helper will not auto-set the selected attribute on an item you pass. It just builds the tag. Use something like:
<%= select_tag("id_of_my_tag", #cube_names.map { |cn| "<option#{cn == cube ? " selected='selected'" : ""}>#{cn}</option>" }.join("")) %>
The first parameter is the id of the select tag, the second is a list of options (here built by mapping the cube names to strings, then joining the array into a single string).
You could alternatively use the options_for_select to build the string:
<%= select_tag("id_of_my_tag", options_for_select(#cube_names, cube)) %>