async for loop in express.js - javascript

I am trying to show all images with for loop. I have saved paths of images in Cubeimage array. And now I am trying to display them in <img>, but I get an error. How to write async code so it would work?
<div class="row">
<% for (var i = 0; i < Cubeimage.length; i++) { %>
<div class="column rounded border d-flex align-items-center">
<img class="demo cursor align-middle" src="<%= Cubeimage[i].image_path; =%>" style="width:100%;" onclick="currentSlide(1)" alt="The Woods">
</div><% } %>
Error:missing ) after argument list in /home/ubuntu/back_end/views/products_cube.ejs while compiling ejs If the above error is not helpful, you may want to try EJS-Lint: github.com/RyanZim/EJS-Lint Or, if you meant to create an async function, pass async: true as an option. SyntaxError: missing ) after argument list in /home/ubuntu/back_end/views/products_cube.ejs while compiling ejs

The solution found by the OP, and originally added to the answer:
<div class="row">
<% Cubeimage.forEach(function(cube){ %>
<div class="column rounded border d-flex align-items-center">
<img class="demo cursor align-middle" src="<%= cube.image_path; %>" style="width:100%;" onclick="currentSlide(1)" alt="Cube">
</div>
<% }); %>
</div>

Related

How to get specific Div's/Card Details when user clicked that using javascript

I am creating various cards using fetch API, this cards are holding details like (Author, Title, Cover Image, etc.).
There is a lot of cards renders there once API call my struggle is how to get specific card data/details like ( author, title etc.) of clicked card. when user clicked any of the card from these set.
HTML
<div class="row" id="ShowReports">
<div class="col-lg-3 col-md-4 col-sm-6 mt-3" onclick="show(this)" id="card">
<div class="card p-1">
<img src="https://d3i5mgdwi2ze58.cloudfront.net/znuxxu2npw851eeboqayu3e35udn" alt="image"
class="bookimg" width="150" height="200">
<h6 class="mb-3 booktitle">${title1}</h6>
<p class="mb-0 bookpara" name="author">Author : ${author1}</p>
<p class="mb-3 bookpara" name="pages">Pages : ${pages1}</p>
Download1
</div>
</div>
<div class="col-lg-3 col-md-4 col-sm-6 mt-3" onclick="show(this)" id="card">
<div class="card p-1">
<img src="https://d3i5mgdwi2ze58.cloudfront.net/znuxxu2npw851eeboqayu3e35udn" alt="image"
class="bookimg" width="150" height="200">
<h6 class="mb-3 booktitle">${title2}</h6>
<p class="mb-0 bookpara" name="author">Author : ${author2}</p>
<p class="mb-3 bookpara" name="pages">Pages : ${pages2}</p>
Download2
</div>
</div>
</div>
javaScript
function show() {
var details = this.innerHTML
console.log(details)
}
Don't know what is the right approach or method to this...
UPDATED
We need to assign unique id to data elements. For example: id="${id}-author". Note that id is from your card id
<div class="col-lg-3 col-md-4 col-sm-6 mt-3" onclick="show(${id})" id="card">
<div class="card p-1">
<img src="https://d3i5mgdwi2ze58.cloudfront.net/znuxxu2npw851eeboqayu3e35udn" alt="image"
class="bookimg" width="150" height="200">
<h6 class="mb-3 booktitle" id="${id}-booktitle">${title1}</h6>
<p class="mb-0 bookpara" name="author" id="${id}-author">Author : ${author1}</p>
<p class="mb-3 bookpara" name="pages" id="${id}-pages">Pages : ${pages1}</p>
Download1
</div>
</div>
After that, we can implement show function like below
function show(id) {
const author = document.getElementById(id + "-author").innerHTML;
const booktitle = document.getElementById(id + "-booktitle").innerHTML;
const pages = document.getElementById(id + "-pages").innerHTML;
console.log({ author, booktitle, pages })
}
If you don't want to modify HTML, you also can try this way
onclick="show({ author: ${author}, booktitle: ${booktitle}, pages: ${pages} })"
And you need to have params corresponding to your data name
function show({ author, booktitle, pages }) {
console.log({ author, booktitle, pages })
}
OLD ANSWER
onclick="show(this)"
this in this context is referred to the global one, but from my understanding of your question, you're trying to get scoped context, so the change could be
onclick="show(event)"
To access the innerHTML from that click, you can try this way
function show(event) { //the param needs to be passed properly
var currentElement = event.target || event.srcElement;
var details = currentElement.innerHTML
console.log(details)
}
P/s: If you want to keep the global context on this, you also need to pass the param on show function.
# Nick Vu thanks for your comment your approach is quite logical and great well what i have did is, I have assigned a unique id to every card div while calling API and then target its childnode's innerHTMLS.
HTML
<div class="col-lg-3 col-md-4 col-sm-6 mt-3" id="card">
<div class="card p-1" id="second" onclick="show(id)">
<img src="https://d3i5mgdwi2ze58.cloudfront.net/znuxxu2npw851eeboqayu3e35udn" alt="image"
class="bookimg" width="150" height="200">
<h6 class="mb-3 booktitle">${title2}</h6>
<p class="mb-0 bookpara" name="author">Author : ${author2}</p>
<p class="mb-3 bookpara" name="pages">Pages : ${pages2}</p>
Download2
</div>
</div>
</div>
javascript
function show(e) {
console.log(e)
var details = document.getElementById(e)
console.log(details)
console.log(details.childNodes[1].src)
console.log(details.childNodes[3].innerHTML)
console.log(details.childNodes[5].innerHTML)
console.log(details.childNodes[7].innerHTML)
}
this is working around what i want as output.. thanks. Or may be at last i can do forEach loop of childnodes to make it more short.

