Creating a product table and counter with javascript - javascript

I'm looking to create a product table that lets the user add products to a counter, or cart if you like. I think I've got most of the coding concepts but I can't seem to get it to work.
Some of the code snippet seem to work on their own but as soon as I put them together I get no results at all.
Here is the Javascript:
// Products with descriptions
const products = [
{
"name": "Aloe Vera",
"origin": "Nederländerna",
"description": "Lättskött suckulent med tjocka gröna blad. En av världens äldsta läkeväxkter. Trivs på soliga platser. Låt den torka ut mellan varje vattning",
"care": "Lättskött suckulent som trivs ljust, men undvik direkt solljus. Vattna undertill och inte på växten, men låt jorden torka mellan varje vattning. Ge flytande näring från vår till höst. Eventuell omplantering ska göras på våren.",
"price": 799,
"image": "images/Aloevera.png"
},
{
"name": "Citronfikus",
"origin": "Danmark",
"description": "En vacker växt med blanka, små gröna blad. Lättskött alternativ till en bonsai. Trivs i ljust till halvskuggigt läge. Vattnas då jorden nästan torkat upp, ungefär en gång i veckan.",
"care": "Passar bra i uterummet sommartid, vänt mot öst eller väst. Behöver extra ljus vintertid. Tål måttlig uttorkning, men att vattna den regelbundet är rekommendationen för att den ska bli så fin som möjligt.",
"price": 299,
"image": "images/Citronfikus.png"
},
{
"name": "Benjaminfikus",
"origin": "Asien och Australien",
"description": "En vacker växt med blanka, gröna blad, här med elegant flätad stam. Trivs ljust, men undvik direkt solljus. Låt den torka lätt mellan vattningarna. Gillar att bli duschad på bladen.",
"care": "Vill stå så ljust men undvik direkt sol och drag. Flytta helst inte växten under vinterhalvåret då den kan tappa sina blad. Vattna 1 gång i veckan. Håll jorden fuktig. Under vinterhalvåret behöver den inte samma mängd vatten. Ge den näring 1 gång i veckan under våren och sommaren. Under höst och vinter 1 gång i månaden. ",
"price": 599,
"image": "images/Benjaminfikus.png"
}
];
// The protocol array pointing the key that is the products
let protocol = {};
// Starting of the amount at 0
function initProtocol() {
for (let product of products) {
protocol[product.name] = 0;
}
}
// The body of the protocol
function renderProtocol() {
let tbody = document.querySelector("#protocol > tbody");
tbody.innerHTML = "";
for (let product of products) {
let row = tbody.insertRow(-1);
let cellName = row.insertCell(-1);
let cellAmount = row.insertCell(-1);
let cellScore = row.insertCell(-1);
let amount = protocol[product.name];
cellName.textContent = product.name;
cellAmount.textContent = amount;
cellScore.textContent = amount * product.score;
}
}
// Uping the product amount in the protocol
function increment(name) {
console.log("Name: " + name);
protocol[name]++;
renderProtocol();
}
// Rendering the design of the product table
function renderProducts() {
const template = `
<img>
<div class="p-2">
<div>
<span class="name"></span>
<span class="plus float-right" title="Lägg till produkt">
<i class="fa fa-plus-square" aria-hidden="true"></i>
</span>
</div>
<div class="origin"></div>
<div class="description"></div>
<div class="care"></div>
<div class="price"></div>
</div>
`;
const container = document.querySelector("#products");
for (let product of products) {
let item = document.createElement("div");
item.classList.add("item", "ml-2");
item.innerHTML = template;
item.querySelector("img").src = product.image;
item.querySelector(".name").textContent = product.name;
item.querySelector(".origin").textContent = product.origin;
item.querySelector(".care").textContent = product.care;
item.querySelector(".price").textContent = product.price;
item.querySelector(".description").textContent = product.description;
item.querySelector(".plus").addEventListener("click", () => increment(product.name));
container.appendChild(item);
}
}
window.onload = function() {
renderProducts();
initProtocol();
renderProtocol();
}
And here is the HTML:
<body> <h1 class="headline">Produkter</h1>
<div class="container col-12">
<div class="row">
<div class="col-8 d-flex flex-wrap" id="products"></div>
<div class="col-4">
<table class="table" id="protocol">
<thead>
<tr>
<th>Produkt</th>
<th>Antal</th>
<th>Pris</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
</div>
</div>
</body>

You're trying to invoke renderBirds method but its not defined yet.
Tip: Whenever you code and something doesn't seems to work appropriately try checking console errors. They might help you a lot!

