connecté
Bonjour. Essayer ceci par exemple (retourne le premier li) :
const lis = ul.children[0];
console.log(lis);

Pour obtenir tous les <li> il faudra utiliser une boucle.

Votre code ne marche pas car vous utilisez l'API JavaScript servant à manipuler le DOM, alors qu'en fait vous manipulez un objet JavaScript qui n'a pas encore été ajouté à la page web.
Modifié par Olivier C (09 Dec 2022 - 12:57)
Excuse moi de ne pas avoir répondu plus tôt, j'étais parti quelques jours de chez moi.

Si une propriété est une liste d'éléments on n'a le choix que d'utiliser un champ avec des séparateurs ou faire une table auxiliaire.
Pour donner un exemple différent de mes "groupes d'utilisateurs" qui prêtent à confusion, prenons le cas d'une couleur: un objet peut avoir une ou plusieurs couleurs, et la même couleur peut s'appliquer à différents objets.
Dans un objet "cravate" on peut avoir un champ "couleurs" qui contiendra "bleu;rouge;vert", ce qui signifie que que les motifs de la cravate contiennent ces couleurs.
Mais si pour une autre raison j'ai besoin de retrouver toutes les cravates qui ont du rouge dans leurs couleurs, je suis amené à créer une table intermédiaire permettant d'indiquer que telle couleur et telle cravate sont "associées".
Pour autant on n'a pas besoin de créer une table "couleurs", sauf bien entendu on a d'autres besoins, auquel cas on pourra éventuellement la créer plus tard.

Pour le reste je suis d'accord que le champ "groupName" devrait plutôt s'appeler "groupID" en prévision du jour ou je serai amené à créer une table des groupes. Je vais regarder si je peux facilement faire cette modification dans mes applications. Comme elles ne sont pas nombreuses, je dois pouvoir corriger cette erreur.
Modifié par PapyJP (09 Dec 2022 - 11:43)
connecté
Bonjour,

Etant un peu débutant en js certaines choses sont encore un peu floues dans ma tête. Je vais essayer d'expliquer mon problème: je suis sur un exercice ou je récupère des données en json avec fetch, jusque là tout va bien, ensuite je boucle sur mes données pour créer une liste en HTML (à grand coup de createElement), là aussi ça va la liste apparait dans le DOM, en revanche lorsque je veux accéder à un de ces nouveaux éléments créé....rien. Je vais essayer d'être plus clair (code ci-dessous), lorsque je console.log mon ul il me le sort, mais pas les li crééent en js. J'aurai donc voulu récupérer toutes mes checkbox afin de toutes les checked (ou pas) d'un coup.
Ce que je ne comprend pas c'est qu'en inspectant mon ul en dépliant on voit bien les li, mais impossible de récupérer celles-ci. Je ne sais pas si j'ai été assez clair, mais si quelqu'un pourrait m'aiguiller sur ce comportement ce serai magnifique !
En vous remerciant,

Ma liste

<!DOCTYPE html>
<html lang="fr">
[...]
    <ul class="list-group">
     </ul>
[...]
</html>


Pour info, la fonction qui récupère les données

const wrapper = document.querySelector(".list-group");

async function fetchTodos() {
  const loader = document.createElement("p");
  loader.innerText = "Chargement ...";
  wrapper.append(loader);
  try {
    const r = await fetch(
      "https://jsonplaceholder.typicode.com/todos?_limit=5",
      {
        method: "GET",
        headers: {
          Accept: "application/json",
        },
      }
    );
    if (!r.ok) {
      throw new console.Error("Erreur serveur.");
    }

    const todos = await r.json();
    loader.remove();
    for (const todo in todos) {
      wrapper.prepend(createListTodo(todos[todo], Number(todo) + 1));
    }
  } catch (e) {
    loader.innerText = "Impossible de charger les articles.";
    loader.style.color = "red";
    return;
  }
}


Fonction pour créer mon li qui prend en paramètre un objet (todo) que je récupère du json et un indice (i) pour générer un id