How to place EJS element into onclick="", in a html line

So I am creating a simple project gallery, and to do so I followed a W3schools tutorial on making a photo gallery and converting this to my needs. However with that tutorial the number of items is predefined, for mine, it is connected to MongoDB using Nodejs and stuff.
The original tutorial follows this html scheme:
<div class="section-projects-main-container">
<!-- Full-width images with number text -->
<div class="section-projects-project-container">
<div class="section-projects-project-title">Great Tree 1</div>
<div class="section-projects-project-date">21<span id="slashs">/</span>69<span id="slashs">/</span>4200</div>
<img class="section-projects-project-img" src="tree.jfif">
<div class="section-projects-project-description">This is a sample description, it will explain the project and basic about what this is going to be, and why it is so cool. This is a sample description, it will explain the project and basic about what this is going to be, and why it is so cool.</div>
<button class="section-projects-project-btn">Learn More</button>
</div>
<div class="section-projects-project-container">
<div class="section-projects-project-title">Great Tree 2</div>
<div class="section-projects-project-date">21/21/21</div>
<img class="section-projects-project-img" src="tree2.jfif">
<div class="section-projects-project-description">This is a sample description, it will explain the project and basic about what this is going to be, and why it is so cool. This is a sample description, it will explain the project and basic about what this is going to be, and why it is so cool.</div>
</div>
<!-- Next and previous buttons -->
<a class="section-projects-btn-prev" onclick="plusSlides(-1)">❮</a>
<a class="section-projects-btn-next" onclick="plusSlides(1)">❯</a>
<!-- Thumbnail images -->
<div class="section-projects-thumbnail-mtitle">Other Projects</div>
<div class="section-projects-thumbnail-row">
<div class="section-projects-thumbnail-col" >
<img class="section-projects-thumbnail-img cursor" src="tree.jfif" onclick="currentSlide(1)" alt="The Woods">
<h3 class="section-projects-thumbnail-title">Project Title 1</h3>
<h4 class="section-projects-thumbnail-date">21/69/4300</h4>
</div>
<div class="section-projects-thumbnail-col">
<img class="section-projects-thumbnail-img cursor" src="tree2.jfif" onclick="currentSlide(8)" alt="Cinque Terre">
<h3 class="section-projects-thumbnail-title">Project Title 2</h3>
<h4 class="section-projects-thumbnail-date">21/69/4200</h4>
</div>
</div>
</div>
And the JS used was :
var slideIndex = 1;
showSlides(slideIndex);
// Next/previous controls
function plusSlides(n) {
showSlides(slideIndex += n);
}
// Thumbnail image controls
function currentSlide(n = id) {
showSlides(slideIndex = id);
}
function showSlides(n) {
var i;
var slides = document.getElementsByClassName("section-projects-project-container");
var column = document.getElementsByClassName("section-projects-thumbnail-col");
var dots = document.getElementsByClassName("section-projects-thumbnail-img");
if (n > slides.length) {slideIndex = 1}
if (n < 1) {slideIndex = slides.length}
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
for (i = 0; i < dots.length; i++) {
column[i].className = column[i].className.replace(" active", "");
column[i].style.display = "inline-block";
}
slides[slideIndex-1].style.display = "inline-flex";
column[slideIndex-1].className += " active";
column[slideIndex-1].style.display = "none";
}
So the onclick was passed into <img> of each thumbnail image, and the specific order of the thumbnail was listed into it's parameter as such currentSlide(n).
Now with EJS, the html is as such :
<div class="section-projects-main-container">
<% projectdetails.forEach(project => { %>
<!-- Full-width images with number text -->
<div class="section-projects-project-container">
<div class="section-projects-project-title"><%= project.projectName %></div>
<div class="section-projects-project-date"><%= project.projectDate %></div>
<img class="section-projects-project-img" src="data:<%=project.img.contentType%>;base64,<%=project.img.data.toString('base64')%>">
<div class="section-projects-project-description"><%= project.projectDescription %></div>
<button class="section-projects-project-btn">Learn More</button>
</div>
<% }) %>
<!-- Next and previous buttons -->
<a class="section-projects-btn-prev" onclick="plusSlides(-1)">❮</a>
<a class="section-projects-btn-next" onclick="plusSlides(1)">❯</a>
<!--Thumbnail images-->
<div class="section-projects-thumbnail-mtitle">Other Projects</div>
<div class="section-projects-thumbnail-row">
<% projectdetails.forEach(item => { %>
<div class="section-projects-thumbnail-col" >
<img class="section-projects-thumbnail-img cursor" src="data:<%=item.img.contentType%>;base64,<%=item.img.data.toString('base64')%>" onclick="currentSlide()" alt="The Woods">
<h3 class="section-projects-thumbnail-title"><%= item.projectName %></h3>
<h4 class="section-projects-thumbnail-date"><%= item.projectDate %></h4>
</div>
<% }) %>
</div>
</div>
But I am not sure how to pass the _id of each project into the thumbnail onclick function. I have tried sending the _id into the html <div id="hiddendiv" style="color: white; display: none; position: relative;"><%=project.id %></div> and then retrieving this value via JS and running the function as such. But this does not work properly.
Is there any solution to this? and if not what is the next possible way to make the currentSlide() function without a variable being needed?.
THank you
I would probably skip using a hidden div as some sort of data keeper. Use data-id attribute instead: data-id="<%=project.id %>"
Or on the other hand, why not just do onclick="currentSlide(<%= project.id %>)"?
I would gladly like to help you more, but I don't know what's the point of the JavaScript above and what it should do.
Also, I would probably add an event click listener to every <div class="section-projects-project-container"> and then in the JavaScript got the data-id using: getAttribute('data-id'). You can get the element that called the function using this so you could probably then do:
this.getAttribute('data-id')
Edit:
Well, if it's really that similar to that W3 example - why not just do this?
<% for (var i = 0; i < projectdetails.length; i++) { %>
<div class="section-projects-thumbnail-col">
<img
class="section-projects-thumbnail-img cursor"
src="data:<%= projectdetails[i].img.contentType %>;base64,<%= projectdetails[i].img.data.toString('base64') %>"
onclick="currentSlide(<%= i %>)"
alt="Alternate text"
/>
<h3 class="section-projects-thumbnail-title"><%= projectdetails[i].projectName %></h3>
<h4 class="section-projects-thumbnail-date"><%= projectdetails[i].projectDate %></h4>
</div>
<% } %>
Hopefully it works, but the principle is clear

