Javascript: Unrecognized expression due to rails code in class name? - javascript

$(".collapse.summary_row_<%= pin %>").each(function() {
var thisId = $(this).find('#pin').text();
var sumVal = parseFloat($(this).find('#price').text());
var $rowsToGroup = $(this).nextAll('tr').filter(function() {
return $(this).find('#pin').text() === thisId;
});
$rowsToGroup.each(function() {
sumVal += parseFloat($(this).find('#price').text());
$(this).remove();
});
$(this).find('#price').text(sumVal);
});
<tr class="clickable" data-toggle="collapse" id="summary_row_<%=pin%>" data-
target=".summary_row_<%= pin %>">
<td><i class="glyphicon glyphicon-plus"></i></td>
<td> <%= pin%> </td>
<td align="right"> <strong> <%= number_to_currency(amount, unit: "",
precision: 2) if amount %> </strong> </td>
</tr>
<tr id="child_row_<%=pin%>" class="collapse summary_row_<%= pin %>"
align="right" >
<td class="child_data_<%=pin%>"><strong>Year</strong></td>
<td><strong>Quarter</strong></td>
<td><strong>Amount</strong></td>
</tr>
<% if detail %>
<% detail.each do |key, value| %>
<tr id="child_row_<%=pin%>" class="collapse summary_row_<%= pin %>"
bgcolor="#fba993" align="right" >
<td class="child_data_<%=pin%>" id="pin"><%= value[0]%></td>
<td id="quart"><%= value[1]%></td>
<td id="price"><%= number_to_currency(value[2], unit: "", precision: 2) %>
</td>
</tr>
<% end %>
The code above is the Javascript code and the code below is the html/ruby code. I'm trying to make it so that when the .clickable tr class gets clicked, the function will do it's work, but it doesn't and I get this message instead:
Uncaught Error: Syntax error, unrecognized expression: .collapse.summary_row_<%= pin %>
I've noticed that the other functions in my JS files worked, but they do not have the ruby syntax inside their class names so I'm assuming that the ruby code has something to do with this error.

You're writing Rails Code inside JavaScript file, it will not work there, you have to write your rails code inside html.erb file or you can call that function inside <script> tag from html.erb file or you can use dynamic data attributes inside your html tags

If you want to use Ruby variable in your Javascript you should add erb extension to your JS file: my_file.js.erb.
Other option is to use directly my_file.coffee. Here you can change adapt your JS file JsToCoffee
Hope it helps,

Related

Using ejs input for js if statement