function createListTodo(todo, i) {
  const li = document.createElement("li");
  li.setAttribute("class", "todo list-group-item d-flex align-items-center");

  const input = document.createElement("input");
  input.setAttribute("class", "form-check-input mb-1");
  input.setAttribute("type", "checkbox");
  input.setAttribute("id", `todo-${i}`);
  //   input.setAttribute("checked", `${todo.completed}`);
  li.appendChild(input);

  const labelInput = document.createElement("label");
  labelInput.setAttribute("class", "form-check-label ms-2");
  labelInput.setAttribute("for", `todo-${i}`);
  labelInput.innerText = `${todo.title}`;
  li.appendChild(labelInput);

  return li;


Quand j'inspecte tout cela

const ul = document.querySelector(".list-group");
console.log(ul);

const lis = ul.querySelectorAll("li");
console.log(lis);


Lorsque je console.log mon ul j'ai ceci
upload/1670530345-85253-ul.jpg
En revanche quand je console.log mes li, j'ai...rien, nodeList vide... et donc impossible de les sélectionner en js
upload/1670530423-85253-li.jpg

J'espère ne pas avoir été trop brouillon dans mon explication, si vous avez besoin de renseignement complémentaires n'hésitez pas à me demander !
Modifié par Shuppsy (08 Dec 2022 - 21:44)
Alors j'ai réussi à régler le problème en combinant le comportement normal (d'où le " //e.preventDefault(); ") avec du javascript; ça fonctionne sur Firefox/Chrome Windows/Android 8; si vous pouviez me faire des retour sur les autres plateformes Smiley ravi

Les autres lignes en commentaire ne règlent pas le problème.



(() => {
  document.querySelectorAll('a[href^="#"]').forEach((elem) => {
    elem.addEventListener('click', (e) => {
      //e.preventDefault();          
      // location.href = elem.getAttribute('href');
      
      var h = elem.getAttribute('href').replace('#', '');
         
      //var top = document.getElementById(h).offsetTop; //Getting Y of target element
      //window.scrollTo(0, top); 

      document.getElementById(h).scrollIntoView(); 

    });
  });
})()
 