How to include javascript place holder in Jinja 2 place holder?

I am trying to embed this feature in my Flask app --> Scattered Polaroid Gallery
So, I have a template (Jinja2), where I am displaying a stack of images. To access the images I am using Flask's url_for() command which uses the symbol ---> {{}}. In the Javascript file which is supposed to dynamically load the images, the same symbol is being used i.e ----> {{}}. I want to know how can I use Javascript's {{}} along with Flask/Jinja 2 {{}}
Below is the Javascript function that replaces every instance of {{img}} with the actual file name.
function addPhotos() {
var template = select('#wrap').innerHTML;
var html = [];
var nav = [];
for (i=0; i<1; i++) {
var _html = template.replace('{{index}}', i)
.replace('img', data[i].img)
.replace('{{caption}}', data[i].caption)
.replace('{{desc}}', data[i].desc);
html.push(_html);
nav.push('<span id="nav_'+i+'" class="i" onclick ="turn(select(\'#photo_'+i+'\'))"> </span>');
}
html.push('<div class="nav">'+nav.join('')+'</div>');
select('#wrap').innerHTML = html.join('');
sort(random([0, data.length]));
}
<div class="mainPage" id="fullpage">
<div class="first section">
<div class="wrap" id="wrap">
<div class="photo photo_front" id="photo_{{index}}" onclick="turn(this)">
<div class="photo-wrap">
<div class="side side-front">
<p class="image">
<!-- <img src="photo/{{img}}"> -->
<img src="{{ url_for('static',filename='photo/{{img}}') }}">
<!-- .replace('{{img}}', data[i].img) -->
</p>
<p class="caption">{{caption}}</p>
</div>
<div class="side side-back">
<p class="desc">{{desc}}</p>
</div>
</div>
</div>
</div>
</div>
Above is the template that uses both Javascript and Jinja2 {{}}.
The following error is shown in the Chrome debug console.
Below is my folder structure for the Flask app -
PS - I have tried using relative path for the image folder instead of url_for() function for ex- <img src="../static/photo/{{img}}"> but it failed as well.
In that case, the following error was shown -
Please help.
EDIT -
After having used " , the following error resulted.
You need to escape the curly brackets by using quotes. Since you need to do this inside an html attribute src you will have to escape these quotes as well since quotes are used already inside the HTML attribute and the way to achieve that is byusing "
Take a look at the img tag src attribute below. If you want to escape the Jinja curly brackets that are not part of an HTML attribute then you can use jinja {% raw %} block (see how I surrounded {{caption}} )
<div class="mainPage" id="fullpage">
<div class="first section">
<div class="wrap" id="wrap">
<div class="photo photo_front" id="photo_{{index}}" onclick="turn(this)">
<div class="photo-wrap">
<div class="side side-front">
<p class="image">
<img src="{{ url_for('static',filename='photo/"{{img}}"') }}">
</p>
<p class="caption">{% raw %}{{'caption'}}{% endraw %}</p>
</div>
<div class="side side-back">
<p class="desc">{% raw %}{{desc}}{% endraw %}</p>
</div>
</div>
</div>
</div>
</div>

