How can i display images from firestore to the carousel slider? - javascript

I have 3 images in the image array in my firestore database. However, when i change ${info.image[0]} to ${info.image1} its displaying the next image. How can i put them all together and when i click on the next button it takes me to the next image?
This is picture of my database and my website
This is my code:
const setupSub = data => {
const id = window.location.href.split('?')[1];
data.forEach(doc => {
if(doc.id === id) {
let info = doc.data();
let html = `
<div class="row" >
<div class="col l6 s12 m12">
<div class="carousel carousel-slider" data-indicators ="true" style="border-radius: 5px;">
<a href="#" class="carousel-item">
<img src="${info.image[0]}" alt="istanbul" style="height: 390px;">
</a>
</div>
<div class="btn indigo waves-affect prev">Prev</div>
<div class="btn indigo waves-affect right next">Next</div>
</div>
<div class="col l6 s12 m12">
<div class="card" style="height: 357px; border-radius: 5px; background-color: #f9f9f9; padding: 10px;">
<h5 class="center">${info.title}</h5><br><br>
<span style="font-weight: bold;">Price: ${info.price} $</span><br><br>
<span><i class="material-icons blue-text">room</i> Located in ${info.city}.</span><br><br>
<span><i class="material-icons blue-text">single_bed</i> Total Rooms ${info.rooms}.</span><br><br>
</div>
</div>
</div>
`;
// To activate the image slider (Materialize css)
$(document).ready(function(){
$('.carousel').carousel();
// function for next slide
$('.next').click(function(){
$('.carousel').carousel('next');
});
// function for prev slide
$('.prev').click(function(){
$('.carousel').carousel('prev');
});
});
propShow.innerHTML = html;
}
})
}