https://stackoverflow.com/questions/68467475/lazy-loading-conflicting-with-scrollto-anchor-to-id-scroll-stops-halfway-throu
https://stackoverflow.com/questions/13735912/anchor-jumping-by-using-javascript
Modifié par negtrick (08 Dec 2022 - 17:18)
connecté
Pour la postérité (si le codepen est supprimé un jour), voici ce que peut donner le code (ton code fonctionne très bien niuxe, mais celui-ci sera plus simple à maintenir pour moi parce que je le comprend mieux d'emblée) :
const rangeMultithumb = (() => {
  document.querySelectorAll('.range-multithumb').forEach(range => {

    const [start, stop] = range.querySelectorAll('input')
    const output = range.querySelector('output')
    const step = Number(start.getAttribute('step'))
    let valStart = Number(start.value)
    let valStop = Number(stop.value)

    output.textContent = `${valStart}-${valStop}`
    
    function plus(){
      valStop = Number(stop.value)
      output.textContent = `${this.value}-${valStop}`
      stop.value = (valStop > Number(this.value)) ? valStop : (Number(this.value) + step)
    }

    function moins(){
      valStart = Number(start.value)
      output.textContent = `${valStart}-${this.value}`
      start.value = (valStart < Number(this.value)) ? valStart : (Number(this.value) - step)
    }

    start.oninput = plus
    start.onchange = plus

    stop.oninput = moins
    stop.onchange = moins

  })
})()

Modifié par Olivier C (07 Dec 2022 - 22:27)
connecté
Mathieuu a écrit :
start.oninput = stopPlus;
stop.oninput = stopMoins;
start.onchange = stopPlus;
stop.onchange = stopMoins;

A ben volà ! il était là le hic : j'avais essayé cette solution mais j'avais mis des parenthèses aux fonctions, comme ceci :
start.oninput = stopPlus();

Et ensuite je me perdais sur de faustes pistes de déboguage...

Merci beaucoup. C'est encore plus important pour moi de comprendre mon erreur que de trouver une solution.
Bonjour,

J'ai un site web avec un sommaire et différents chapitres.

J'utilise les balises <a id=#SOM-XX" href="#XX"> et <a id="XX" href="#SOM-XX"> pour permettre aux utilisateurs de faire le va-et-vient entre les titres du sommaire et les chapitres et sous-chapitres. Jusqu'à il y a peu cela fonctionnait bien.

Depuis une date indéterminée, sur Firefox, après un premier va-et-vien entre sommaire et chapitres, les liens depuis le sommaire ne renvoient pas exactement au chapitre concerné, mais légèrement plus haut... Smiley rolleyes
Le phénomène s'amplifie à mesure que l'on choisit un chapitre proche de la fin, par exemple le 5e.

Essayez par vous-mêmes: https://blog.patrick-kiri.mq/2019/02/connaissances-et-orientations-patrick_15.html#lapasfc

En revanche, tout fonctionne normalement sur Chrome.

Comment corriger ce problème ?
Salut,

En solution simple, au lieu de declarer des fonctions anonymes, je pense que tu peux déclarer des fonctions et les nommer puis les affecter aux events voulus, un truc dans le genre :

    function stopPlus(){
      valStop = Number(stop.value)
			output.textContent = `${this.value}-${valStop}`
      stop.value = (valStop > Number(this.value)) ? valStop : (Number(this.value) + step)
    }
    
    function stopMoins(){
      valStart = Number(start.value)
			output.textContent = `${valStart}-${this.value}`
      start.value = (valStart < Number(this.value)) ? valStart : (Number(this.value) - step)
    }
    
		start.oninput = stopPlus;

		stop.oninput = stopMoins;

		start.onchange = stopPlus;

		stop.onchange = stopMoins;
Salut,

ce qui change avec ton modèle ce n'est pas le nombre de requête à écrire mais le nombre de ligne impacté par la modification. Dans les 2 cas en gros la requête ça serait ça :

UPDATE Groups set groupName = "NouveauNom" 
WHERE groupName = "VieuxNom" 

Dans ton cas il y a autant de ligne à changer qu'il y a de gens dans le groupe que tu modifies.

Si tu avais une table pivot en plus, la modification du nom du groupe n'affecte plus qu'une seule ligne dans la table de groupe et cela ne change rien à ta table pivot.

Et le jour ou tu veux faire évoluer ta table groupe, tu peux rajouter des informations sans modifier ton code.
Ta suggestion d'utiliser le vieux groupName comme groupID, c'est pas mal de la bidouille aussi Smiley sweatdrop . Plus propre de basculer sur un vrai ID et de modifier la table pivot pour qu'elle utilises ton ID.
Bonjour,
En utilisant la propriété display:flex avec quelques paramètres, tu devrais obtenir un résultat plus satisfaisant. Cependant, si les formats de tes images sont très variés, ce ne sera sans doute pas aussi optimal que ce que tu pourrais obtenir avec du javascript du style https://masonry.desandro.com/

Pour le flex, ça devrait ressembler à ça, en enlevant le float:left des images.

<div class="container">
    <div class = image>
	<a href="img/cake.jpg"><img src="img/cake.jpg"></a>
    </div>
    <div class = image>
	<a href="img/donuts.jpg"><img src="img/donuts.jpg"></a>
    </div>
    <div class = image>
	<a href="img/luciie.jpg"><img src="img/luciie.jpg"></a>
    </div>
...
</div>

.container { 
    display:flex; 
    flex-wrap: wrap; /* Permet le retour à la ligne*/
    justify-content: space-between;
    align-items: center; /* Pour l'alignement vertical */
}

Pour simplifier, tu devrais pouvoir enlever les <div class="image">
Bon, je n'ai pas testé, donc, à ajuster.
De la doc ici:
https://www.alsacreations.com/outils/lire/1719-flexbox-cheat-sheet-pense-bete.html
et ici:
https://css-tricks.com/snippets/css/a-guide-to-flexbox/
Modifié par loicbcn (07 Dec 2022 - 12:41)
Bonjour,

J'essaie d'aligner un grand nombre d'images sur ma page. Elles s'alignent bien horizontalement, mais il y a de gros espaces verticaux et j'aimerais que mes images soient collées... (image à l'appui)