removing and adding a class based on position within an array Angular

I am creating a blog page using angular 5 where each of the blog posts have the class:
col-md-4
However, what I want is the latest blog post (i.e the first on the page) to have the class of :col-md-12.
The html that I have is as follows:
<div *ngFor="let blog of blogs" class="blog-posts col-md-4">
<div class="card">
<img class="blog-img" (click)="goToBlogDetailsPage(blog.sys.id)"src="{{blog.fields.blogimage.fields.file.url}}" class="rounded" alt="">
<div class="info">
<h3 class="author">{{blog.fields.authorInfo}}</h3>
<h2 (click)="goToBlogDetailsPage(blog.sys.id)" class="title">{{blog.fields.title}}</h2>
<p class="short-desc" > {{blog.fields.desciption}}</p>
<img (click)="goToBlogDetailsPage(blog.sys.id)" class="sml-logo" src="/assets/img/logos/logo_blue.png" alt="">
<!-- <button (click)="goToBlogDetailsPage(blog.sys.id)"class="btn btn-info">Open Blog Post</button> -->
</div>
</div>
</div>
</div>
</div>
I have tried accessing the index of the array[0] however I can not seem to alter the styling on just the first item, any suggestions?
Use index and ternary operator to set the class
<div *ngFor="let blog of blogs; let ind = index" class="blog-posts"
[ngClass]="ind === 0 ? 'col-md-12' : 'col-md-4'" >

