javascript in my .html.erb using embedded ruby--escaping problems - javascript

I'm trying to embed data I have defined in my controller in my view.
in view.html.erb:
<script>
some_var = <%= #var_data %>
some_ints = <%= #int_data %>
</script>
in my controller:
#var_data = ['hi', 'bye']
#int_data = [1,2,3,4]
however, when I view the generated html file, it looks like
<script>
some_var = ["hi", "bye"]
some_ints = [1,2,3,4]
</script>
ie the ints are fine but all the quotes got escaped. I tried
some_var = <%= #var_data.map {|i| i.html_safe} %>
instead but it didn't do anything (and also html_safe didn't work on the whole array). How should I do this?
Thanks

have you tried this?
<%=raw #var_data %>

Related

How to store a mysql string in a javascript variable using jsp

I want to store mysql strings in a javascript array variable. I am using jsp for server-side.
I tried it in three ways. All the three aren't working. Need some help.
Attempt-1:
<script>
var name = [];
<%
st=con.prepareStatement("select name from company");
rs=st.executeQuery();
while(rs.next()){
String s = rs.getString(1);
%>
name.push(<%=s%>);
<%
}
%>
</script>
Attempt-2:
<script>
var name = [];
<%
st=con.prepareStatement("select name from company");
rs=st.executeQuery();
while(rs.next()){
%>
name.push(<%=rs.getString(1)%>);
<%
}
%>
</script>
Attempt-3:
<script>
var name = [];
<%
st=con.prepareStatement("select name from company");
rs=st.executeQuery();
while(rs.next()){
%>
name.push(<%out.print(rs.getString(1));%>);
<%
}
%>
</script>
All the three attempts showed the same result and error after processing.
Interpreted Code:
<script>
var name = [];
name.push(tcs);
name.push(wipro);
</script>
Error:
ReferenceError: tcs is not defined
You should add " around your string also you should javascript encode it(I think apache has a library that will do this for you):
<script>
var name = [];
<%
st=con.prepareStatement("select name from company");
rs=st.executeQuery();
while(rs.next()){
String s = StringEscapeUtils.escapeJavaScript(rs.getString(1));
%>
name.push("<%= s %>");
<%
}
%>
</script>
Try using this Apache library to escape the java string based on javascript rules: StringEscapeUtils
Javascript is trying to interpret name.push(tcs); tcs as a variable which in this case tcs has not been declared or initialized it is undefined. Instead you want javascript to interpret tcs as a string so you need quotes around it "tcs" or in your case "<%= s %>".

Javascript map from java map

I want to create a javascript map from a java map to set a dropdown value depending upon the value selected in another dropdown.
Below is the code(not working):
var categoryAndReportsMap = new Object();
<%
Map<String,Set<String>> categoryAndReportsJ = (Map<String,Set<String>>) request.getAttribute("categoryAndReports");
for(Map.Entry<String,Set<String>> e : categoryAndReportsJ.entrySet()){ %>
categoryAndReportsMap[ <% e.getKey(); %> ] = <% e.getValue(); %>;
<% } %>
Please suggest how can I achieve this.
You need quotes around the keys and values :
categoryAndReportsMap["<%= e.getKey() %>"] = "<%= e.getValue() %>";
But this supposes those strings don't contain quotes themselves. The best solution would be to use a JSON serializer like the excellent gson, this would be as simple as
var categoryAndReportsMap = <%= gson.toJson(categoryAndReportsJ) %>;

Loops in Mustache-Mode Underscore Templates

I've set underscore to mustache mode like so:
_.templateSettings = {
interpolate : /\{\{(.+?)\}\}/g
};
I've got part of a template with the following:
<script id="detail_view" type="text/template">
<% for(registration in REGISTRATION_NUMBERS){ %>
<tr>
<td>{{registration.TYPE}}</td>
<td>{{registration.VALUE}}</td>
</tr>
<% } %>
</script>
Which results in "registration not defined". Using this causes the entire section to be output in the template. What am i doing wrong?
You have two problems, one you know about and one that you don't.
The first problem is that you're replacing all three _.templateSettings when you only want to replace one of them. You want this:
_.templateSettings.interpolate = /\{\{(.+?)\}\}/g;
That will leave the evaluate and escape parts of _.templateSettings alone. What you're doing is the same as:
_.templateSettings = {
interpolate : /\{\{(.+?)\}\}/g,
evaluate : undefined,
escape : undefined
};
so you're ending up without an evaluate at all. BTW, you can look at the source property of a compiled template function to see the JavaScript that your template is compiled to, the JavaScript isn't that easy on the eyes but looking at it can help with this sort of problem.
The problem you don't know about is that a for...in loop is for iterating over the properties of an object, not the values in an array. This means that registration will be the strings '0', '1', ... inside your loop and that's not what you want. You'd need something like this in your template if REGISTRATION_NUMBERS is an array:
<% for(var i = 0; i < REGISTRATION_NUMBERS.length; ++i) { %>
<% var registration = REGISTRATION_NUMBERS[i]; %>
<tr>
<td>{{registration.TYPE}}</td>
<td>{{registration.VALUE}}</td>
</tr>
<% } %>
Or, since you have Underscore around anyway, you could use _.each:
<% _(REGISTRATION_NUMBERS).each(function(r) { %>
<tr>
<td>{{r.TYPE}}</td>
<td>{{r.VALUE}}</td>
</tr>
<% }) %>
Demo: http://jsfiddle.net/ambiguous/jfckA/

Rails + JS - Using instance variable (array of arrays with strings)

I have the following in a html.erb file:
<%= #location_list = [['test',2]] %>
<script type="text/javascript">
var test = <%= #location_list.to_json %>
alert(test);
</script>
And the alert is not showing up.
However if I do <%= #location_list = [[3,2]] %> - The alert is showing up.
Why?
<%= %> tag means output something. In your case, you probably dont want to output anything, so I guess you are looking for
<% #location_list = [['test',2]] %>, which means normal statement no output will be involved
Sorry, havn't really answer your question.
var test = <%= #location_list.to_json %>
should be
var test = "<%=j #location_list.to_json %>"

Using jQuery UI autocomplete plugin in Rails app

I'm interested in using the jQuery UI autocomplete plugin in my Rails app. The number of possible values will be small, so I wanted to store them client-side. So I have my controller set up as follows:
def index
#tags = Tag.find(:all).map { |t| t.name }
end
And in my view:
var tags = <%= #tags %>
The problem is that this renders as:
var tags = ["tag1","tag2"];
Instead of:
var tags = ["tag1","tag2"]
What do I need to do differently in order to stop escaping those quotes inside my tag array?
What about:
var tags = <%=raw #tags %>;
EDIT:
in your controller
#tags = Tag.find(:all).map(&:name).to_json
in your view:
var tags = <%= #tags %>;
It's the same as what you presented but you're sure it's valid and sure (because escaped) json (+ the query is improved).
I'm still questioning about the XSS + raw...
I was able to solve this by changing my view code to:
<%= array_or_string_for_javascript(#tags) %>
The thing missing in your controller is html_safe - here is an example:
controller
#keys = #categories.map { |x| x.name }
#autocomplete_categories = #keys.to_json.html_safe
view:
<script type="text/javascript">
$(document).ready(function() {
var data = <%= #autocomplete_categories %>;
$("#auto").autocomplete( { source: data } );
});
</script>

Categories