upload/1670411441-85250-capturedancran2022-12-0712044.png

Voici mon code :

HTML (je montre que le début parce-que c'est toujours la même chose):

<div class = image>
	<a href="img/cake.jpg"><img src="img/cake.jpg"></a>
</div>

<div class = image>
	<a href="img/donuts.jpg"><img src="img/donuts.jpg"></a>
</div>

<div class = image>
	<a href="img/luciie.jpg"><img src="img/luciie.jpg"></a>
</div>


CSS (pareil je montre que la partie image) :

img{
	width:15%;
}
.image img{
	transition: all 0.3s ease;
	float: left;
	margin: 2px;
}

.image:hover img {
	transform:scale(1.25);
}


Voila voila merci à ceux qui m'aideront Smiley smile
Modifié par Brocoli (07 Dec 2022 - 12:11)
Idem pour moi: Firefox, dernière version (win), tout fonctionne une fois tous les scripts chargés.

Bongota a écrit :
GuppY, je ne connaissais pas, ça a l'air pas mal, et sans BBD.
Question performances et sécurité, c'est mieux que Wordpress ?


Bonjour, guppy va fêter ses 20ans à la fin du mois. Perso, je l'avais tester il y a longtemps (2006) et revenu dessus il y a quelques mois.
Mon impression est resté la même, coté installation puis administration : c'est pas très clair ni intuitif.

Coté performance, on économise d'un coté la connexion à une base de donnée et multiplie de l'autre l’accès en lecture à des fichiers . Pas de requête SQL . Pour des sites sans trop de contenus ce n'est probablement pas significatif, cependant certains hébergeurs gratuits vont jusqu’à interdire ou désactiver des pages persos utilisant des CMS sans bdd.

Coté sécurité, Comme c'est un CMS peut présent, il(ou ses plugins) n'est pas systématiquement étudié et ciblé par les hackers.

Ce n'est pas, à mon humble avis, une alternative à wordpress et probablement trop pour un simple blog.

Enfin, pour les thèmes, comme tout CMS que l'on maitrise, la création de thème (skin) permet de faire de très bel pages. Il ne semble pas y avoir de collection de thème dispo et assez peu de plugins, il faut donc savoir mettre les mains dans le cambouis pour en tirer le meilleur. C'est malheureusement le soucis de tout CMS ayant une communauté réduite. Le mieux pour te faire une idée, c'est de l'installer et d'aller faire un tour sur leurs pages et forums Smiley cligne .

cdt
Modifié par gcyrillus (07 Dec 2022 - 12:30)
il n'y a rien de compliqué. La base de ton code est la même. Le code que je t'ai présenté, ce ne sont que des pirouettes syntaxiques.

ce code

const params = {
    inputMin,
    inputMax,
    // ....
}


est l'équivalent de :

const params = {
    inputMin: inputMin,
    inputMax: inputMax,
    // ....
}

et celui ci

let eventsInputs = {
    change_min(e, params){
        let currentTargetValue = e.currentTarget.value;
        params.valStop = Number(params.inputMax.value)
        params.output.textContent = `${currentTargetValue}-${params.valStop}`
        params.inputMax.value = (params.valStop > Number(currentTargetValue)) ? params.valStop : (Number(currentTargetValue) + params.step)
    },
    // ...
};

est l'équivalent de

let eventsInputs = {
    change_min: (e, params) =>{
        let currentTargetValue = e.currentTarget.value;
        params.valStop = Number(params.inputMax.value)
        params.output.textContent = `${currentTargetValue}-${params.valStop}`
        params.inputMax.value = (params.valStop > Number(currentTargetValue)) ? params.valStop : (Number(currentTargetValue) + params.step)
    },
    // ...
};

Modifié par niuxe (07 Dec 2022 - 11:49)
connecté
Ouf ! il va falloir que je décortique... (édit : ton code est nettement plus lisible pour moi si je commence par la deuxième partie)

Je te remercie.

Je vais récupérer tel et tel concept que je comprends et les intégrer petit à petit pour m'approprier le code. Parce que, hormis ma question d'origine, il y a des trucs qui m'intéressent et auxquels je n'avais pas pensé, par exemple :
const [inputMin, inputMax] = range.querySelectorAll('input')

Modifié par Olivier C (07 Dec 2022 - 07:12)
Salut,

Je t'invite à lire ceci [^1]

const rangeMultithumb = (() => {
    let eventsSelect = ['input', 'change'];
    let eventsInputs = {
        change_min(e, params){
            let currentTargetValue = e.currentTarget.value;
            params.valStop = Number(params.inputMax.value)
            params.output.textContent = `${currentTargetValue}-${params.valStop}`
            params.inputMax.value = (params.valStop > Number(currentTargetValue)) ? params.valStop : (Number(currentTargetValue) + params.step)
        },
        change_max(e, params){
            let currentTargetValue = e.currentTarget.value;
            params.valStart = Number(params.inputMin.value)
            params.output.textContent = `${params.valStart}-${currentTargetValue}`
            params.inputMin.value = (params.valStart < Number(currentTargetValue)) ? params.valStart : (Number(currentTargetValue) - params.step)
        }
    };


    document.querySelectorAll('.range-multithumb').forEach(range => {
        const [inputMin, inputMax] = range.querySelectorAll('input') 
        const params = {
            inputMin,
            inputMax,
            output : range.querySelector('output'),
            step : Number(inputMin.step),
            valStart : Number(inputMin.value),
            valStop : Number(inputMax.value),
        }

        params.output.textContent = `${params.valStart}-${params.valStop}`;
        // @see  https://stackoverflow.com/questions/8796988/binding-multiple-events-to-a-listener-without-jquery
 
        eventsSelect.forEach(event_type =>{
            inputMin.addEventListener(event_type, e => eventsInputs.change_min(e, params))
            inputMax.addEventListener(event_type, e => eventsInputs.change_max(e, params))
        });
    })
})()


Tu as le codepen ici

[^1] peut être, on peut améliorer.
Modifié par niuxe (07 Dec 2022 - 00:19)
Bonjour,
Avec Firefox j'ai un souci, lors d'une consulation d'un diaporama je n'ai pas l'affichage des flèches pour visualiser l'ensemble des photos et cela à 95%. Par contre avec Google et Safari aucun problème.
Le site concerné est https://iso.espace63.fr voir le menu La vie de Clé / Evénements
Merci de me dire pour quelle raison sur Firefox il faut dans la majorité des cas visualiser une image puis effectuer un retour en arrière pour sélectionner une autre image alors que sur d'autres navigateurs j'ai systématiquement l'aide des flèches latérales pour visualiser toutes les images.

Cordialement
Robin
Bonjour,

On a bien avancé mais il reste un problème.

overflow: hidden sur #recherche n'est pas ergonomique, il faut une barre de défilement horizontal pour voir la partie cachée.

J'ai enlevé cette propriété.
Bonne nouvelle, Chrome et Edge font exactement ce qu'il faut faire : texte fluide et barre de défilement horizontal..
Par contre Firefox affiche la barre de défilement mais bouffe le texte.

J'ai essayé overflow: scroll
Firefox rend alors le texte fluide mais sans afficher la barre de défilement.
Et trop bizarrement Chrome et Edge n'affichent plus de barre de défilement.horizontal, mais à, droite une barre grise verticale qui n'est pas une barre de défilement et doublonne avec la barre de la fenêtre...
Dans mon modèle actuel si je voulais changer le nom d’un groupe — ce qui a peu de chances d’arriver car ces noms de groupes sont stables depuis au moins 12 ans — il suffirait d’une seule requête pour le faire.
Si je voulais avoir d’autres propriétés que le nom (par exemple afficher un nom différent de groupId) il suffirait de créer une nouvelle table dont l’index serait le groupID. Je n’aurais rien à modifier au code actuel, car si on crée une nouvelle propriété c’est évidemment du code nouveaux qui serait nécessaire pour l’exploiter.
connecté
Bonsoir à tous,

Dans la suite de ce topic. J'ai réussi à obtenir le comportement attendu grace à deux écouteurs d'événement. Le problème étant que je duplique mon code :
input[0].oninput = function() {
  valStop = Number(input[1].value)
  output.textContent = `${this.value}-${valStop}`
  input[1].value = (valStop > Number(this.value)) ? valStop : (Number(this.value) + step)
}

input[0].onchange = function() {
  valStop = Number(input[1].value)
  output.textContent = `${this.value}-${valStop}`
  input[1].value = (valStop > Number(this.value)) ? valStop : (Number(this.value) + step)
}

Comment factoriser ces deux appels à la même fonction que je duplique ici (J'ai tenté plusieurs solutions que je passe sous silence pour éviter de vous disperser).

Le code dans son contexte : CodePen
Modifié par Olivier C (07 Dec 2022 - 05:39)
PapyJP a écrit :
Je ne vais tout de même pas créer une table des groupes du genre

GoupId      GroupName
group1        group1
group2       group2
……….

En fait, tu n'as pas le choix si tu souhaite respecter la théorie derrière les modèles de données SQL. Et c'est pas pour rien. Dans ton cas, la valeur GroupName va apparaître autant de fois qu'il y a de membres dans le groupe. Si tu souhaite modifier le nom du groupe c'est toute ces lignes que tu devras modifier à la fois. Si tu respecte la règle, c'est qu'une seule entrée à modifier. Et c'est juste un exemple parmi d'autres.
Modifié par Anymah (05 Dec 2022 - 17:17)
Je suis allé chez Auchan et chez Boulanger, j'ai demandé des conseils aux vendeurs et tous m'ont dit de lire ce qui était écrit sur le panneau annonçant le produit exposé. Autrement dit, ils m'ont presque dit "démerde-toi avec ce qui est écrit dessus". Plus jamais je n'achèterai quoi que se soit en grande surface ! Je préfère de loin acheter chez Amazon ou LDLC, je sais que j'aurai des conseils et des explications avec leur tchat en ligne.
Il n’y a pas de "table des groupes" car les groupes n’ont aucune autre information que leur nom de groupe.
Ma table est donc bien ce que tu appelles une "table intermédiaire" sauf que l’identifier de la deuxième table suffit. Je ne vais tout de même pas créer une table des groupes du genre

GoupId      GroupName
group1        group1
group2       group2
……….

pour faire joli.
Bien sûr si un jour j’ai besoin d’informations supplémentaires pour les groupes je ferai une table de plus.
connecté
Bonjour à tous,

Je tente de créer ma propre solution de curseurs pour deux mutlipouces : CodePen.

J'aimerais que le curseur minimum ne dépasse jamais le curseur maximum et vice versa.

J'ai donc fait ceci (vous trouverez l'ensemble du contexte JS sur le Pen) :
input[1].value = (valStop > Number(this.value)) ? valStop : (valStop + step)

et :
input[0].value = (valStart < Number(this.value)) ? valStart : (valStart - step)

Celà ne fonctionne que partiellement : si l'on dépasse le curseur trop vite on a tout de même un dépassement. Comment puis-je résoudre ce problème ?
Hello Papy,

Selon moi ton modèle de données est incorrect. Si un membre peut appartenir à plusieurs groupes et qu'un groupe peut contenir plusieurs membre, tu es dans une relation de type "many-to-many" (comme dans ton précédent sujet). Il te manque théoriquement une table intermédiaire et cela change complètement requête.

Je commencerai par là à ta place Smiley smile
50 Dernières réponses