How to show a div in JS underscore template - javascript

I am using $.getJSON in a jquery script to get data from a php file and display it in a template(underscore).
My template:
<script type="text/template" id="user-template">
<% _.each(users, function(user){%>
<div class="id"><%=user.id%> </div>
<div class="name"><%= user.name %></div>
<div class="city"><%= user.city %></div><br />
<% }); %>
</script>
My script:
$.getJSON(url, function(data){
var results = userTemplate({ users: data.users}),
$("#theresults").html(results);}
On each page im listing 10 users (or 10 results). The code works fine. I want to be able to show another div after every 4 results. Like an ad or a promotional content.
<div id="mycustomdiv">Custom DIV</div>
How do i do that?
Thanks.

Just use the second argument of the callback function to determine the current index
<% _.each(users, function(user, index){%>
<div class="id"><%=user.id%> </div>
<div class="name"><%= user.name %></div>
<div class="city"><%= user.city %></div><br />
<% if(index !== 0 && (index % 4) === 0) { %>
<div id="mycustomdiv">Custom DIV</div>
<% } %>
<% }); %>

Related

How to use a passed variable in an ejs file

SO i am trying to change the value of an html tag in an ejs file to a variable i declared in a JavaScript file
let checkbox = document.querySelector('input[name="plan"]');
checkbox.addEventListener('change', function () {
if (this.checked) {
document.querySelector('.plan-title').innerHTML = investment.name;
document.querySelector('.plan-description').innerHTML = investment.description;
}
else {
document.querySelector('.plan-title').innerHTML = '';
document.querySelector('.plan-description').innerHTML = '';
}
});
So when I pass it directly it shows but I want it to be dynamic and Although it gets pass through when i click the checkbox it doesn't seem to have any value.
<%- include('../partials/sidebar'); %>
<% if(currentUser && currentUser.isAdmin){ %>
Add New Plan
<% } %>
<div class="container">
<h1>Investments</h1>
<% investments.forEach((investment)=>{ %>
<div class="col-md-4">
<div class="card">
<strong>
<%= investment.name %>
</strong>
<h4>
<%= investment.min %> - <%=investment.max %>
</h4>
<p>
<%= investment.caption %>
</p>
<p><input type="checkbox" name="plan" id="">Choose investment</p>
</div>
<% if(currentUser && currentUser.isAdmin){ %>
Edit
Delete
<% } %>
</div>
<% }) %>
<% investments.forEach((investment)=>{ %>
<div class="">
<div><strong>Package: </strong>
<p class="plan-title">
</p>
</div>
<p class="plan-description">
</p>
<input type="number" name="" id="" min="<%= investment.min %>"
max="<%= investment.max %>">
</div>
<% }) %>
</div>
<%- include('../partials/footer'); %>
I cant seem to get through this, need help thanks!
If I got it right, you are trying to insert the value of the EJS variable in the HTML tag from JavaScript when the user clicks the checkbox.
The value of the HTML tag doesn't change because in your JS code:
document.querySelector('.plan-title').innerHTML = investment.name;
document.querySelector('.plan-description').innerHTML = investment.description;
investment.name and investment.description are undefined. Check the console on your page.
This is because you tried accessing EJS variables after the page finished rendering.
EJS is mainly used to pass server-side variables to the page before it is rendered. So once it's rendered you cannot access those variables.
So to have the values of those variables in your JavaScript after the page finishes rendering, try doing:
document.querySelector('.plan-title').innerHTML = '<%- investment.name %>';
document.querySelector('.plan-description').innerHTML = '<%- investment.description %>';
instead. This is how you pass the EJS variable to JavaScript. JavaScript now sees it as a string and there's no problem, unlike in your code where it was looking for investment object and returned undefined since that variable is not defined on the client-side.
Also, since you have a for-each loop in the HTML part, I'm assuming you are trying to change the values of specific plan-title and plan-description divs. If that's the case, '<%= investment.name %>' and '<%= investment.description %>' in JavaScript part should be in a for-each loop as well, but that would be a lot of mess.
I suggest you instead to right under the for-each loop in the HTML part, add class to the div tag according to the index of the for-each loop, add on change event to the checkbox, and pass the checkbox and the index of the for-each loop to the JavaScript function which would handle the on change event, include the EJS variables in the plan-title and plan-description divs, and in the JavaScript function that handles on change event change the CSS display property from display: none to display: block to these divs.
See an example:
HTML:
<% investments.forEach((investment, index)=>{ %>
<div class="col-md-4">
<div class="card">
<strong>
<%= investment.name %>
</strong>
<h4>
<%= investment.min %> - <%=investment.max %>
</h4>
<p>
<%= investment.caption %>
</p>
<p><input onchange="displayPlan(this, '<%= index %>')" type="checkbox" name="plan" id="">Choose investment</p>
</div>
<% if(currentUser && currentUser.isAdmin){ %>
Edit
Delete
<% } %>
</div>
<% }) %>
<% investments.forEach((investment, index)=>{ %>
<div class="plan <%= index %>" style="display: none;">
<div><strong>Package: </strong>
<p class="plan-title">
<%- investment.name %>
</p>
</div>
<p class="plan-description">
<%- investment.description %>
</p>
<input type="number" name="" id="" min="<%= investment.min %>"
max="<%= investment.max %>">
</div>
<% }) %>
JavaScript:
function displayPlan(checkbox, id){
if (checkbox.checked) {
document.querySelector(`.plan.${id}`).style.display = 'block';
}
else {
document.querySelector(`.plan.${id}`).style.display = 'none';
}
}
Cheers!
EDIT: Grammar and syntax issues
It's not clear to me what variable you're referring to, but any variable you set in a client-side script will not be available to you in an EJS file that you're rendering on the server. Server-side Node.js code and client-side JavaScript code have no knowledge of each other.

Why this is saying me 'Could not find matching close tag for "<%" '?

I have the following code.
<body>
<div class="container">
<div class="row">
<% for(let i=0;i<seats.length;i++) { %>
<div class="col-lg-6">
<h3> <%= seats[i].name %> </h3>
<% if(<%= seats[i].isBook %> == false) { %>
<% document.querySelector("h3").disabled = true; %>
<% } %>
</div>
<% } %>
</div>
</div>
I get the following error:
Error: Could not find matching close tag for "<%".
at d:\seat booking\node_modules\ejs\lib\ejs.js:710:19
at Array.forEach()
...
The Problem is your if sentence. You are opening the tag <% and before closing it you are opening another one, which doesn't work and is not needed.
You can try the following:
<div class="container">
<div class="row">
<% for(let i=0;i<seats.length;i++) { %>
<div class="col-lg-6">
<h3> <%= seats[i].name %> </h3>
<% if(seats[i].isBook == false) {
document.querySelector("h3").disabled = true;
} %>
</div>
<% } %>
</div>
</div>
As you can see, I did not just remove the tags within the if(..). The other tags I removed are also unnecessary, because you don't have any HTML code in between your if sentence.

Load data after Ajax request in a template

I render a page with the data that ejs puts together. when the user presses a submit button a section (thirdRow)of the page should be refreshed with the new data that was submitted plus the old data. I got the new data in the db, I want to refresh the thirdRow that shows all the reviews.
basically my problem is the success method in the $.ajax . I could get all the data there but it seems weird to write everything over in html strings. There should be a better way.
I saw a method where I could put the .thirdRow into a template and include that into the main EJS page and also put that into my static public folder and do something like new EJS({url : 'public/thirdRow.ejs' }).update('.thirdRow', data); in this case is the data in the last code snippet the returned data from the success callback in the AJAX? How Do I get Access to the EJS There are alot of links for ejs can you show my how to include the EJS
I don't know if this is the correct method. How would you do it? I have a page that is basically made up of all the returned data and I want to click a button and have only one section have the new data.
One section inside main.ejs
<div class="thirdRow">
<div class="reviewSection">
<% if(reviews){%>
<% reviews.forEach(function(e, i){%>
<div class="indivReview">
<div class = "userRow row">
<div>
<span>user </span>
<% if( e.username) {%>
<span><%= e.username %></span>
<%}else{ %>
<span><%=e.user%></span>
<% }%>
</div>
<div><%= e.momented %></div>
</div><!--userRow-->
<div class = "companyRow row">
<div>
<span>Experince for</span>
<span><%=e.companyName%></span>
</div>
<div>
<span> industry</span>
<span>online retail</span>
</div>
</div> <!--companyRow -->
<div class="voteRow row">
<div>
Vote
</div>
<div><%= e.vote%></div>
</div>
<div class="reviewRow row">
<div>Review</div>
<div class = "displayReview">
<% e.reviewText.split("\n").forEach(function(e){ %>
<%= e %><br>
<%})%>
</div>
</div>
<div class="statementRow ">
// make a div for each object
<% e.statements.forEach(function(obj){%>
<div class="indivStatement">
<% var arr = []%>
<%for(var prop in obj) {%>
<% if(prop !== "name"){ %>
<% if(prop == "question"){%>
<% arr[0] = obj[prop] %>
<%} %>
<% if (prop == "result"){%>
<% arr[1] = obj[prop] %>
<%}%>
<% console.log(arr) %>
<%} %>
<%}%>
<div class = "question"><%= arr[0]%></div>
<div class = "bar" data-result ="<%= arr[1]%>"><%= arr[1]%></div>
</div>
<%})%>
</div>
<div> <span></span>
<span><%=e.companyName%></span></div>
<div><%= e.momented %></div>
</div>
<%})%>
<%}%>
</div> <!--reviewSection-->
</div> <!--thirdRow-->
inside client script
$(".submitButton").on("click",function(){
console.log(datum)
var empty;
if(datum.reviewText == "" && Object.keys(datum.statements) == 0 && datum.vote == null){
empty = true;
}else{
empty = false;
}
console.log("empty : " , empty)
scrollFunction(".thirdRow", ".submitButton, .shareButtonSection")
var data = datum;
if(!empty){
$.ajax({
type : "POST",
data : JSON.stringify(data),
contentType : "application/json",
url : "http://localhost:4000/submitreview",
success : function(data){
console.log("success")
$(".thirdRow").fadeOut(800, function(){
console.log("this", $(this))
$(this).html(data).fadeIn().delay(200)
})
console.log(data)
}
})
}
})
I never used EJS on the client side. Allways used with express
Here's an example of using EJS client side
https://github.com/tj/ejs/blob/master/examples/client.html

How to get an index number in Hexo article loop "for each"?

In Hexo.js, when you want to output some articles, you loop using .sort, .limit and .each, for example:
<% site.posts.sort('date', 'desc').limit(8).each(function(post){ %>
<div id="post-1" class="post">
<%= post.title %>
all the other post tags and content
</div>
<% }) %>
How do you set the id number post-X to be dynamically incremented, for example first post would get id="post-1", second id="post-2" and so on?
Try this:
<% site.posts.sort('date', 'desc').limit(8).each(function(post, i){ %>
<div id="post-<%=i+1%>" class="post">
<%= post.title %>
all the other post tags and content
</div>
<% }) %>
As you can see, there is an additional parameter, i, which means index.

.load() Jquery function load duplicate window in the same time

I have the Jquery code below:
$(document).ready(function() {
$('tr[href]').click(function(event) {
$('tr[href]').removeClass('selected')
$(this).addClass('selected');
event.preventDefault();
$('#profile').load('home/users/1');
event.stopPropagation();
});
});
Every time I click the target, I found the .load function load the window double times the last click. For example, in the rails log it shows several Started GET "/home/users/1in the same time thus my app becomes slow and slow. Below is the view file where the window is loaded:
<div class="col-md-5" >
<div class="table table-responsive" >
<div id='list' >
<% if params[:q] == 'a' %>
<%= render 'users' %>
<% elsif params[:q] == 'b' %>
<%= render 'jobs_index' %>
<% else %>
<%= render 'lineitems' %>
<% end %>
</div>
</div>
</div>
<div class="col-md-5">
<div id="profile">//load the window
</div>
Could any body tell me why this occurs? Very thanks!
I solved it.
I modified the code $('#profile').load('home/users/1'); in application.js as below:
var url="home/users/"+$(this).attr("href")
$('#profile-outline').load(url+" #special");
And add a in the outermost of the html file.Then the problem is solved.
In summary, just use load("url #container") to replace load("url").

Categories

Resources