11525 sujets

JavaScript, DOM et API Web HTML5

Bonjour à tous,
J'ai un formulaire qui permet d'entrer ligne par ligne des éléments constituant le corps d'une facture. Je récupère les données saisies dans une chaîne concaténée pour afficher la facture qui se construit mais également pour l'envoyer vers une autre page php afin d'être enregistrée dans une bdd.

Le problème est que rien empêche l'utilisateur de saisir des ' ou des ; ou des | qui affectent non seulement l'affichage du corps de facture en cour, mais empêche tout calcul des quantités x prix sans parler de l'enregistrement php qui plante....

Ma question est comment afficher pour l'utilisateur ces caractères (exemple : Chambre d ' hôte ; Salle de bain...) et comment les échapper dans la partie traitement ?
Pour échapper j'ai pensé à ça :

// index 1 - désignation_prestation
var ref_prestation = prestation.value;
ref_prestation = ref_prestation.replace(/[';|]/g,' ');


Mais le problème est que l'affichage de l'utilisateur est affecté !


Voici mon code complet :


// ################# AJOUT PRESTATIONS AU CONTRAT ################
var TotalContrat = 0;
var selectElmt = document.getElementById("prestation");

function plus_contrat() {
    if (prestation.value != 0 && prix.value != 0 && quantite.value != 0) {
        // index 0 - id_prestation
        var text_prestation = selectElmt.options[selectElmt.selectedIndex].text;
        // index 1 - désignation_prestation
        var ref_prestation = prestation.value;
        ref_prestation = ref_prestation.replace(/'/g, "\\'");
        // index 2 - descriptif_prestation
        var text_descriptif = descriptif.value;
        text_descriptif = text_descriptif.replace(/'/g, " ");
        // index 3 - Prix prestation
        var ref_prix = parseFloat(prix.value).toFixed(2);
        // index 4 - Quantité_prestation
        var ref_quantite = parseFloat(quantite.value).toFixed(2);
        chaine_contrat.value += "|" + ref_prestation + ";" + text_prestation + ";" + text_descriptif + ";" + ref_prix + ";" + ref_quantite;
        TotalContrat = TotalContrat + ref_prix * ref_quantite;
        total_contrat.value = TotalContrat.toFixed(2);
        document.getElementById("quantite").value = '';
        contrat();
    }
}

function contrat() {
    var tableau_contrat = chaine_contrat.value.split('|');
    var nb_lignes = tableau_contrat.length;
    document.getElementById("detail_contrat").innerHTML = "";
    for (ligne = 0; ligne < nb_lignes; ligne++) {
        if (tableau_contrat[ligne] != "") {
            var ligne_contrat = tableau_contrat[ligne].split(';');
            document.getElementById("detail_contrat").innerHTML += " <
                div class = 'ligne_contrat' >
                ";
                // Affichage de l'ID de la prestation :
                //document.getElementById("detail_contrat").innerHTML += "
                <
                div class = 'col1' > " + ligne_contrat[0] + " < /div>
            ";
            // Affichage de la DÉSIGNATION de la prestation :
            document.getElementById("detail_contrat").innerHTML += " <
                div class = 'col2' > " + ligne_contrat[1] + " < /div>
            ";
            // Affichage du PRIX de la prestation :
            document.getElementById("detail_contrat").innerHTML += " <
                div class = 'col3' > " + ligne_contrat[3] + " < /div>
            ";
            // Affichage de la QUANTITÉ de la prestation :
            document.getElementById("detail_contrat").innerHTML += " <
                div class = 'col4' > " + ligne_contrat[4] + " < /div>
            ";
            document.getElementById("detail_contrat").innerHTML += "<input type='button' class = 'btn_annulation' value = '?' title ='Supprimer la prestation' onclick='suppr(\"" + tableau_contrat[ligne] + "\");' /> <
                /div> <
                /div>";
            // Affichage du descriptif de la prestation :
            document.getElementById("detail_contrat").innerHTML += " <
                div class = 'col5' > " + ligne_contrat[2] + " < /div>
            ";
        }        
    }
}

function suppr(ligne_s) {
    chaine_contrat.value = chaine_contrat.value.replace('|' + ligne_s, '');
    var tab_detail = ligne_s.split(';');
    TotalContrat = TotalContrat - tab_detail[3] * tab_detail[4];
    total_contrat.value = TotalContrat.toFixed(2);
    contrat();
}


Merci d'avance pour votre aide...
Modifié par etienne69 (25 Mar 2022 - 10:13)
salut,

Tu pourrais, en PHP, échapper TOUS les caractères spéciaux avec une petite fonction :


function clean($string) {
   $string = str_replace(' ', '-', $string); // Replaces all spaces with hyphens.

   return preg_replace('/[^A-Za-z0-9\-]/', '', $string); // Removes special chars.
}


et
echo clean('a|"bc!@£de^&$f g');

te renvoi
abcdef-g 


Tu peux également faire ce genre de méthode un peu plus "précise" et où tu peux ajouter certains caractère à traiter et avoir gérer leur retour

function cleanString($text) {
    $utf8 = array(
        '/[áàâãªä]/u'   =>   'a',
        '/[ÁÀÂÃÄ]/u'    =>   'A',
        '/[ÍÌÎÏ]/u'     =>   'I',
        '/[íìîï]/u'     =>   'i',
        '/[éèêë]/u'     =>   'e',
        '/[ÉÈÊË]/u'     =>   'E',
        '/[óòôõºö]/u'   =>   'o',
        '/[ÓÒÔÕÖ]/u'    =>   'O',
        '/[úùûü]/u'     =>   'u',
        '/[ÚÙÛÜ]/u'     =>   'U',
        '/ç/'           =>   'c',
        '/Ç/'           =>   'C',
        '/ñ/'           =>   'n',
        '/Ñ/'           =>   'N',
        '/–/'           =>   '-', // UTF-8 hyphen to "normal" hyphen
        '/[’‘‹›‚]/u'    =>   ' ', // Literally a single quote
        '/[“”«»„]/u'    =>   ' ', // Double quote
        '/ /'           =>   ' ', // nonbreaking space (equiv. to 0x160)
    );
    return preg_replace(array_keys($utf8), array_values($utf8), $text);
}

Modifié par JENCAL (25 Mar 2022 - 10:28)
Merci JENCAL pour ta réponse très rapide...

Tu écris "Tu pourrais, en PHP, ..." mais je ne vois pas comment implémenter tes propositions PHP au beau milieu de mon code JavaScript...
Quoi qu'il en soit, je vais regarder ton code de près car je viens de me rendre compte que ma facture est "fabriquée" avec un input dans lequel l'utilisateur peut saisir les caractères interdits mais aussi avec des select dont les contenus ont été créés dans une autre page PHP pour le coup qui elle n'interdit pas les ' les ; et les |
Je viens de faire un essai et tout plante quand je retourne dans ma page facture avec ces select

upload/1648201610-52818-capturedancran.jpg


upload/1648201338-52818-capturedancrandu2022-03-2510-.png
Modifié par etienne69 (25 Mar 2022 - 10:46)
Si je tente du supprimer une ligne contenant des ' alors toutes la partie Javascript qui sert à supprimer la ligne ne fonctionne plus et affiche un message d'erreur en console
etienne69 a écrit :
Merci JENCAL pour ta réponse très rapide...

Tu écris "Tu pourrais, en PHP, ..." mais je ne vois pas comment implémenter tes propositions PHP au beau milieu de mon code JavaScript...


Parce que tu as dit :
etienne69 a écrit :

également pour l'envoyer vers une autre page php afin d'être enregistrée dans une bdd.
Effectivement je peux échapper les caractères qui me gênent dans la page de traitement PHP mais en l’occurrence j'ai le problème dès la conception de la facture (puisque je ne peux pas supprimer une prestation formatée avec les caractères interdits)...

Je vais me servir de tes fonctions pour la page PHP qui permet en amont de créer les types de prestations (2° select car le 1° n'est pas en bdd) mais il me restera toujours les erreurs possibles dans le champ descriptif...

J'ai trouvé un moyen d'empêcher leur saisie ICI mais du coup on ne peut plus écrire 'chaises d'enfants' mais chaises d enfant
En soit ce n'est pas bien grave...
Personnellement je laisserais le traitement des caractères spéciaux au serveur. En PHP il existe des fonctions prédéfinies telles que addcslashes() et stripcslashes().

Sinon, pour la concaténation en javascript, je vois des choses comme ceci dans votre code :
"<div class = 'col5' > " + ligne_contrat[2] + " < /div>";

J'utiliserais plutôt des littéraux de gabari :
`<div class="col5">${ligne_contrat[2]}</div>`

Modifié par Olivier C (25 Mar 2022 - 13:30)
Je suis parfaitement d'accord Olivier, sauf que le 3ème input est de type texte, l'utilisateur peut donc écrire ce qu'il veut dedans (y compris des ' ; |) et quand il valide avec le bouton en bout de ligne, la partie dynamique (calcul + affichage) foire et la validation du formulaire fera crasher l'enregistrement à la page PHP suivante puisque le découpage de la chaîne chaine_contrat.value sera (pourra être) remplie de caractères interdits...

Pour ta deuxième remarque, je la note mais je dois reconnaître que compte tenu de mon niveau très faible en JavaScript, les + me parlent mieux Smiley biggrin
etienne69 a écrit :
Pour ta deuxième remarque, je la note mais je dois reconnaître que compte tenu de mon niveau très faible en JavaScript, les + me parlent mieux Smiley biggrin

Il me semble pourtant que les littéraux de gabarit sont plus lisibles.

Est-il plus lisible d'écrire ceci ? :
"<input type='button' class = 'btn_annulation' value = '?' title ='Supprimer la prestation' onclick='suppr(\"" + tableau_contrat[ligne] + "\");' /> </div></div>"

Ou ceci ? :
`<input type="button" class="btn_annulation" value="?" title="Supprimer la prestation" onclick="suppr(${tableau_contrat[ligne]})"/></div></div>`
Merci Olivier, ta première proposition me semble plus compréhensible...
Quoi qu'il en soit, j'ai trouvé après de nombreux tests que le blocage de certains caractères n'était pas génial en cours de saisie

J'ai notamment essayé ça (trouvé sur Internet) :

function caracteresInterdits(event) {
  var keyCode = event.which ? event.which : event.keyCode;
  var touche = String.fromCharCode(keyCode);  
  var champ = event.target;
  var caracteres = ';\'|';
  /*if(caracteres.indexOf(touche) >= 0) {// Code pour caractères autorisés
    champ.value += touche;
  }*/
  if (caracteres.indexOf(touche) == -1) { // Code pour caractères interdits
    champ.value += touche;
  }
}

Mais si on revient en milieu de texte pour corriger, l'ajout se fait en bout de chaîne dans l'input et cette fonction n’empêche pas le copier/coller de texte contenant des caractères interdits...

Du coup j'ai écrit ça avec mes très faibles connaissances en JavaScript qui fonctionne plutôt pas mal :

<div class="type-descriptif">
    <label for="descriptif">Descriptif : <em> (Caractères interdits : ' , | et ; </em></label>
    <textarea name="descriptif" id="descriptif" onblur="caracteresInterdits(this);">
    </textarea>
</div>



// ########### CARACTÈRES INTERDITS ##### 
function caracteresInterdits(arg2) {
    var str = arg2.value;
    var str = str.replace(/[\';|]/gi, '');
    arg2.value = str;
}


C'est pas terrible, mais le résultat me convient pour l'instant et m'évite surtout de cracher la page de traitement d'enregistrement...
Modifié par etienne69 (28 Mar 2022 - 10:50)