Related

Empty image when trying to change src in javascript

I am trying to change an image and some text in javascript trough a button.I can change the text but no matter what I do if I change the image it's just an image not found icon
Here's my relevant html:
`
<div class="review1">
<img id="student" src="images\review1.png" />
<div id="review1text">
<h1 id="reviewnume">Alina,21</h1>
<p id="reviewtext">
Sunt studenta la Politehnica in Bucuresti si Pitagora.ro m-a ajutat
foarte mult sa aprofundez cunostiintele mele de algebra.Recomand cu
cea mai mare incredere!
</p>
</div>
<i class="fa-solid fa-circle-arrow-left"></i>
<i class="fa-solid fa-circle-arrow-right"></i>
</div>
And here is my javascript:
let btnNext = document.querySelector("fa-solid fa-circle-arrow-right");
let btnprevious = document.querySelector("fa-solid.fa-circle-arrow-left");
btnNext = addEventListener("click", () => {
document.getElementById("reviewtext").textContent =
"Nu am reusit sa ajung la cursurile mele de algebra din cause serviciului.In orice caz,nu a fost mare pierdere deoarece Pitagora.ro m-a ajutat sa recuperez materia fara probleme";
document.getElementById("reviewnume").textContent = "Bogdan,22";
document.getElementById("reviewnume").style.textAlign = "center";
document.getElementById("reviewtext").style.fontSize = "25px";
document.getElementById("reviewtext").style.marginLeft = "20px";
document.getElementById("student").src = "images\review2.png";
});
Again,the text on "reviewnume" and "reviewtext" changes when I click but the image from "review1" to "review2" doesn't,even though they are in the same folder
You are getting this error because you forgot to use the dot(.) operator when finding an element using a class name.
I mean, you did-
let btnNext = document.querySelector("fa-solid fa-circle-arrow-right");
But you should do-
let btnNext = document.querySelector(".fa-solid .fa-circle-arrow-right");
or
let btnNext = document.querySelector(".fa-circle-arrow-right");
You also used the wrong syntax for the event listener.
btnNext = addEventListener("click", () => {...});
but it should be-
btnNext.addEventListener("click", () => {...});
Here is the working demo-
let btnNext = document.querySelector(".fa-circle-arrow-right");
let btnprevious = document.querySelector(".fa-circle-arrow-left");
btnNext.addEventListener("click", () => {
document.getElementById("reviewtext").textContent =
"Nu am reusit sa ajung la cursurile mele de algebra din cause serviciului.In orice caz,nu a fost mare pierdere deoarece Pitagora.ro m-a ajutat sa recuperez materia fara probleme";
document.getElementById("reviewnume").textContent = "Bogdan,22";
document.getElementById("reviewnume").style.textAlign = "center";
document.getElementById("reviewtext").style.fontSize = "25px";
document.getElementById("reviewtext").style.marginLeft = "20px";
document.getElementById("student").src = "https://picsum.photos/id/237/200/300";
});
btnprevious.addEventListener("click", () => {
document.getElementById("student").src = "https://picsum.photos/200/300";
});
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.1/css/all.min.css" integrity="sha512-MV7K8+y+gLIBoVD59lQIYicR65iaqukzvf/nwasF0nqhPay5w/9lJmVM2hMDcnK1OnMGCdVK+iQrJ7lzPJQd1w==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<div class="review1">
<img id="student" src="https://picsum.photos/200/300" />
<div id="review1text">
<h1 id="reviewnume">Alina,21</h1>
<p id="reviewtext">
Sunt studenta la Politehnica in Bucuresti si Pitagora.ro m-a ajutat
foarte mult sa aprofundez cunostiintele mele de algebra.Recomand cu
cea mai mare incredere!
</p>
</div>
<i class="fa-solid fa-circle-arrow-left"></i>
<i class="fa-solid fa-circle-arrow-right"></i>
</div>
Try this code
const image = document.getElementById("student");
image.setAttribute("src","images\review2.png");
If it doesn't work check the path or the type of image is png or not.
change
document.getElementById("student").src = "images\review2.png";
to
document.getElementById("student").setAttribute('src', "images\review2.png");

How to show the item of a tab with Pagination

I want to make a Pagination control with a tabs of JSON data that I retrives from an AJAX request i pull it on a tabs like this :
I managed to display all the data and show only the 10 first and after the if i click on "page 2" it hide the 10 first and the 10 after to show the 10 that i need; with a max number of 10 per page, and number of page are dynamic, the active page works and i logged in the console the info to make it sure.
But when i click on a page number different than 1 the data are hide, but if i click on the first page it show the data.
https://www.youtube.com/watch?v=Xznn-ggD0GU i found this guy and I wanted to do the same but, i may forget something like a bad selected class or id...
HTML:
<div class="container">
<div id="conTable" class="table-responsive-xl">
<!-- Tableau de données des mails -->
<table class="table table-hover table-dark mail">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Date</th>
<th scope="col">From</th>
<th scope="col">To</th>
</tr>
</thead>
<tbody class="ItemMail">
<!-- Insertion infos des mails avec JQuery/AJAX depuis main.js-->
</tbody>
</table>
</div>
<!-- Pagination -->
<nav aria-label="Page navigation example">
<ul class="pagination d-flex justify-content-center">
<!-- Insertion du Bouton "Previous" -->
<!-- Insertion du nombres de pages -->
<!-- Insertion du Bouton "Next" -->
</ul>
</nav>
</div>
JQuery/JS code which take my data :
$("#contTable").toggleClass('d-block table-responsive-xl');
for(ligne in response) {
console.log(response[ligne].hits)
var res=response[ligne].hits;
for(ligne2 in res) {
var lastEventDate=res[ligne2]._source.last_event_date;
var from=res[ligne2]._source.from;
var to=res[ligne2]._source.to;
$(".ItemMail:last").append(
"<tr>"+
"<th scope='row'>"+(increment+=1)+"</th>"+
"<td>"+lastEventDate+"</td>"+
"<td>"+from+"</td>"+
"<td>"+to+"</td>"+
"</tr>"
);
}
}
And finally my Pagination code :
//Pagination
var TotalMail=response.hits.total;
var limitMailParPage=10;
// cache les mails au dessus du nombre max de limitMailParPage
$(".ItemMail:gt("+(limitMailParPage-1)+")").hide();
// compte le nombre de pages qu'il faudra pou stocker les mails
var nbrDePage=Math.round(TotalMail/limitMailParPage);
// Insertion du nombre 1 pour le mettre en active par défaut
$(".pagination li:first").after("<li class='page-item current active'><a class='page-link' href='javascript:void(0)'>"+1+"</a></li>");
for(var i=2; i<=nbrDePage; i++) {
$(".pagination li:last").before("<li class='page-item current'><a class='page-link' href='javascript:void(0)'>"+i+"</a></li>");
}
$(".pagination li.current").click(function() {
if($(this).hasClass("active")) {
return false;
}
else {
var currentIndex=$(this).index();
$(".pagination li").removeClass("active");
$(this).addClass("active");
$(".ItemMail").hide();
// marche pas à partir d'ici
var grandTotal=(limitMailParPage*currentIndex);
console.log(grandTotal+" GRAND TOTAL");
for(var i=grandTotal-limitMailParPage; i<grandTotal; i++) {
console.log(i);
$(".ItemMail:eq("+i+")").show();
}
}
});
Instead of show hide parent div toggle on tr . Please refer below code.
('.ItemMail') is your parent div class. You are hiding whole div thats why second page is blank. Try below code and it will solve your problem.
var TotalMail=response.hits.total;
var limitMailParPage=10;
// cache les mails au dessus du nombre max de limitMailParPage
$(".ItemMail tr:gt("+(limitMailParPage-1)+")").hide();
// compte le nombre de pages qu'il faudra pou stocker les mails
var nbrDePage=Math.round(TotalMail/limitMailParPage);
// Insertion du nombre 1 pour le mettre en active par défaut
$(".pagination li:first").after("<li class='page-item current active'><a class='page-link' href='javascript:void(0)'>"+1+"</a></li>");
$(".pagination li.current").click(function() {
if($(this).hasClass("active")) {
return false;
}
else {
var currentIndex=$(this).index();
$(".pagination li").removeClass("active");
$(this).addClass("active");
$(".ItemMail tr").hide();
// marche pas à partir d'ici
var grandTotal=(limitMailParPage*currentIndex);
console.log(grandTotal+" GRAND TOTAL");
for(var i=grandTotal-limitMailParPage; i<grandTotal; i++) {
console.log(i);
$(".ItemMail tr:eq("+i+")").show();
}
}
});

how to retrieve a value by clicking and retrieve the id?

I want to make a function that allows me by clicking on the square with the id of colors, in return me id = " retours_couleurs " the sentence containing the colors contained in the table in php files, sorry for my english i'm french
this is my html code
<fieldset class="appel">
<code>
Un clic simple sur le carré bleu appelle le contenu du fichier couleurs.php, en transmettant en paramètre l'ID de ce carré. La réponse du fichier appelé devra s'afficher dans l'espace prévu à cet effet (id="retour_couleurs").
</code>
</fieldset>
<br />
<fieldset class="appel">
<div class="carre-couleurs">
<div class="carre" id="jaune"></div>
<div class="carre" id="rouge"></div>
<div class="carre" id="bleu"></div>
<div class="carre" id="vert"></div>
<div class="clear"></div>
</div>
<br />
<br />
<fieldset class="retour">
<legend>Contenu du fichier</legend>
<div id="retour_couleurs"></div>
</fieldset>
</fieldset>
this is my ajax function
function appel_contenue_couleur(){
var cM = new XMLHttpRequest();
cM.open("POST","fichiers/couleurs.php",true);
cM.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
var couleur = this.id;
var retour_couleurs = document.getElementById('retour_couleurs');
cM.send("retour= "+couleur);
cM.onreadystatechange = function (){
if (cM.readyState == 4 && cM.status == 200)
{
retour_couleurs.innerHTML=cM.responseText;
}
}}
and this is my php code
$_couleurs = array("jaune", "rouge", "bleu", "vert");
$_citations = array(
"L’herbe est toujours plus verte ailleurs",
"La terre est bleue comme une orange",
"Le ciel est un oeuf, la terre en est le jaune",
"Mieux vaut rester rouge cinq minutes que jaune toute la vie",
"C'était un moustique snob. Il ne buvait que du sang bleu"
);
$couleurs = $_POST['retour'];
if (in_array($couleurs,$_couleurs)){
for ($i=0;$i<count($_citations);$i++){
if (in_array ($couleurs,$_citations[$i])){
echo $_citations[$i];
}
}
}
If I understood your problem correctly, you're not getting any output from the AJAX request. That's probably because you're using the wrong PHP function to check if a sentence contains a certain word.
Try with this one:
if (stripos($_citations[$i], $couleurs) !== false) {
echo $_citations[$i];
}
I used stripos because you probably don't want to make a case sensitive check.
Complete code:
Javascript:
function appel_contenue_couleur(obj){
var cM = new XMLHttpRequest();
cM.open("POST","colors.php",true);
cM.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
var couleur = obj.id;
var retour_couleurs = document.getElementById('retour_couleurs');
cM.send("retour= "+couleur);
cM.onreadystatechange = function (){
if (cM.readyState == 4 && cM.status == 200)
{
retour_couleurs.innerHTML=cM.responseText;
}
}}
HTML:
<div class="carre-couleurs">
<div class="carre" id="jaune" onclick="appel_contenue_couleur(this);">1111111</div>
<div class="carre" id="rouge" onclick="appel_contenue_couleur(this);">222222222</div>
<div class="carre" id="bleu" onclick="appel_contenue_couleur(this);">33333333</div>
<div class="carre" id="vert" onclick="appel_contenue_couleur(this);">444444444444</div>
<div class="clear"></div>
</div>
PHP:
$colors = array("jaune", "rouge", "bleu", "vert");
$citations = array(
"L’herbe est toujours plus verte ailleurs",
"La terre est bleue comme une orange",
"Le ciel est un oeuf, la terre en est le jaune",
"Mieux vaut rester rouge cinq minutes que jaune toute la vie",
"C'était un moustique snob. Il ne buvait que du sang bleu"
);
$color = trim($_POST['retour']);
//echo $color;
if (in_array($color,$colors)){
for($i=0;$i<count($citations);$i++) {
if(stripos($citations[$i],$color)!==false) {
echo $citations[$i].'<br>';
}
}
}
It is working, 100%, it's tested. Just change links, if needed.

how to add a caption to a jquery gallery

I'm using a hand made jquery gallery based on this tutorial : http://www.alsacreations.com/tuto/lire/719-galerie-images-simple-jquery.html
I've made a plugin of this gallery to use it several time in a same page.
From here, no real problem. My question is, how to add a text caption with this plugin. I've tried lots of things without finding a solution.
Here is the jquery gallery code :
jQuery(function($){
// définition du plugin
$.fn.ben_galerie = function(options) {
// définition des paramètres par défaut
var defaults = {
activeClass: "active",
activeTitle: "Photo en cours de visualisation",
loaderTitle: "Chargement en cours",
loaderImage: "/ben/images/loader.gif"
};
// mélange des paramètres fournis et des paramètres par défaut
var settings = $.extend(defaults, options);
function initGallery(ul)
{
var thumbLinks = $(this).find("a"), //référence toutes les vignettes cliquables dans un tableau
firstThumbLink = thumbLinks.eq(0), //et extrait le premier élément
//listeLinks = $(this).find("li"),
highlight = function(elt){
thumbLinks.removeClass(settings.activeClass).removeAttr("title"); //supression de l'attribut title
elt.addClass(settings.activeClass).attr("title",settings.activeTitle); //ajout du nouvel attribut title pour l'image en cours de visualisation
},
loader = $(document.createElement("img")).attr({ //chargement des parametres du loader
alt: settings.loaderTitle,
title: settings.loaderTitle,
src: settings.loaderImage
});
highlight(firstThumbLink);
var imgViewer = $(document.createElement("p")).attr("class","viewer") //creation d'un paragraphe qui fera office de récepteur pour les images grand format
.append(
$(document.createElement("img")).attr({ //extraire le contenu de l'attribut href de la première vignette photo
alt: "",
src: firstThumbLink.attr("href") //et le renseigner en tant que valeur de l'attribut src d'un nouvel objet image créé
})
);
$(this).after(imgViewer);
var bigPic = imgViewer.children("img");
thumbLinks //fonction qui sera déclenchée au clic sur chaque élément ciblé
.click(function(e){
e.preventDefault(); //annule l'événement par défaut lors du clic sur le lien
var $this = $(this), //$(this) = vignette cliquée et stocké dans $this pour ne pas parcourir pls fois le DOM
target = $this.attr("href");
if (bigPic.attr("src") == target) return;
highlight($this);
imgViewer.html(loader);
bigPic
.load(function(){
imgViewer.html($(this).fadeIn(250));
alert(caption);
})
.attr("src",target);
});
}
$(this).each(initGallery);
// interface fluide
return $(this);
};
// utilisation du plugin
$(document).ready(function() {
$(".thumbs").ben_galerie({
activeClass: "ssg_active",
activeTitle: "ben galerie : Photo en cours de visualisation",
loaderTitle: "ben galerie : Chargement en cours",
loaderImage: "images/loader.gif"
});
});
});
And here is a part of the html associated :
<div id="bloc_page">
<div id="contenu">
<div class="item">
<div class="galerie">
<div class="thumbs">
<div class="mini">
<li> <img alt="Description illus 1" src="images/galerie/illus/small/mini1.jpg" /></li>
<li> <img alt="Description illus 2" src="images/galerie/illus/small/mini2.jpg" /></li>
</div></div></div></div></div>
I'm thinking of using the title or the alt attribute, but I don't known how :/
Any tips or ideas will be fantastic.
Thanks guys !
you should use the alt attribute for the caption put it into a variable and call that variable in a caption element from you gallery. for example something like this
caption = $('img').attr("alt").text();
$('.whatever you call your caption element').text(caption);

use id attribute as reference or variable for tooltip

I am currently using this code .
However the text I wish to display must be in one line, and if there is a apostrophe ( ' ) in the text, it will not work anymore .
imgover(this, 'Text to display')
Is there a way to remplace the second variable of onmouseover by an id of a div so that it will display everything in the div please ?
Here is an example of the div :
<div id ="text1" >
<em><img class="floatLeft" src="images/F9979.jpg" alt="" />
TITRE DU FILM : Man of Steel
<br />
<br />
RESUME :
Film fantastique américain réalisé par Zack Snyder avec Henry Cavill, Amy Adams, Diane Lane
<br />
<br />
DUREE : 2H23
<br />
Un petit garçon découvre qu'il possède des pouvoirs surnaturels et qu'il n'est pas né sur la Terre. Plus tard, il s'engage dans un périple afin de comprendre d'où il vient et pourquoi il a été envoyé sur notre planète. Mais il devra devenir un héros s'il veut sauver le monde de la destruction totale et incarner l'espoir pour toute l'humanité...
</em>
</div>
I would like to remplace 'Text to display' from
imgover(this, 'Text to display')
by what's in the div (text1) so that at the place where there is the div ( tooltip) I will see the text and the image from the div ( text1).
I'm not really sure whether I understood your question properly but this should work. You need to put the value of the id tag of your html element in the parameter of getElementById
<script>
function imgover(img, tip) {
document.getElementById('text1').style.display = 'block';
document.getElementById('text1').innerHTML = tip;
document.getElementById('text1').style.left = img.offsetLeft + 'px';
}
function imgout() {
document.getElementById('text1').style.display = 'none';
}
</script>

Categories

Resources