Erreur de jquery.autocomplete.min.js

Uncaught TypeError: Cannot read property 'toLowerCase' of null ou Uncaught TypeError: Cannot read property 'value' of null

Le problème exposé dans ce sujet a été résolu.

Bonjour,

Après avoir suivi le tutoriel d'autocompletion de Syl pour créer un champ de recherche et d'ajout rapide au panier du système e-commerce que je mets en place sur le site d'un client, je rencontre quelques difficultés lors de la phase de test.

En effet, lorsque j'entre une lettre pour afficher les articles disponibles, je reçois, selon la lettre entrée, l'erreur suivante : Uncaught TypeError: Cannot read property 'toLowerCase' of null

C'est étrange, car lorsque je recherche avec la lettre "m", cela fonctionne correctement, mais pas avec la lettre "p" ou "a"

Autre point étrange, certaines lettres, comme le "r" me renvoient une erreur différente : *Uncaught TypeError: Cannot read property 'value' of null *

Le site en développement

Suis-je le seul à rencontrer ce problème ? Je suppose que le souci ne vient pas d'autocomplete mais plutôt de moi, mais je ne vois pas où j'ai pu me tromper. J'ai reproduit à l'identique le tuto de Syl, en modifiant bien entendu ce qui avait trait à la connexion à la base de données et à la sélection de la table.

Merci d'avance pour votre aide =)

Salut,

Je suis un peu rouillé en PHP, mais si ta requête ne renvoie rien (pas de mot commençant par ta lettre), $suggestions aura une valeur bizarre et json_encode($suggestions) va merder. Ce qui expliquerait le fait que ça fonctionne un coup sur deux.

En outre, ne devrais-tu pas passer par une requête préparée plutôt que par une concaténation ?

+0 -0

J'ai trouvé d'où venait le problème. Il s'agissait simplement de l'encodage des caractères (je n'étais pas en UTF-8.) J'ai simplement rajouté $options = array( PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8' ); en dernier paramètre à mon PDO.

Mais je reste curieux de savoir où tu veux en venir avec ta remarque. Actuellement, je suis certain que la requête ne peut pas ne rien renvoyer car il s'agit du nom du produit qui est toujours défini. Par contre, je suis curieux de savoir ce qu'une requête préparée peut apporter par rapport à la concaténation ? De meilleures performances ?

+0 -0

Salut !

J'ai simplement rajouté $options = array( PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8' ); en dernier paramètre à mon PDO.

Ulayka

J'aimerais juste relever que ce que tu as fait n'est nécessaire que pour PHP 5.3.6 et moins récent. Il vaudrait mieux utiliser le dernier paramètre du DSN, comme expliqué dans la FAQ PHP  ;)

Sinon, est-ce qu'on pourrait avoir le script qui traite ta requête pour l'auto-complétion ?

+0 -0

Effectivement, il serait intéressant d'éviter ce genre de problème… La sécurité n'est pas vraiment ma spécialité ^^' Je dois avouer que je ne sais pas vraiment comment m'y prendre. Actuellement, si l'utilisateur utilise un caractère qui n'est pas contenu dans un article, il ne passe rien.

Pour le code, ça reprend celui fourni par Syl, je n'ai pas vraiment cherché à réinventer la roue.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<?php
    if(isset($_GET['query'])) {
        // Mot tapé par l'utilisateur
        $q = htmlentities($_GET['query']);

        $options = array(
            PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'
        );
        // Connexion à la base de données
        try {
            $bdd = new PDO('mysql:host=localhost;dbname=dbname', 'root', '', $options);
        } catch(Exception $e) {
            exit('Impossible de se connecter à la base de données.');
        }

        // Requête SQL
        $requete = "SELECT nom FROM table WHERE nom LIKE '". $q ."%' LIMIT 0, 10";

        // Exécution de la requête SQL
        $resultat = $bdd->query($requete) or die(print_r($bdd->errorInfo()));

        // On parcourt les résultats de la requête SQL
        while($donnees = $resultat->fetch(PDO::FETCH_ASSOC)) {
            // On ajoute les données dans un tableau
            $suggestions['suggestions'][] = $donnees['nom'];
        }

        // On renvoie le données au format JSON pour le plugin
        echo json_encode($suggestions);
    }
?>
+0 -0

Bon, je vais me permettre d'adapter un peu ce code…

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<?php
    if(isset($_GET['query'])) {
        // Connexion à la base de données
        try {
            $bdd = new PDO('mysql:host=localhost;dbname=dbname;charset=utf8', 'root', '', $options);
        } catch(Exception $e) {
            exit('Impossible de se connecter à la base de données.');
        }

        // Requête SQL, avec marqueur pour la valeur
        $requete = "SELECT nom FROM table WHERE nom LIKE :query LIMIT 0, 10";

        // Préparation de la requête (reconnaissance des marqueurs)
        $statement = $bdd->prepare($requete);
        // Liaison des données (remplacement d'un marqueur)
        $statement->bindValue(array(
            'query',
            $_GET['query'],
            PDO::PARAM_STRING
        ));
        // Exécution de la requête SQL
        $resultat = $bdd->execute() or die(print_r($bdd->errorInfo()));

        // On parcourt les résultats de la requête SQL
        while($donnees = $resultat->fetch(PDO::FETCH_ASSOC)) {
            // On ajoute les données dans un tableau
            $suggestions['suggestions'][] = $donnees['nom'];
        }

        // On renvoie le données au format JSON pour le plugin
        echo json_encode($suggestions);
    }
?>

Les requêtes préparées aident à éviter les risques d'injection SQL en permettant d'éviter d'avoir à échapper les données soi-même – au passage, l'échappement avec htmlspecialchars() ou htmlentities(), désolé, mais on en a déjà fait un troll.

+1 -0

Salut Ymox, merci pour le code, je comprends la logique, malheureusement, ça ne fonctionne pas chez moi, j'ai beau taper ce que je veux dans le champ de recherche, rien ne s'affiche. J'ai bien entendu bien pris soin de modifier les informations de connexion à la BDD et de supprimer le paramètre $options, qui n'existait que pour forcer l'utilisation de l'UTF8.

Pour ce qui est de l'échappement, c'est une mauvaise habitude qu'il va me falloir perdre dans ce cas, c'est vrai que c'était un beau troll :)

J'ai vu ça avec un ami, on a trouvé une solution fonctionnelle :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<?php
    if(isset($_GET['query'])) {
        // Connexion à la base de données
        try {
            $bdd = new PDO('mysql:host=localhost;dbname=dbname;charset=utf8', 'root', '');
        } catch(Exception $e) {
            exit('Impossible de se connecter à la base de données.');
        }

        // Requête SQL, avec marqueur pour la valeur
        $requete = "SELECT nom FROM table WHERE nom LIKE :query";

        // Préparation de la requête (reconnaissance des marqueurs)
        $statement = $bdd->prepare($requete);
        // Liaison des données (remplacement d'un marqueur)
        $statement->bindValue(':query',$_GET['query'].'%',PDO::PARAM_STR);
        // Exécution de la requête SQL
        $resultat = $statement->execute() or die(print_r($statement->errorInfo()));
        // On parcourt les résultats de la requête SQL
        $suggestions = array('suggestions' => array());
        if($resultat == true){
            while($donnees = $statement->fetch(PDO::FETCH_ASSOC)) {
                // On ajoute les données dans un tableau
                $suggestions['suggestions'][] = $donnees['nom'];
            }

            // On renvoie le données au format JSON pour le plugin
            echo json_encode($suggestions);
        }else{}
    }
?>

Merci pour votre aide :)

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte