11521 sujets

JavaScript, DOM et API Web HTML5

Pages :
(reprise du message précédent)

Bonjour,

<tr>
<td><input type="radio" name="super" value="COMTFV006SM-D" id="ACOMTFV006SM-D"  /></td>
<td>6 fibres, OS2 (9 / 125), Str. serr&eacute;e &gt;&gt; <input type="text" size="4" name="unit[COMTFV006SM-D]" id="UCOMTFV006SM-D" /> m</td>
</tr>


J'ai essayé cela :

const tex = document.querySelectorAll ('input[type="text"]');

for (let i = 0; i < tex.length; i++)
{	
tex[i].addEventListener('click', function ()
{
const id_radio = this.parentNode.parentNode.children.children.id;
document.getElementById (id_radio).checked=true;
}
);

}


Ne marche pas.

Voyez-vous où est l'erreur ?
Modifié par boteha_2 (09 Aug 2020 - 14:28)
Salut,

Voilà deux solutions qui marchent (si le but est bien de checker le bouton radio relié à l'input texte) :


const tex = document.querySelectorAll('input[type="text"]');

// Avec forEach
tex.forEach(element => {
    element.addEventListener('click', () => {
        const idRadio = element.parentNode.parentNode.querySelector('input[type=radio]').id;
        document.getElementById(idRadio).checked = true;
    });
});

// Avec for ... of
for (const element of tex) {
    element.addEventListener('click', () => {
        const idRadio = element.parentNode.parentNode.querySelector('input[type=radio]').id;
        document.getElementById(idRadio).checked = true;
    });
}


Je préfère utiliser forEach ou for ... of car ça donne un code plus lisible. Mais après chacun ses goûts Smiley langue
Modifié par Wazazaby (09 Aug 2020 - 15:41)
MERCI.

L'élément clé de ton code est :

element.parentNode.parentNode.querySelector('input[type=radio]').id;


Autrement j'essaye de produire un code compatible IE, ce qui d’ailleurs est peut-être idiot.

tex.forEach(element => n'est pas compatible IE à ma connaissance.
for (const element of tex) je ne sais pas, je vais essayer.

avec cette boucle on est sûr que cela fonctionne avec IE.

const tex = document.querySelectorAll ('table.compcab input[type=text]');

if (tex.length > 0)
{
for (let i = 0; i < tex.length; i++)
{	
tex[i].addEventListener('click', function ()
{
const idRadio = this.parentNode.parentNode.querySelector('input[type=radio]').id;
document.getElementById (idRadio).checked=true;
}
);
}
}
forEach est compatible avec IE 9+, for ... of n'est compatible avec aucune version d'IE (tu peux regarder sur ces 2 liens : https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/Array/forEach, https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Instructions/for...of )

Edit : pour forEach, c'est surement la syntaxe de l'arrow function qui bloque avec IE ->

text.forEach(function(element) {
    // code
});

Ce code devrait être valide
Modifié par Wazazaby (09 Aug 2020 - 16:35)
Sur la version d'IE que j'utilise pour mes tests ni for ni foreach ne fonctionnent.

j'ai testé tes deux scripts, les deux fonctionnent parfaitement sur Firefox ou Chrome.

Je n'arrive même pas à trouver quelle version d'IE j'utilise, elle est de 2016, je suppose donc que c'est la dernière.

Je reconnais que c'est assez idiot de créer un indice quand on peut s'en passer mais si c'est le code passe-partout je me sens obligé.

Autrement j'avais un autre problème très proche que j'ai résolu grâce à ce que tu m'as proposé : l'association de parentNode et querySelector.

Cette fois j'ai un ou plusieurs SELECT dans la page.
L'objectif est de donner le focus au submit quand l'utilisateur sélectionne une option dans le select.

<p><select name="ssg[B1]">
<option value="tou" selected="selected">123 produits</option>
<option value="*rph">Rallonge USB active, A ou C, en 3.x</option>
<option value="*rpi">Rallonge USB active, A, en 2.0</option>
</select><input type="submit" id="aB1" value="Voir" /></p>

<p><select name="ssg[B7]">
<option value="tou" selected="selected">100 produits</option>
<option value="*awr">Convertisseur USB vers Mini-DisplayPort</option>
<option value="*aww">USB vers plusieurs formats</option>
</select><input type="submit" id="aB7" value="Voir" /></p>



var ssg = document.getElementsByTagName ('select');

if (ssg.length > 0)
{
	
for (let i = 0; i < ssg.length; i++)
{
	
ssg[i].addEventListener ('change', function ()
{
this.parentNode.querySelector('input[type=submit]').focus ();

}
);
}
}


Cela marche très bien.

Je n'ai plus besoin d'un id dans l'input type="submit".

Une alternative serait de récupérer le name du select, puis de récupérer la clé de ssg[B7], ce qui permet de cibler l'élément id="aB7".

Je ne sais pas si cette alternative est meilleure et accessoirement je ne sais pas comment récupérer B7 dans ssg[B7].
Modifié par boteha_2 (09 Aug 2020 - 16:56)
Modérateur
bonsoir,
pour la boucle avec let ,regarde le dernier post de : https://forum.alsacreations.com/topic-5-87089-1-Resolu-Introduire-un-settimeout-dans-une-boucle.html , où il y a une façon de garder IE11 dans le jeux .
Cela donnerait :
for (let i = 0; i < ssg.length; i++) {
  (function (index) {
    //IE11 fix : parceque let se laisse aller ...
    ssg[index].addEventListener("change", function () {
      this.parentNode.querySelector("input[type=submit]").focus();
    });
  })(i); //IE11 fix // fermeture de la fonction interne permettant de garder le fil dans IE
}

.. si j'ai compris la question Smiley smile
Modifié par gcyrillus (09 Aug 2020 - 23:04)
Bonsoir gcyrillus,

(i); //IE11 fix // fermeture de la fonction interne permettant de garder le fil dans IE


Merci, c'est très intéressant.
Bonjour,

Je reviens vers vous avec un nouveau problème d'externalisation.


<td><input type="radio" name="super" value="6-OS1-S-EXT-DG" id="A6-OS1-S-EXT-DG--824--6" /></td><td>6 fibres, OS1 (9 / 125), Str. serr&eacute;e &gt;&gt; <input type="text" size="4" name="unit[6-OS1-S-EXT-DG]" id="U6-OS1-S-EXT-DG" /> m</td>

<td><input type="radio" name="super" value="24-OS1-L-EXT-AD" id="A24-OS1-L-EXT-AD--824--24" /></td><td>24 fibres, OS1 (9 / 125), Str. libre &gt;&gt; <input type="text" size="4" name="unit[24-OS1-L-EXT-AD]" id="U24-OS1-L-EXT-AD" />

<p><input type="text" size="2" name="prec[824][F]" id="F824" /></p>


Objectifs :
Cliquer dans le radio donne le focus au text de la même ligne et renseigne une valeur dans le text name="prec[824][F] plus bas.
Cliquer dans le text sélectionne le radio sur la même ligne et renseigne une valeur dans le text name="prec[824][F] plus bas.

Avec le script ci dessous j'arrive à tout SAUF à renseigner la valeur quand click dans le text.


/* Donne le focus au radio */

const tex = document.querySelectorAll ('table.compcab input[type=text]');

if (tex.length > 0)
{
for (let i = 0; i < tex.length; i++)
{	
tex[i].addEventListener('click', function ()
{
const idRadio = this.parentNode.parentNode.querySelector('input[type=radio]').id;
document.getElementById (idRadio).checked=true;

}
);
}

/* Donne le focus au text */

const rad = document.getElementsByName ('super');

for (let i = 0; i < rad.length; i++)
{	
rad[i].addEventListener('click', function ()
{

const idRadio = 'U'+this.value;
document.getElementById (idRadio).focus ();

/* Donne la valeur au text Prévo sur x fibres */
if (this.id.indexOf ('--') != -1)
{
const idImg = this.id.split ('--');
const idPreco = 'F'+idImg[1];
document.getElementById (idPreco).value=idImg[2];
}
}
);
}
}


Exemple plus développé dans le codepen

Merci d'avance pour votre aide.
Modifié par boteha_2 (12 Aug 2020 - 16:47)
Bonjour,

J'ai trouvé une solution :

const idPreco = document.getElementById ('F'+ ca_id);

const tex = document.querySelectorAll ('table.compcab input[type=text]');

for (let i = 0; i < tex.length; i++)
{	
tex[i].addEventListener('click', function ()
{
const Radio = this.parentNode.parentNode.querySelector('input[type=radio]');
const idImg = Radio.id.split ('--');

idPreco.value=idImg[2];
document.getElementById(Radio.id).checked=true;
}
);
}


const rad = document.getElementsByName ('super');

for (let i = 0; i < rad.length; i++)
{	
rad[i].addEventListener('click', function ()
{

const idRadio = 'U'+this.value;
const idImg = this.id.split ('--');

document.getElementById (idRadio).focus ();
idPreco.value= idImg[2];
}
);
}



Je fais donc deux boucles en calculant un peu les mêmes choses dans chaque boucle.

Je me demande s'il n'est pas possible de faire une seule boucle.

Mais cela marche, voir le codepen.
Bonjour,

Je coche Résolu mais il existe peut-être une meilleure solution.

Merci de votre aide.
Modérateur
Bonjour
a écrit :
Je me demande s'il n'est pas possible de faire une seule boucle.

Sans doute, mais il faudrait pas mal de if dans les boucles, et puis faire une sélection bizarre, ce qui ne rendrait pas le code plus lisible.
Les deux boucles concernant des éléments de nature différente, c'est plutôt bien de les laisser séparer, et appréciable lorsque tu voudras étendre les fonctionnalités. La seule chose qui se répète un peu, c'est ça:

const idImg = this.id.split ('--');
idPreco.value= idImg[2];


tu peux le factoriser dans une fonction:

const idPreco = document.getElementById ('F'+ ca_id);

const tex = document.querySelectorAll ('table.compcab input[type=text]');
const setIdPrecoFromId = function(id){
  const idImg = id.split ('--');
  idPreco.value=idImg[2];
};

for (let i = 0; i < tex.length; i++)
{	
tex[i].addEventListener('click', function ()
{
const Radio = this.parentNode.parentNode.querySelector('input[type=radio]');
setIdPrecoFromId(Radio.id)
document.getElementById(Radio.id).checked=true;
}
);
}


const rad = document.getElementsByName ('super');

for (let i = 0; i < rad.length; i++)
{	
rad[i].addEventListener('click', function ()
{

const idRadio = 'U'+this.value;
setIdPrecoFromId(this.id)

document.getElementById (idRadio).focus ();
}
);
}
Bonjour,

Merci de ton message.

Je vais tester pendant le week-end.

Je vais aussi ouvrir une nouvelle discussion car quand ces boucles sont elles-mêmes dans une boucle, il y a un problème que je n'arrive pas à résoudre.

Je connais bien les boucles PHP mais avec javascrript je manque de bases.
Bonjour,

Ok pour une fonction.

Pour des raisons de lisibilité personnelle (je dis bien personnelle) je préfère une fonction façon PHP :

function setIdPrecoFromId (id)
{
const idImg = id.split ('--');
return idImg[2];
}


Je suppose qu'en terme de performances cela ne change rien par rapport à ta factorisation.

Cela marche bien, voir le codepen

PS : je reviens vers vous un peu plus tard avec mon problème de double boucle.
Pages :