Why eventListener in JavaScript not displaying? - javascript

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

Class Method As Event Handlers Javascript

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()

Odoo12ce objet this not recognised inside of setinterval function

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.

How to display information relative to image clicked using pokemon API?

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){
...
});
});

Javascript : How access to a local function from global code

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.

innerHTML not printing anything

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>";

Categories