I have a code problem I need to do for a class. I have a database that has users, another table has the titles which the user has access to. I'm trying to make a page where they can edit a user and when they click the button the form fills automatically with the id, first name and last name fine.
Now I'm trying to show what access the user selected has access to at the moment. And what I thought would just be a simple if statement has turned into a headache, it seems I can't access the id variable inside the html code that I want to insert and when I try to put the if statement outside, it says errors with the http headers, like it is sending too many renders. How can I accomplish this?
So here the code works but it loads the tabs of all of the users but I would like to filter the results based on the id.
<tbody>
<% all_users_to_modify.forEach(function(row){ %>
<tr>
<td>
<button class="btn btn-primary m-b-0"
onClick="fillForm('<%= row.id %>','<%= row.f_name %>','<%= row.l_name %>');";
onclick="moneyCalc('<%= row.id %>')" >
<%= row.id %>
</button>
</td>
<td><%= row.f_name %></td>
<td><%= row.l_name %></td>
<td><%= row.email %></td>
<td><%= row.phone_number %></td>
</tr>
<% }); %>
</tbody>
<table class="table table-striped table-bordered nowrap">
<thead>
<tr>
<th>Acceso</th>
</tr>
</thead>
<tbody id="lastResult">
</tbody>
</table>
function moneyCalc(id) {
'use strict';
var id = document.getElementById('id').value;
if (id) {
var html_to_insert = `
<% list_of_all_users_tabs.forEach(function(row1){ %>
<tr>
<td><%= row1.tab_name %> </td>
</tr>
<% }); %>
`;
lastResult.innerHTML += html_to_insert;
}
}
Now this is what I would like to do, in each row of the list_of_all_users_tabs it has a column that is the user_id and the other column is tab_name. So I have had two ideas but neither seem to work.
First idea was to put a while loop to compare the user_id in the db and the input id however I get: Error [ERR_HTTP_HEADERS_SENT]:
function moneyCalc(id) {
'use strict';
var id = document.getElementById('id').value;
if (id) {
while(list_of_all_users_tabs.user_id == id) {
var html_to_insert = `
<% list_of_all_users_tabs.forEach(function(row1){ %>
<tr>
<td><%= row1.tab_name %> </td>
</tr>
<% }); %>
`;
lastResult.innerHTML += html_to_insert;
}
}
}
Second idea had an if statement in the html code however it says id not defined:
function moneyCalc(id) {
'use strict';
var id = document.getElementById('id').value;
if (id) {
var html_to_insert = `
<% list_of_all_users_tabs.forEach(function(row1){ %>
<% if(row1.id == id) { %>
<tr>
<td><%= row1.tab_name %> </td>
</tr>
<% } %>
<% }); %>
`;
lastResult.innerHTML += html_to_insert;
}
}
Wrap your javascript code into <script> tag.
<script>
//Your code goes here
</script>
You need to set you header status to 200 in your route file.
res.json({
success: 'updated',
status: 200
})
And write you JS code inside <script> </script> tags only.

How to display parsed data from ajax in express.js

