views:

427

answers:

2

Update:

If you look at the javascript code that I pasted in the update below, I have single quotes around the variety.name variable. I think I was just following a tutorial in doing that. Turns out that when I switch those to double quotes, everything works fine. Question: Is this a stable solution? Or would it still be better to implement the escape_javascript helper?

I have a Rails app where users can input values for a field. Other users can then add that value to their profile by selecting it from a dropdown. I'm using the collection_select helper to render the dropdown. I have a bit of javascript tied to this dropdown that recognizes a parent selection and then displays a certain child selection.

The problem is that some users are entering values that include an apostrophe. Firebug is telling me that the apostrophe is breaking the javascript. When I manually remove all apostrophes for testing, the javascript functions perfectly.

Earlier today, I asked a question about escaping ampersands in rendered html text, and I know now that you use <%=h %>. From what I've read on the web, <%=h %> does not escape an apostrophe. If I'm wrong and <%=h %> does escape apostrophes, then I'm not sure how to implement it with a collection_select because I've tried a number of combinations and none of them work.

Here's the line of code creating the dropdown:

<%= season_form.collection_select :variety_id, Variety.find(:all), :id, :name, :prompt => "Optional: Variety" %>

Thanks!

UPDATE

Here's my javascript. I have a hierarchy of goods. By way of explanation: this javascript lets my user select a product from a dropdown, and then automatically limits the second dropdown to only those varieties that belong to whatever product the user selected. It works great, so long as there are no apostrophes in the names of the varieties.

Also, I tried adding escape_javascript in front of almost all the elements, but none of them solved the problem. The Rails documentation is non-existent on this helper, so there's not much to go on in terms of examples. Thanks for your help!

var varieties = new Array();
<% for variety in @varieties -%>
  varieties.push(new Array(<%= variety.product_id %>, '<%=h variety.name %>', <%= variety.id %>));
<% end -%>

function collectionSelected(e) {
  product_id = e.getValue();
  options = e.next(1).options;
  options.length = 1;
  varieties.each(function(variety) {
    if (variety[0] == product_id) {
      options[options.length] = new Option(variety[1], variety[2]);
    }
  }); 
}
A: 

Edit:

I just realised that you should not be escaping in your server side code. You should be escaping in the javascript code. For the javascript escape function please see here: http://www.w3schools.com/jsref/jsref_escape.asp

You should use escape_javascript() found in the api here: http://api.rubyonrails.org/classes/ActionView/Helpers/JavaScriptHelper.html#M001758

Robert Massaioli
A: 

You can use gsub and replace what you want.

I normally use the select helper and just pass this in. I don't think collection_select uses this.

Variety.all.collect{|v| [v.id, v.name.gsub("'", "\'")]}

For collection_select, you can 'fix' the records before you use them.

varieties = Variety.all.map{|v| v.name.gsub("'", "\'")}
collection_select(:variety_id, varieties, :id, :name, :prompt => "Optional: Variety")
Jim