I have managed to do it, for those who are having the same issue this is how you do it:
data.forEach(doc => {
let info = doc.data();
const images = info.image.map(img => {
return (
<a href="#" class="carousel-item">
<img src=${img} alt="istanbul" style="height: 390px;">
</a>
)
});
let html =
<div class="row" >
<div class="col l6 s12 m12">
<div class="carousel carousel-slider";"> ${images.join('')} </div>
...

Related

How make buttons in all cards clickable?

Hi I created a web app with Django. In this app there are 6 cards with a button for increase and a button for decrease the quantity of food to buy. I have a problem: only the buttons in the first card work. Here's the HTML code
<div class="container">
<div class="row">
{% for roll in rolls %}
<div class="col-4">
<div class="card" style="width: 16rem;">
<img src="{{ roll.immagine.url }}" class="card-img-top" alt="...">
<div class="card-body">
<h5 class="card-title">{{ roll.nome }} Roll</h5>
<p class="card-text">€ {{ roll.prezzo }}</p>
<button id="incrementBtn" style="border-radius: 8px; background-color:orange;">+</button>
<span id="counter">0</span>
<button id="decrementBtn" style="border-radius: 8px; background-color: lightsalmon;">-</button>
Acquista
</div>
</div>
</div>
{% endfor %}
</div>
</div>
Here's the Javascript code:
document.addEventListener("DOMContentLoaded", function() {
let idCounter = "counter1, counter2, counter3, counter4, counter5, counter6";
let arrIdCounter = idCounter.split(", ");
console.log(arrIdCounter);
let valueCounter = document.getElementById('counter').innerHTML;
const incrementBtn = document.getElementById('incrementBtn');
const decrementBtn = document.getElementById('decrementBtn');
incrementBtn.addEventListener('click', () => {
console.log(valueCounter);
valueCounter++;
document.getElementById('counter').innerHTML = valueCounter;
console.log(valueCounter);
});
decrementBtn.addEventListener('click', () => {
if (valueCounter > 0)
{
valueCounter--;
}
document.getElementById('counter').innerHTML = valueCounter;
});
});
When you render your file you will have something like:
<div class="col-4">
<div class="card" style="width: 16rem;">
...
<button id="incrementBtn" ...>+</button>
...
<button id="decrementBtn" ...>-</button>
...
</div>
</div>
<div class="col-4">
<div class="card" style="width: 16rem;">
...
<button id="incrementBtn" ...>+</button>
...
<button id="decrementBtn" ...>-</button>
...
</div>
</div>
<div class="col-4">
<div class="card" style="width: 16rem;">
...
<button id="incrementBtn" ...>+</button>
...
<button id="decrementBtn" ...>-</button>
...
</div>
</div>
How your script may know which element take? You cannot have more than 1 html element with same id, they have to be unique. To do so, you may change you buttons' ids to:
<button id="incrementBtn_{{ poll.id }}" style="border-radius: 8px; background-color:orange;">+</button>
And your variable to array:
const incrementBtn = document.querySelectorAll('[id^="incrementBtn"]');
But then of course you have to use it in loop.

Update Incremented Quantity in Order Item Total?

I'm trying to update item totals when an image card is clicked and update the corresponding totals and prices in an order panel. See screenshot.
I'm currently incrementing the quantity total onclick in the black circle qty-icon div on the image card using the "Update food quantity" function below which increments the number, but how do I pass that incremented value to the "0 Items" field in the add-order-panel panel at the bottom and update the price in "Add to Order"?
Link to GitHub repo
Live GitHub page
// Update food quantity
$(function() {
$('.food-container').click( function() {
var num = $(this).find('.qty-icon');
num.text( parseInt(num.text()) + 1 );
});
});
<!-- Sliders -->
<div class="food-container">
<div class="food-icon">
<div class="qty-icon">0</div>
<img src="images/food/icons/sliders.png" alt="">
</div>
<div class="food-details">
<div class="food-title left">
<h4>Sliders</h4>
</div>
<div class="food-title right">
<h4>$5</h4>
</div>
</div>
</div>
<!-- Add to Order Panel -->
<div class="add-order-panel down">
<!-- Order Buttons -->
<div class="order-buttons">
<a href="#">
<div class="order-but-container one">
<h4><span class="bold-cash">0</span> Items</h4>
</div>
</a>
<a href="#">
<div class="order-but-container two">
<div class="order-label">
<h4>Add to Order</h4>
</div>
<div>
<h4><span class="bold-cash">$0</span></h4>
</div>
</div>
</a>
</div>
</div>
You can use .each loop to iterate through your food-container div then inside this you need to get qty ,price and add them to some variable . Finally ,show these values insid your total & item quantity spans.
Demo code :
$(function() {
$('.food-container .qty-icon').click(function() {
var num = $(this);
num.text(parseInt(num.text()) + 1);
var qty = 0;
var total = 0;
//loop through your food conatiner divs
$(".food-container").each(function() {
//add total qty on evry iteration
qty += parseInt($(this).find(".qty-icon").text())
//get actual qty
var qty_of_item = parseInt($(this).find(".qty-icon").text())
//mutliply it with price add total
total += parseInt($(this).find('.price').text().replace('$', '')) * qty_of_item;
})
$(".order-but-container.one .bold-cash").text(qty); //set new qty
$("#total").text("$" + total) //set total
});
});
.food-container {
width: 105px;
height: 150px;
border: 1px solid blue;
margin-bottom: 5px
}
.food-icon {
text-align: right;
font-size: 20px
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- Order Buttons -->
<div class="order-buttons">
<a href="#">
<div class="order-but-container one">
<h4><span class="bold-cash">0</span> Items</h4>
</div>
</a>
<a href="#">
<div class="order-but-container two">
<div class="order-label">
<h4>Add to Order</h4>
</div>
<div>
<!--added here id-->
<h4><span id="total" class="bold-cash">$0</span></h4>
</div>
</div>
</a>
</div>
<div class="food-container">
<div class="food-icon">
<div class="qty-icon">0</div>
<img src="images/food/icons/sliders.png" alt="">
</div>
<div class="food-details">
<div class="food-title left">
<h4>pizza</h4>
</div>
<div class="food-title right">
<!--added here class-->
<h4 class="price">$10</h4>
</div>
</div>
</div>
<div class="food-container">
<div class="food-icon">
<div class="qty-icon">0</div>
<img src="images/food/icons/sliders.png" alt="">
</div>
<div class="food-details">
<div class="food-title left">
<h4>burger</h4>
</div>
<div class="food-title right">
<h4 class="price">$5</h4>
</div>
</div>
</div>
<div class="food-container">
<div class="food-icon">
<div class="qty-icon">0</div>
<img src="images/food/icons/sliders.png" alt="">
</div>
<div class="food-details">
<div class="food-title left">
<h4>somethings</h4>
</div>
<div class="food-title right">
<h4 class="price">$5</h4>
</div>
</div>
</div>
<div class="add-order-panel down">
You're over thinking it :) You're already storing the element your wanting into a variable called "num". Then you're grabbing the text inside of it. Here's what you do.
redefine num to be the text of the element.
do this for every other element you want to update the text for.
then add all of the values of those inside the function.
save that in a var called total and update that in the area where the total should be
make sure to start total at 0 every time the function runs or you will compound the value
note you'll want to declare all of your variables globally and then update them locally. Don't declare any variables locally or they will come back undefined when you try to update them in other functions
$(function() {
let total = 0
$('.food-container').click( function()
{var num = $(this).find('.qty-icon');
num = num.text( parseInt(num.text()) + 1 );
total = num + otherVar + yetAnotherVar});});

traversing an html file to get a a href

My html file is as below
<div id="sidebar" style="top: 100px;">
<div class="items">
<div class="item hentry selected" itemscope="" itemtype="http://schema.org/BlogPosting" data-id="3714235398193725034">
<img class="thumbnail" src="http://4.bp.blogspot.com/-FLnjwm6youQ/UUGhQei8KqI/AAAAAAAAAUE/nEl-5V5IcDw/s30-p/1.jpg" style="width: 30px; height: 30px;">
<h3 class="title entry-title" itemprop="name">
art1
</h3>
</div>
<div class="item hentry" itemscope="" itemtype="http://schema.org/BlogPosting" data-id="179325489509322215">
.
.
.
</div>
</div>
</div>
The html has a div with id sidebar
Under that there is another div with class items
Under that there are multiple divs with class item
Under each div with class item I have a h3 with class title
Under h3 tag I have 'a' tag
I need to get the href values of 'a' tags under all divs with class item.
I would appreciate some help as to how to do the same.
Thanks
Once try with inline jQuery:
$.each($("#sidebar .items .item h3 a"),function(a,b){console.log($(b).attr("href"));});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="sidebar" style="top: 100px;">
<div class="items">
<div class="item hentry selected" itemscope="" itemtype="http://schema.org/BlogPosting" data-id="3714235398193725034">
<img class="thumbnail" src="http://4.bp.blogspot.com/-FLnjwm6youQ/UUGhQei8KqI/AAAAAAAAAUE/nEl-5V5IcDw/s30-p/1.jpg" style="width: 30px; height: 30px;">
<h3 class="title entry-title" itemprop="name">
art1
</h3>
</div>
<div class="item hentry" itemscope="" itemtype="http://schema.org/BlogPosting" data-id="179325489509322215">
<img class="thumbnail" src="http://4.bp.blogspot.com/-FLnjwm6youQ/UUGhQei8KqI/AAAAAAAAAUE/nEl-5V5IcDw/s30-p/1.jpg" style="width: 30px; height: 30px;">
<h3 class="title entry-title" itemprop="name">
art2
</h3>
</div>
</div>
</div>
You can first get all divs with class item using getElementsByClassNameand then for each div find all the anchor tags under that div using getElementsByTagName.
const itemDivs = [...document.getElementsByClassName('item')];
const hrefs = [];
itemDivs.forEach(div => {
const anchors = [...div.getElementsByTagName('a')];
if (anchors && anchors.length > 0) {
anchors.forEach(a => hrefs.push(a.href));
}
});
console.log(hrefs); // prints ["http://mywebsiteurl/2013/03/blog-post.html"]
You can try using DOMParser api
let html = `<div id="sidebar" style="top: 100px;">
<div class="items">
<div class="item hentry selected" itemscope="" itemtype="http://schema.org/BlogPosting" data-id="3714235398193725034">
<img class="thumbnail" src="http://4.bp.blogspot.com/-FLnjwm6youQ/UUGhQei8KqI/AAAAAAAAAUE/nEl-5V5IcDw/s30-p/1.jpg" style="width: 30px; height: 30px;">
<h3 class="title entry-title" itemprop="name">
art1
</h3>
</div>
<div class="item hentry" itemscope="" itemtype="http://schema.org/BlogPosting" data-id="179325489509322215">
</div>
</div>
<div class = 'item'>
<a href='http://example1.com'/>
</div>
<div class = 'noitem'>
<a href='http://example2.com'/>
</div>
</div>`
let parser = new DOMParser()
let parsed = parser.parseFromString(html, 'text/html')
let anchors = [...parsed.querySelectorAll('.item > a')]
let hrefs = anchors.map(v=> v.href)
console.log(hrefs)

setTimeout function on a <div>

I am working on my own portfolio and I want to put a delay between 2 pages with a setTimeout function. I've tried some ways but haven't worked yet. I am already using a function to open my "href" with all my box but now I just want to put a delay to go from accueil.html to presentation.html.
"accueil.html":
document.addEventListener('DOMContentLoaded', function()
{
var items = document.querySelectorAll('.ouverture');
for (var i = 0; i < items.length; i++)
{
var item = items[i];
item.addEventListener('click', function()
{
var url = this.getElementsByTagName('a');
url = url[0];
window.location = url;
});
}
});
<div class="box">
<div class="container">
<div class="row">
<div class="col-lg-4 col-md-4 col-sm-4 col-xs-12">
<div class="box-part text-center ouverture">
<i class="fa fa-address-book fa-3x" aria-hidden="true"></i>
<div class="title">
<h4>Présentation</h4>
</div>
</div>
</div>
</div>
</div>
</div>
Just add a timeout add the part where you redirect to another page:
item.addEventListener('click', function() {
var url = this.getElementsByTagName('a');
if(url.length > 0)
url = url[0];
setTimeOut(() => {
window.location = url;
}, 2000); // 2000 = 2000ms === 2sec
});
More info is found here
A general-purpose snippet that "delays" clicks. Just add the script at the top of the page and use the delay-click[=numberOfMilliseconds] attribute.
document.body.addEventListener("click", function(event) {
var target = event.target;
var currentTarget = target.closest("[delay-click]:not(.delay-click-ignore)");
if (!currentTarget) return;
var delay = +currentTarget.getAttribute("delay") || 2000;
currentTarget.classList.add("delay-click-ignore");
setTimeout(function() {
target.click();
currentTarget.classList.remove("delay-click-ignore");
}, delay);
event.preventDefault();
});
.delay-click-ignore,
.delay-click-ignore a,
.delay-click-ignore input,
.delay-click-ignore button {
cursor: progress !important;
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<div class="box">
<div class="container">
<div class="row">
<div class="col-lg-4 col-md-4 col-sm-4 col-xs-12">
<div class="box-part text-center ouverture">
<i class="fa fa-address-book fa-3x" aria-hidden="true"></i>
<div class="title">
<!-- on the element itself -->
<h4><a href="presentation.html" delay-click>default delay</a></h4>
</div>
</div>
</div>
<div class="col-lg-4 col-md-4 col-sm-4 col-xs-12">
<!-- or somewhere up the ranks -->
<div class="box-part text-center ouverture" delay-click=5000>
<i class="fa fa-address-book fa-3x" aria-hidden="true"></i>
<div class="title">
<h4>delay 5s</h4>
</div>
</div>
</div>
<div class="col-lg-4 col-md-4 col-sm-4 col-xs-12">
<div class="box-part text-center ouverture">
<i class="fa fa-address-book fa-3x" aria-hidden="true"></i>
<div class="title">
<h4>immediate</h4>
</div>
</div>
</div>
</div>
<div class="form-group">
<!-- works here too -->
<input type="checkbox" class="form-control" delay-click />
</div>
</div>
</div>

*ngIf is not working like other *ngIf's

I encountered a strange problem with my *ngIf on one particular variable isAdmin (which should allow me to display the list of users in userList). I'm not sure why its behaving different from all the other *ngIf statements in the same component.
heres a snippet of my js code for the component. This is where isAdmin is being switched from false to true if the user is an Admin.
_initAutorun(): void {
this.autorunComputation = Tracker.autorun(() => {
this.zone.run(() => {
this.usersList = Meteor.users.find({}).fetch(); //update the users list automatically
this.currentUser = Meteor.user(); //update the current user automatically
this.isLoggingIn = Meteor.loggingIn();
this.isLoggedIn = !!Meteor.user();
this.checkAndSub();
});
});
}
checkAndSub(){
if(this.isLoggingIn){
Meteor.call('checkAdmin', function(error, result) {
if (error) {
this.errors.push(error.reason || "call from server has an error");
}
this.isAdmin = result;
console.log(this.isAdmin);
if(this.isAdmin){
Meteor.subscribe("userList");
}
else console.log("User is not admin");
});
}
}
Heres the corresponding HTML
<span *ngIf="viewDetails">
<div class="pizza_details" id="pizza_details" [ngClass]="{'show' : viewDetails, 'hide' : !viewDetails}">
<div class="row">
<!--PIZZA DESCRIPTION PANEL-->
<div class="pizza_description col-lg-4 col-md-4 col-sm-12 col-xs-12">
<div class="panel" id="description_panel">
<div class="panel-body">
<div>
{{error}}{{message}}
<span *ngIf="isAdmin">
<p><h2>User List</h2></p>
<ul>
<li *ngFor="let iterate of usersList">
_id: {{iterate._id}}
<p>Emails: {{iterate.emails}}</p>
<p>username: {{iterate.username}}</p>
<p>isadmin: {{iterate.isAdmin}}</p>
</li></ul>
</span>
</div>
<h1>Description: </h1>
{{currentPizza.description}}
<p><button type="button" class="btn active" role="button" (click)="toggle()">Toggle</button></p>
</div>
</div>
</div><!--&&&&pizza description collapes&&&&-->
<!--STARTING THE "SECOND PANEL" FOR PICTURES, STYLE, VOTES, AND MODS-->
<div class="col-lg-8 col-md-8 col-sm-12 col-xs-12">
<div class="row">
<div class="pizza_picture col-lg-12 col-md-12 col-sm-12 col-xs-12">
<div class="panel" id="picture_panel">
<div class="panel-body" style="padding:0px;">
<img src="{{currentPizza.imageUrl}}" class="img-rounded" style="max-height: 400px; width:100%;">
</div>
</div>
</div><!--&&&&pizza picture collapse&&&&-->
</div>
<div class="row">
<div class="pizza_style col-lg-6 col-md-6 col-sm-12 col-xs-12">
<div class="panel" id="style_panel">
<div class="panel-body">
<h4>Style:</h4>{{currentPizza.style}}
<h4>Location:</h4>
<span *ngIf="currentPizza.location.state">
{{currentPizza.location.state}} ,
</span>
{{currentPizza.location.country}}
<h4>Brand: </h4>{{currentPizza.brand}}
</div>
</div>
</div><!--&&&&pizza style collapse&&&&-->
<div class="pizza_votes col-lg-6 col-md-6 col-sm-12 col-xs-12">
<div class="panel" id="vote_panel">
<div class="panel-body">
<h3>Pizza Spectrum Score: </h3>
{{currentPizza.votes}}
</div>
</div>
</div><!--&&&&pizza votes collapse&&&&-->
</div>
<div class="row">
<div class="pizza_users col-lg-12 col-md-12 col-sm-12 col-xs-12">
<div class="panel" id="user_panel">
<div class="panel-body">
<h3>SubmittedBy: </h3>
{{submittedBy(currentPizza._id)}}
<ul><li *ngFor="let i of currentPizza.userUpvotes">{{i}}
</li>
</ul>
<p><button type="button" id="exit_details_btn" class="btn active" role="button" (click)="toggleDetails()">Exit Details</button>
<button type="button" id="upvote_btn" class="btn active" role="button" (click)="upVote(currentPizza._id)">Upvote</button>
<button type="button" id="downvote_btn" class="btn active" role="button" (click)="downVote(currentPizza._id)">Downvote</button></p>
<button type="button" id="downvote_btn" class="btn active" role="button" (click)="cc()">publish all users</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</span>
I know isAdmin is true, but nothing shows up. If I create a separate button to toggle it then my userLIst shows up. Why won't it display properly when the page is loaded?
Thanks
Try changing the span *ngIf to a div. I simple check could be to temporary change the content in the span to a static text ex: hello. Can you then see the hello? If true it's a markup problem
ngZOne.run doesn't mark a component for change detection. All it does is execute the callback function inside the Angular error handler.
You need to inject ChangeDetechRef and call markForCheck.
public constructor(private cdr: ChangeDetectorRef, private zone: NgZone) {
}
then elsewhere:
_initAutorun(): void {
this.autorunComputation = Tracker.autorun(() => {
this.zone.run(() => {
//.....
this.checkAndSub();
this.cdr.markForCheck(); // <--- mark component dirty
});
});
}

Categories

Resources