I have this page made using node.js + express where I am displaying the following table :
I wish to reload only the table with new data using ajax when limit is changed using the dropdown (one with the label show result), but am having trouble doing so.
Here's the ejs code that displays my table :
<table class="assignment-table table table-striped table-bordered table-hover table-condensed table-responsive">
<thead>
<tr>
<th>S.No.</th>
<th>Name</th>
<th>Subject</th>
<th>Topic</th>
<th>Faculty</th>
<th>Posted</th>
<th>Last Date</th>
<th>Mode of Submission</th>
</tr>
</thead>
<tbody class="table_body">
<% for(var i =0;i< result.length;i++) { %>
<tr>
<td class="result_id">
<a target="_blank" href="/assignment/abc.pdf" class="download-link" id="">
<%= result[i]._id %>
</a>
</td>
<td class="result_name">
<a target="_blank" href="/assignment/abc.pdf" class="download-link">
<%= result[i].nameAssignment %>
</a>
</td>
<td class="result_subject">
<a target="_blank" href="/assignment/abc.pdf" class="download-link">
<%= result[i].Subject %>
</a>
</td>
<td class="result_topic">
<a target="_blank" href="/assignment/abc.pdf" class="download-link">
<%= result[i].Topic %>
</a>
</td>
<td class="result_faculty">
<a target="_blank" href="/assignment/abc.pdf" class="download-link">
<%= result[i].Faculty %></a>
</td>
<td class="result_posted">
<a target="_blank" href="/assignment/abc.pdf" class="download-link">
<%= result[i].Posted %></a>
</td>
<td class="result_lastdate">
<a target="_blank" href="/assignment/abc.pdf" class="download-link">
<%= result[i].LastDate %></a>
</td>
<td class="result_submission">
<a target="_blank" href="/assignment/abc.pdf" class="download-link">
<%= result[i].Submission %></a>
</td>
</tr>
<% } %>
</tbody>
</table>
In the filter_result() route mentioned above, I am fetching limit from the url and querying the database with new limits and rendering the page again.
Router.get('/filter_result',(req,res) => {
limit = parseInt( decodeURIComponent(req.query.limit) );
models.filterResults(limit, (count,result) => {
//if (err) throw err;
console.log(limit);
//res.send(result);
res.render('assignment-list',{limit:limit,result:result,count : count});
});
});
How can I redisplay the table in the ejs page?
Basically your .ejs format is rendered only once when you load or reload the page. So what you do is re-render (or, replace) the HTML from your AJAX call on top of already-rendered HTML.
It seems that you're using jQuery already so my example code uses jQuery too.
Re-rendering (or, again, replacing) HTML depends on what your /filter_result responds. If it's just bunch of <tr>s then it might be
JS
$('table.assignment-table').find('tbody').html(result);
If it's the entire <table> then you'd better wrap <table> with some wrapper like <div> and do the following.
HTML
<div id="table-wrapper">
<table>
...
</table>
</div>
JS
$('div#table-wrapper').html(result);
How you refer your wrapper and replace the content can vary.
Update 1
Assuming your API (/filter_result) returns an array of assignment objects like
{
"status": "success",
"data": [
{
"Subject": "Your subject",
"Topic": "Your topic",
...
},
...
]
}
you can create bunch of <tr/>s from data and replace the existing <tr/>s with them like (with jQuery of course. About creating DOM with jQuery, you can refer the docs.)
$.ajax({
method: 'GET',
url: 'URL_TO_FILTER_RESULT',
data: SOME_DATA,
success: function(res) {
var assignments = res.data;
var body = [];
assignments.forEach(function(assignment) {
var tr = $('<tr/>');
tr.append($('<td/>').html('' + assignment.Subject + '');
tr.append($('<td/>').html('' + assignment.Topic + '');
...
body.push(tr);
});
$('table.assignment-table').find('tbody').html(body);
}
})

How to call js for appropriate element

Can't how to deal with my problem: part of view are hidden, when page is loaded.
Here is this part:
<table>
<% #websites.each do |website| %>
<%if (current_user.id == website.user_id)%>
<tr>
<td> <%= link_to(image_tag("/images/caret-horizontal.png", id: "caret-horizontal"), '#') %> </td>
<td> <h4><%= website.name %></h4> </td>
</tr>
</table>
<table id="<%= website.id %>"> // or can be like this:
//I don't what variant is better
<table id="table-data" data-id="<%= website.id %>">>
<tr >
<td >
<%= website.url %>
</td>
</tr>
<tr>
<td >
<%= website.category %>
</td>
</tr>
<tr>
<td><%= website.language %></td>
</tr>
</table>
And I can get attributes in JavaScript like this(thanks to good people):
var yourWebsiteId = $("#table-data").attr("data-id");
How I can choose approriate element and show it? I should use getElementById or something like this, but I don't know exactly how to do it.
Please help me, if you can.
$("#table-data").show()
You can find information on this from here
$("#table-data") gets a reference to the part of the dom you are trying to access (# denotes id, . denotes class), once you have a reference you can then call any jquery operation you want on it

error with document.getElementById()

I am trying to write a jdo query in which I have to get a set of values based on the category that the user selects on the jsp...my query looks like this
Query query2 = pm.newQuery("select from " + ProductDB.class.getName()+ "where pCategory = " document.getElementById("cname").text);
Now on my jsp page, I have a dynamic drop-down box and in the tag I have given the id tag as "cname". So when I execute the above query I am hoping it will get the category that the user selects.
However I am getting this error:
Syntax error on token "document", delete this token
My select tag looks like this :
<select name = "cname" id="cname">
.
.
.
</select>
What am i missing here?
UPDATE :
I am putting my entire code for the jsp file below :
<%# page contentType="text/html;charset=UTF-8" language="java"%>
<%# page import="java.util.*"%>
<%# page import="javax.jdo.Query"%>
<%# page import="javax.jdo.PersistenceManager"%>
<%# page import="com.google.appengine.api.users.User"%>
<%# page import="com.google.appengine.api.datastore.Key"%>
<%# page import="com.google.appengine.api.users.UserService"%>
<%# page import="com.google.appengine.api.users.UserServiceFactory"%>
<%# page import="java.net.*"%>
<%# page import="javax.servlet.http.HttpServletRequest"%>
<%# page import="com.nerdy.needs.*"%>
<html>
<head>
<title>Product Inventory</title>
<META HTTP-EQUIV="Refresh" CONTENT="450">
<link rel="stylesheet" href="login.css" type="text/css" />
</head>
<h1 align="center">Product Inventory</h1>
<body>
<form>
<table>
<tr>
<td>View</td>
<td><select name="cname" id="cname">
<option value="all">All</option>
<%
PersistenceManager pm = PMF.get().getPersistenceManager();
Query query = pm.newQuery("select cname from "
+ CategoryDB.class.getName());
List<String> categories = new ArrayList<String>();
categories = (List<String>) query.execute();
String[] c = categories.toArray(new String[categories.size()]);
for (int i = 0; i < c.length; i++) {
String s = c[i];
%>
<option value="<%=s%>"><%=s%></option>
<%
}
%>
</select></td>
<td>Products</td>
</tr>
</table>
</form>
<%
if (document.getElementById("cname").value == "all") {
PersistenceManager pm1 = PMF.get().getPersistenceManager();
Query query1 = pm1.newQuery("select * from "
+ ProductDB.class.getName());
List<ProductDB> prods1 = (List<ProductDB>) query1.execute();
if (prods1.isEmpty()) {
%>
<table class="items">
<tr>
<th class="main">Image</th>
<th class="main">Category</th>
<th class="main">Name</th>
<th class="main">Price</th>
<th class="main">Description</th>
</tr>
<tr class="lightBlue">
<td class="actions" colspan=100%>
<p>No items were found.</p>
</td>
</tr>
</table>
<%
} else {
%>
<table class="topics">
<tr>
<th class="main">Image</th>
<th class="main">Category</th>
<th class="main">Name</th>
<th class="main">Price</th>
<th class="main">Description</th>
</tr>
<%
for (ProductDB p : prods1) {
%>
<tr>
<td>
<p><b> <img width="100" height="100"
src="http://localhost:8888/serve?id= <%=p.getProductImage()%>">
</b></p>
</td>
<td>
<p><b><%=p.getProductCategory()%></b></p>
</td>
<td>
<p><b><%=p.getProductName()%></b></p>
</td>
<td>
<p><b><%=p.getProductPrice()%></b></p>
</td>
<td>
<p><b><%=p.getProductDescription()%></b></p>
</td>
</tr>
<%
}
%>
</table>
<%
pm1.close();
}
} else {
PersistenceManager pm2 = PMF.get().getPersistenceManager();
Query query2 = pm.newQuery("select * from "
+ ProductDB.class.getName() + "where pCategory = "
+ document.getElementById("cname").value);
List<ProductDB> prods2 = (List<ProductDB>) query2.execute();
if (prods2.isEmpty()) {
%>
<table class="items">
<tr>
<th class="main">Image</th>
<th class="main">Category</th>
<th class="main">Name</th>
<th class="main">Price</th>
<th class="main">Description</th>
</tr>
<tr class="lightBlue">
<td class="actions" colspan=100%>
<p>No items were found.</p>
</td>
</tr>
</table>
<%
} else {
%>
<table class="topics">
<tr>
<th class="main">Image</th>
<th class="main">Category</th>
<th class="main">Name</th>
<th class="main">Price</th>
<th class="main">Description</th>
</tr>
<%
for (ProductDB p : prods2) {
%>
<tr>
<td>
<p><b> <img width="100" height="100"
src="http://localhost:8888/serve?id= %=p.getProductImage()%>">
</b></p>
</td>
<td>
<p><b><%=p.getProductCategory()%></b></p>
</td>
<td>
<p><b><%=p.getProductName()%></b></p>
</td>
<td>
<p><b><%=p.getProductPrice()%></b></p>
</td>
<td>
<p><b><%=p.getProductDescription()%></b></p>
</td>
</tr>
<%
}
%>
</table>
<%
pm2.close();
}
}
%>
</body>
</html>
I am getting "document cannot be resolved" errors in two places - one at the if statement
if(document.getElementById("cname").value=="all")
and the other at the query statement
Query query2 = pm.newQuery("select * from " + ProductDB.class.getName()+ "where pCategory = " + document.getElementById("cname").value);
Can anyone help me to figure out what is wrong?
Your concrete problem is that you're mixing Java/JSP with JavaScript. You seem to expect that they run in sync and you seem to expect that JavaScript's document object variable is also present in JSP scriptlet code.
This is wrong. Java/JSP is a HTML code generator. It runs in webserver upon a HTTP request and generates HTML/JS code and sends it back to webbrowser as HTTP response. All the webbrowser retrieves is plain HTML/JS code. Rightclick the page in webbrowser and do View Source to see it yourself.
Your concrete functional requirement seems to be that you need to grab the the submitted value of
<select name="cname">
in the Java/JSP side.
You need to get it as a request parameter by HttpServletRequest#getParameter(). So, replace
<%
if (document.getElementById("cname").value == "all") {
// ...
}
%>
by
<%
if ("all".equals(request.getParameter("cname"))) {
// ...
}
%>
That said, writing Java code in JSP files is a poor practice. Work on that as well. Note that this problem is unrelated to JDO.
You forgot the plus mark before the document.getElementById.
The correct code would be
Query query2 = pm.newQuery("select from " + ProductDB.class.getName() + "where pCategory = " + document.getElementById("cname").text);
Also, although that will fix the syntax error, the code still won't work. According to W3C DOM specification, the <select/> element doesn't have the text attribute; you should use the value, or selectedIndex in conjunction with options instead.
Try this way:-
var i = document.getElementById("cname").selectedIndex;
document.getElementById("cname").options[i].text;
OR
document.getElementById("cname").value
UPDATE:
Column names are missing too. It should be either * or specific column names.
Query query2 = pm.newQuery("select * from " + ProductDB.class.getName()+ "where pCategory = " + document.getElementById("cname").value);
As per your error update
your code should be as follows:-
if(document.getElementById("cname").value=="all")
{
<%
PersistenceManager pm1 = PMF.get().getPersistenceManager();
Query query1 = pm1.newQuery("select * from " + ProductDB.class.getName());
List<ProductDB> prods1 = (List<ProductDB>) query1.execute();
%>
}
JSP tags should be declared between tags <% and %> and other html tags should be outside.
As per your Code:
The problem is document.getElementById("cname").value calling inside the JSP tags. That is wrong.
Here either you can pass cname value as query string and get value through the parameter
OR
Assign document.getElementById("cname").value value to JSP variable and process it.

Passing string to popup

I'm working with a JSP page and it's displaying a table of a storage objects that was fetched. I want to have a popup to another JSP page when the user clicks on the number that is showing the size of the storage object.
How do I pass the name of the specified storage item to the popup JSP window with Javascript (or any other technique), and then retrieve that name in the popup JSP and be able to use it in that page's code?
The scriptlet for-loop looks like this:
<% for(Storage s : someList){ %>
<tr>
<td> <%= s.getName() %> </td> <td> <%= s.getSize() %> </td>
</tr>
<% } %>
Pass it as request parameter.
E.g.
<td onclick="window.open('popup.jsp?name=<%= URLEncoder.encode(s.getName(), "UTF-8") %>', 'windowname')">
with in popup.jsp:
<%= request.getParameter("name") %>
Or, more cleanly, with JSTL and EL:
<c:forEach items="${someList}" var="s">
<c:url value="popup.jsp" var="popupUrl">
<c:param name="name" value="${s.name}" />
</c:url>
<tr>
<td>${s.name}</td><td onclick="window.open('${popupUrl}', 'windowname')">${s.size}</td>
</tr>
</c:forEach>
with in popup.jsp
${param.name}

Categories

Resources