Javascript in html tags to avoid repetition

I am a newbie to JavaScript and I need to use it with bootstrap for my own web page. My question is now how can I make a loop so that pictures names (stored as an array) can emerge in the right places of the HTML code so I do not have to copy the blocks of code for each picture.
For example :
<div class="row">
<div class="col-md-3 col-xs-6 portfolio-item">
<img class="img-responsive" src="01.jpg">
</div>
</div>
<div class="row">
<div class="col-md-3 col-xs-6 portfolio-item">
<img class="img-responsive" src="01.jpg">
</div>
</div>
<div class="row">
<div class="col-md-3 col-xs-6 portfolio-item">
<img class="img-responsive" src="02.jpg">
</div>
</div>
<div class="row">
<div class="col-md-3 col-xs-6 portfolio-item">
<img class="img-responsive" src="03.jpg">
</div>
</div>
As we can see here the only different text is the src.How can I store the names (paths) in an array and make a loop that changes the src property?
Thank you!
Try this demo: http://jsbin.com/pinoxeqapi/1/edit?html,output
I think that's what you're looking for.
CODE
$(function () {
var images = ["01.jpg", "01.jpg", "02.jpg", "03.jpg"];
$.each(images, function (index, element) {
var imgContainer = "<div class='row'><div class='col-md-3 col-xs-6 portfolio-item><img class='img-responsive' src='" + element + "'></div></div>";
$("body").append(imgContainer);
});
});
First Include JQuery (If not)
<script>
var srcArray = ['01.jpg', '02.jpg', '03.jpg', '04.jpg'];
$(document).ready(function () {
for (var i = 0; i < srcArray.length; i++) {
$('div.row img.img-responsive').eq(i).attr("src", srcArray[i]);
}
});
</script>
I would recommend using one of the templating frameworks described in some of the other answers. If you're interested to see how to implement this in pure JS:
var temp = document.querySelector('#portfolio-item-template');
['01.jpg', '02.jpg', '03.jpg', '04.jpg'].forEach(function(src) {
temp.content.querySelector(".img-responsive").src = src;
var newImg = document.importNode(temp.content, true);
document.querySelector('#insertion-point').appendChild(newImg);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<template id="portfolio-item-template">
<div class="row">
<div class="col-md-3 col-xs-6 portfolio-item">
<img class="img-responsive">
</div>
</div>
</template>
<div id="insertion-point">
</div>
You can use a template stored in the HTML and then generate the actual elements using an array of the image sources. Something like John Resig's micro-templates can achieve this.
<script type="text/template" id="img-tmpl">
<div class="row">
<div class="col-md-3 col-xs-6 portfolio-item>
<img class="img-responsive" src="<%= src %>">
</div>
</div>
</script>

Categories

Resources