I have been struggling for hours with a simple addEventListener and I really don't understand why.
Find attached my JS code. I am trying to create a cart. I store in a localstorage the products I want to buy. Then I display it on a test page to see if my code was working.
I add a class to each line of the array using i variable.
Then I try to do a simple alert when I click on the link I created with the class. The goal is then to add a link to remove this article from the cart.
I get no error, but the alert does not display.
Plus, when I do
alert(querySelector('.article' + i + '').innerHTML);
it works perfectly, but with the code below it does not :
let url = window.location.search;
let searchUrl = new URLSearchParams(url);
if (searchUrl.has("produit")) {
//Requête fetch
fetch('http://localhost:3000/api/cameras')
.then(function(response) {
return response.json();
})
.then(function(produit) {
produit.forEach(element => {
// Récupération url, conversion string et mise en forme pour recherche
let urlProduit = String(searchUrl.getAll("produit"));
urlProduit = urlProduit.replace("-", " ");
//Affichage du produit
if (urlProduit == element.name) {
document.getElementById('content').innerHTML += '' + element.name + '';
document.getElementById('content').innerHTML += '<p>' + element.description + '</p>';
document.getElementById('content').innerHTML += '<p>' + element.price + '</p>';
document.getElementById('content').innerHTML += ' Ajouter au panier ';
// Gestion du panier
document.getElementById('ajoutPanier').addEventListener('click', function() {
if (localStorage.getItem("panier") == null) {
let panier = {};
panier.produits = [];
localStorage.setItem('panier', JSON.stringify(panier));
alert("Panier créé");
} else {
let panier = JSON.parse(localStorage.getItem("panier"));
panier.produits.push(element);
localStorage.setItem("panier", JSON.stringify(panier));
alert("Ajouté au panier");
}
});
}
})
})
}
//Affichage du panier
if (!localStorage.getItem("panier")) {
document.getElementById('panier').innerHTML += '<p> Votre panier est vide</p>';
}
else {
//Vider le panier
document.querySelector('#panier h2').innerHTML += ' (Vider) ';
document.querySelector('.viderPanier').addEventListener('click', function() {
alert("Panier vidé");
});
let i=0;
let panier = localStorage.getItem("panier");
panier = JSON.parse(panier);
console.log(panier); // A supprimer
panier.produits.forEach(element => {
document.getElementById('panier').innerHTML += '<p><strong>' + element.name + '</strong> - ' + element.price + ' € - Retirer du panier - Position' + i + ' </p>';
document.querySelector('.article' + i + '').addEventListener('click', function() {
console.log("ok");
alert("ok");
})
i++;
})
document.getElementById('panier').innerHTML += 'Passer la commande';
}
<!DOCTYPE html>
<html lang="fr" dir="ltr">
<head>
<meta charset="utf-8">
<title>Page produit</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id="content">
Retour à l'acceuil<br>
<h2>Votre produit</h2>
</div>
<div id="panier">
<h2>Votre panier</h2>
</div>
<script src="produit.js" charset="utf-8"></script>
</body>
</html>
I just started JavaScript and eventListener perfectly worked so far. I know it is not the best solution for what I want to create, I am open to tips from you guys.
Related
This is my assignment : " the modif_function, view_function and add_function methods are launched when the corresponding ACTION button is clicked. The corresponding buttons are only visible if the methods have been supplied by the user by a function. "
I've been trying for many hours without success.
class Table {
id_zone = "";
class_table = "";
data = "";
header = "";
class_modif = "";
class_supp = "";
class_vue = "";
icone_modif = "";
icone_supp = "";
icone_vue = "";
constructor(
id_zone = "",
class_table = "",
data = "",
header = "",
class_modif = "",
class_supp = "",
class_vue = "",
icone_modif = "",
icone_supp = "",
icone_vue = ""
) {
this.id_zone = id_zone;
this.class_table = class_table;
this.data = data;
this.header = header;
this.class_modif = class_modif;
this.class_supp = class_supp;
this.class_vue = class_vue;
this.icone_modif = icone_modif;
this.icone_supp = icone_supp;
this.icone_vue = icone_vue;
}
generer = () => {
if (this.id_zone == "") {
throw new Error(
"Pour générer une table, il faut préciser la proprieté id_zone."
);
} else {
var table =
"<table class='" +
this.class_table +
"'>" +
"<tbody>" +
"<tr>" +
"<th>" +
donneesHeader[0] +
"</th>" +
"<th>" +
donneesHeader[1] +
"</th>" +
"<th>" +
donneesHeader[2] +
"</th>" +
"</tr>" +
"<tr></tr>";
$(this.data).each(function () {
table +=
"<tr>" +
"<td>" +
$(this)[0] +
"</td>" +
"<td>" +
$(this)[1] +
"</td>" +
"<td>" +
"<button type='button' class='" +
tableFils.class_vue +
" " +
tableFils.icone_vue +
"' " +
"value=" +
$(this)[0] +
"*" +
$(this)[1] +
"></button>" +
"<button type='button'" +
" class='" +
tableFils.class_modif +
" " +
tableFils.icone_modif +
"' value=" +
$(this)[0] +
"*" +
$(this)[1] +
"></button>" +
"<button type='button' class='" +
tableFils.class_supp +
" " +
tableFils.icone_supp +
"' value=" +
$(this)[0] +
"*" +
$(this)[1] +
">" +
"</button></td>";
});
table += "</tr></tbody></table>";
$("#zoneTable").html(table);
}
};
fonction_modif = () => {};
//What to write here
fonction_supp = () => {};
fonction_vue = () => {};
}
function supprRegion() {
alert("hello world 1");
}
function modifRegion() {
alert("hello world 2");
}
function vueRegion() {
alert("hello world 3");
}
let donnees = [
[1, "Ain"],
[2, "Aisne"],
[3, "Allier"],
[4, "Alpes-de-Haute-Provence"],
[5, "Hautes-Alpes"],
[6, "Alpes-Maritimes"],
[7, "Ardèche"],
[8, "Ardennes"],
[9, "Ariège"],
[10, "Aube"],
[11, "Aude"],
[12, "Aveyron"],
];
let donneesHeader = ["Code", "Nom du département", "Actions"];
let tableFils = new Table();
$(document).ready(function () {
tableFils.id_zone = $("#zoneTable");
tableFils.class_table = "table table-dark table-hover";
tableFils.data = donnees;
tableFils.class_modif = "mod_region";
tableFils.class_supp = "supp_region";
tableFils.class_vue = "vueRegion";
tableFils.icone_modif = "btn btn-info btn-sm fas fa-pencil-alt fa-sm";
tableFils.icone_supp = "btn btn-danger btn-sm fas fa-trash-alt fa-sm";
tableFils.icone_vue = "btn btn-success btn-sm fas fa-eye fa-sm";
tableFils.fonction_modif = modifRegion;
tableFils.fonction_supp = supprRegion;
tableFils.fonction_vue = vueRegion;
tableFils.generer();
});
HTML:
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title></title>
<!-- CDN CSS de BOOTSTRAP -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css">
<!-- CDN de FONTAWSOME pour les ICONES -->
<link rel="stylesheet" href="https://pro.fontawesome.com/releases/v5.10.0/css/all.css" integrity="sha384-AYmEC3Yw5cVb3ZcuHtOA93w35dYTsvhLPVnYs9eStHfGJvOvKxVfELGroGkvsg+p" crossorigin="anonymous" />
</head>
<body>
<div id="zoneTable"></div>
<!-------------------------------------
CDN JS pour BOOTSTRAP
--------------------------------------->
<!-- jQuery library -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<!-- Popper JS -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<!-- Latest compiled JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js"></script>
<!-------------------------------------
Nos fichiers JS
--------------------------------------->
<script src="assets/main.js">
</script>
</body>
</html>
So, when there's a click on the modif, supp or vue icons, I get a simple alert.
But I cannot change this : " fonction_modif = modifRegion; "
Delete this:
fonction_modif = () => {};
//What to write here
fonction_supp = () => {};
fonction_vue = () => {};
And add this to properties of the class:
fonction_modif = null;
fonction_supp = null;
fonction_vue = null;
Now, you already can assign a funtion to the properties of the tableFils object, and type the call inside class code, example, as onclick inside a html element of generer function:
this.fonction_modif()
I working with odoo12ce and have some problems writting a new widget
My new widget shows some data and after 3 second it should disappear
start: function () {
var texto = ""
texto += "<ul>"
this.valor.forEach(element => {
texto += "<li>" + element.cant + ' ' + element.type + "</li>"
});
texto += "</ul>"
this.$el.append(texto);
setTimeout( function(){
this.$el.empty();
}, 3000);
},
And I got the error: Cannot read property 'empty' of undefined
Outside the function the object works fine but inside it is not recognised. What could I do to solve it??
Thanks in advance
you just need to add this to context of the setTimeout. so your code would be something like the following:
start: function () {
var self = this;
var texto = ""
texto += "<ul>"
this.valor.forEach(element => {
texto += "<li>" + element.cant + ' ' + element.type + "</li>"
});
texto += "</ul>"
this.$el.append(texto);
setTimeout( function(){
self.$el.empty();
}, 3000);
},
don't hesitate to let us know if it is working or not.
I'm trying to get and display the image and information of a clicked pokemon from pokemon API
HTML code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js">
</script>
<script src="pokedex2.js"></script>
<link rel="stylesheet" href="pokedex2.css">
<title>Pokedex v 2.0</title>
</head>
<body>
<div id="all">
<div id="pokemon">
</div>
<div id="chosen">
</div>
</div>
</body>
</html>
JavaScript
$(document).ready(function(){
for(i = 1; i <=151; i ++){
$("#pokemon").append("<img id=pokepic" + i + "
src='http://pokeapi.co/media/img/" + i +
".png'>");
}
var clicked = false;
$("img").click(function(){
clicked = true;
console.log(this);
if(clicked){
$.get("http://pokeapi.co/api/v1/pokemon/" + i +"/", function(data){
var str = "";
str += "<h4>Types</h4>";
str += "<ul>";
var str2 = "";
str2 += "<h4>height</h4>";
str2 += "<ul>";
var str3 = "";
str3 += "<h4>weight</h4>";
str3 += "<ul>";
for(i = 0; i < data.types.length; i ++){
str += "<li>" + data.types[i].name + "</li>";
}
str2 += "<li>" + data.height + "</li>";
str3 += "<li>" + data.weight + "</li>";
str += "</ul>"
str2 += "</ul>"
str3 += "</ul>"
$("#chosen").html(str + str2 + str3); }, "json");
}
else{
clicked = false;
}
})
});
At the moment, the only information being brought up are for the first 3 pokemon in the list, not for the pokemon that was clicked. I need to find the information associated with the clicked pokemon, like a pokedex.
I included console.log to show that whichever image is clicked, the picture, and pokepic ID number associated with that image appear in the console. Instead what I need is for the image and stats associated with each image to appear in the div labeled chosen
Your click event uses the i variable defined in your for loop. Since the function inside the click is always called after the loop is done, i is always 152. You need to read the current pokemon from your click event:
$('img').on('click', function(e){
var pokemonId = e.target.id.split('pokepic')[1];
$.get("http://pokeapi.co/api/v1/pokemon/" + pokemonId +"/", function(data){
...
});
});
I have a function inside of an immediately invoked function expression and I want to be able to access that function globally without lexically scoping it that way.
How can I access this "private" function through a namespace called "App"?
indew.html:
<html>
<head>
<meta charset="utf-8">
<title>Test</title>
<script src="filtering.js"></script>
</head>
<body>
<article>
<p>
Computer graphics is widespread today. Computer imagery is found on televi
surfaces, illumination sources, and so forth, perhaps with a dynamic (time) component".[3]
</p>
</article>
<section id="result"></section>
<script>
App.showOccurenceFiltering(); // here is my wrong call
</script>
</body>
</html>
js script :
var App = (function () {
function showOccurenceFiltering() {
"use strict";
var filteredWordsArray = filtering(),
resultView = "<ol>";
for (var i = 0; i < filteredWordsArray.length; i++) {
var partWord = filteredWordsArray[i].substring(0, filteredWordsArray[i].indexOf(" ")), // de 0 jusqua l espace : la partie mot
partNumber = filteredWordsArray[i].substring(filteredWordsArray[i].indexOf(" ") + 1); // de l'espace à la fin : la partie number
resultView += "<li>" + partWord + " (" + partNumber + ")</li>";
}
resultView += "</ol>";
document.getElementById('result').innerHTML = resultView;
}
}(App));
so i got an error of a miss call like shows the capture :
how should i resolve my problem ??
You'll need to expose the function to the global scope. You can do this with a namespace, like this:
(function () {
function showOccurenceFiltering() {
"use strict";
var filteredWordsArray = filtering(),
resultView = "<ol>";
for (var i = 0; i < filteredWordsArray.length; i++) {
var partWord = filteredWordsArray[i].substring(0, filteredWordsArray[i].indexOf(" ")), // de 0 jusqua l espace : la partie mot
partNumber = filteredWordsArray[i].substring(filteredWordsArray[i].indexOf(" ") + 1); // de l'espace à la fin : la partie number
resultView += "<li>" + partWord + " (" + partNumber + ")</li>";
}
resultView += "</ol>";
document.getElementById('result').innerHTML = resultView;
}
// Prepare a "dummy" object
var obj = {};
// Attach the private function to this object
obj.showOccurenceFiltering = showOccurenceFiltering;
// Attach the dummy object to the global scope in a controlled namespace:
window.App = obj;
}());
Then you can access the function like this:
App.showOccurenceFiltering();
You could do the following:
var App = (function(){
var obj = {};
obj.showOccurenceFiltering = function() {
"use strict";
var filteredWordsArray = filtering(),
resultView = "<ol>";
for (var i = 0; i < filteredWordsArray.length; i++) {
var partWord = filteredWordsArray[i].substring(0, filteredWordsArray[i].indexOf(" ")), // de 0 jusqua l espace : la partie mot
partNumber = filteredWordsArray[i].substring(filteredWordsArray[i].indexOf(" ") + 1); // de l'espace à la fin : la partie number
resultView += "<li>" + partWord + " (" + partNumber + ")</li>";
}
resultView += "</ol>";
document.getElementById('result').innerHTML = resultView;
}
return obj;
}());
Your App variable remains undefined because the Immediately Invoked Function Expression does not return a value.
Instead, define App as an object literal, as follows:
var App = {
showOccurenceFiltering: function() {
"use strict";
var filteredWordsArray = filtering(),
resultView = "<ol>";
for (var i = 0; i < filteredWordsArray.length; i++) {
var partWord = filteredWordsArray[i].substring(0, filteredWordsArray[i].indexOf(" ")), // de 0 jusqua l espace : la partie mot
partNumber = filteredWordsArray[i].substring(filteredWordsArray[i].indexOf(" ") + 1); // de l'espace à la fin : la partie number
resultView += "<li>" + partWord + " (" + partNumber + ")</li>";
}
resultView += "</ol>";
document.getElementById('result').innerHTML = resultView;
}
};
Now your call will be valid.
Im trying some stuff for an exam and I can't make it work. It's really simple and i can't understand why is not working.
<!DOCTYPE html>
<html>
<head>
<title>Exercici 2</title>
<script type="text/javascript">
//rep 2 paràmetres d'entrada i els suma
function suma(a, b) {
alert(arguments.length);
//donaria undefined, ja que no existeix el argument amb índex 2, tindria que ser [1]
alert(arguments[2]);
//3 + 5 = 8
return a + b;
}
var result = suma(3,5);
document.getElementById("result").innerHTML += "<strong>Suma</strong>: 3 + 5 = " + result + "<br>";
</script>
</head>
<body>
<div id="result">
</div>
</body>
</html>
I know alert(arguments[2]); will show undefined.
Issue is you are calling function before DOM is rendered. So result is not available. Move your script after body.
<html>
<head>
<title>Exercici 2</title>
</head>
<body>
<div id="result">
</div>
</body>
<script type="text/javascript">
//rep 2 paràmetres d'entrada i els suma
function suma(a, b) {
//3 + 5 = 8
return a + b;
}
var result = suma(3, 5);
document.getElementById("result").innerHTML += "<strong>Suma</strong>: 3 + 5 = " + result + "<br>";
</script>
</html>
Necesitas un onload para que funcione pues llamas el getElement By Id, antes de que exista el elemento y no tiene sentido. Ademas tu salida debe ser un string.
You need a "onload" function for this case, because you declare your getElemetnById before the element, also your output in your function should be a string.
<script type="text/javascript">
//rep 2 paràmetres d'entrada i els suma
function suma(a, b) {
//a = argumento 0, b = argumento 1
return (a + b).toString();
}
//estas ejecutando esto, sin antes existir el id="result", por tanto debes esperar
// aque primero se cree, y luego ejecutar, eso se hace añadiendo esto:
window.onload = function(){ //espera a que todos los elements html se creen.
var result = suma(3,5);
document.getElementById("result").innerHTML += "<strong>Suma</strong>: 3 + 5 = " + result + "<br>";
}
</script>
When working with Sums, it is advisable to add parseInt,
this way you can also add var result = suma('3', 5); and it will return 8, if you dont have the parseInt and you parse a string '3' it will concat it and will return 35
function suma(a, b) {
//3 + 5 = 8
return parseInt(a) + parseInt(b);
}
var result = suma(3, 5);
document.getElementById("result").innerHTML += "<strong>Suma</strong>: 3 + 5 = " + result + "<br>";