[RESOLU] JQuery Autocomplete source oracle

ViPHP
xTG
ViPHP | 7331 Messages

16 févr. 2011, 19:54

Au fait pourquoi récupérer les 65000 enregistrements si c'est de l'autocomplete ?
On est pas censé tout récupérer justement dans un auto-complete, seulement les enregistrements qui répondent à la recherche.
Si on cherche Jac il faut pas qu'on nous propose Daniel par exemple.
Donc avec ton système si tu filtrais, à partir de trois caractères tu diviserais déjà par 6 le nombre de résultats...

Car si ta fonction est appelée sur chaque changement, la pauvre bdd doit en prendre un coup à exécuter ça...
A la rigueur si tu veux le tout il faudrait l'exécuter une fois, le stocker en session et ensuite renvoyer la variable de session plutôt que de relancer la requête.

ViPHP
AB
ViPHP | 5818 Messages

16 févr. 2011, 20:41

Ah bah non faut pas l'utiliser comme ça l'autocomplete :wink:
Ce que tu fais convient pour quelques lignes, sinon il faut faire une requête à la bdd en ajax avec les termes de la recherche.

A ta décharge, la doc jquery sur l'autocomplete n'est pas forcément facile à trouver. C'est ici et regarde les exemples "remote datasource" ou "Remote with caching".

En fait cela envoi les termes de la recherche dans une variable $_GET nommée "term" vers le fichier search.php (lis bien le mode d'emploi). Et donc dans ton fichier "search.php" tu fait ta requête en utilisant $_GET['term'] et tu envoies le résultat sous forme de tableau json.
When a String is used, the Autocomplete plugin expects that string to point to a URL resource that will return JSON data. It can be on the same host or on a different one (must provide JSONP). The request parameter "term" gets added to that URL. The data itself can be in the same format as the local data described above.
EDIT : Faits-le sans Zend au moins dans un premier temps.

Eléphanteau du PHP | 49 Messages

17 févr. 2011, 09:47

Bonjour et merci pour vos réponses. :)

@xTG: Je ne fais l'appel qu'une fois, au chargement de la page (qui du coup est très long), pas à chaque caractère entré, dieu merci! ^^

@AB: C'est justement la question. J'ai trouvé et lu la doc mais je ne trouve pas d'exemple de ce fichier search.php, est-ce une fonction, une simple requete?

Est-ce que cela fonctionnerait:

Code : Tout sélectionner

function listerNoclient() { // Connexion $dbConn = new PDO($this->_dsn, $this->_username, $this->_password); // Preparation de le requete $pdoStmt = $dbConn->prepare('SELECT NO_CLI_VPC FROM VCCLICGP WHERE DT_SUP IS NULL AND NO_CLI_VPC LIKE "%term%"'); // Execution de la requete $pdoStmt->execute(); $res = $pdoStmt->fetchAll(PDO::FETCH_COLUMN); //Courrier_Log::getInstance()->logDebug(print_r($res, true)); // Fermeture connexion $dbConn = null; return $res; }
Quelqu'un aurait-il un exemple de search.php quelque part, même trivial, juste un exemple de quoi mettre dedans?

Merci.

ViPHP
ViPHP | 3607 Messages

17 févr. 2011, 09:52

C'est pourtant simple :
<?php

         // Connexion
        $dbConn = new PDO($this->_dsn, $this->_username, $this->_password);
        // Preparation de le requete
        $pdoStmt = $dbConn->prepare('SELECT NO_CLI_VPC as value FROM VCCLICGP WHERE DT_SUP IS NULL AND NO_CLI_VPC LIKE "term%" LIMIT 0,10');
        // Execution de la requete
        $pdoStmt->execute();
        $res = $pdoStmt->fetchAll(PDO::FETCH_ASSOC);
        //Courrier_Log::getInstance()->logDebug(print_r($res, true));
        // Fermeture connexion
        $dbConn = null;
        echo json_encode($res);
Note que j'ai rajouté une clause LIMIT dans la requête, que j'ai mis le % seulement après terme pour que si tu tappes
"chat"
on te renvois chats, chattons, etc... mais pas achat, ça c'est toi qui voit pour la pertinence des résultats
J'ai également donné le nom de value à ton champs parce que c'est qu'attends jqueryui...

VOilà

ViPHP
ViPHP | 3607 Messages

17 févr. 2011, 09:55

J'ajoute que tu peux voir le résultat de ce que donne ce fichier ici : http://jqueryui.com/demos/autocomplete/ ... hp?term=te
change la valeur de term et tu verras

Eléphanteau du PHP | 49 Messages

17 févr. 2011, 10:20

Super, j'avance j'avance. Merci de votre patience. :)

Donc j'arrive avec ça:

Controller:

Code : Tout sélectionner

$this->view->autocompleteElement = new ZendX_JQuery_Form_Element_AutoComplete('autoComplete'); $this->view->autocompleteElement->setJQueryParams(array("source" => 'pilotage/search')) ->setAttrib('size',10,10,10) ->setAttrib('limit',10) ->setJQueryParam('minLength',4);
Search.phtml

Code : Tout sélectionner

<?php $dsn = Zend_Registry::get('ZendConfig')->pdo->dsn; $username = Zend_Registry::get('ZendConfig')->pdo->username; $password = Zend_Registry::get('ZendConfig')->pdo->password; // Connexion $dbConn = new PDO($dsn, $username, $password); $search = $_GET['term']; $search = $search."%"; // Preparation de le requete $pdoStmt = $dbConn->prepare("SELECT NO_CLI_VPC FROM VCCLICGP WHERE NO_CLI_VPC LIKE '$search'"); // Execution de la requete $pdoStmt->execute(); $res = $pdoStmt->fetchAll(PDO::FETCH_ASSOC); Courrier_Log::getInstance()->logDebug(print_r($res, true)); // Fermeture connexion $dbConn = null; echo json_encode($res); ?>
A sortir cela dans mon log:

Code : Tout sélectionner

Array ( [0] => Array ( [NO_CLI_VPC] => V000000 ) [1] => Array ( [NO_CLI_VPC] => V000014 ) [2] => Array ( [NO_CLI_VPC] => V000015 ) [3] => Array ( [NO_CLI_VPC] => V000016 ) [4] => Array ( [NO_CLI_VPC] => V000017 ) [5] => Array ( [NO_CLI_VPC] => V000018 ) ...
Quand je tape V0000 (j'ai tous les truc commençant par V0000, donc ça marche).

Seulement, l'autocomplete n'affiche rien. J'imagine que ça a à voir avec le echo json_encode($res);, du coup j'y travaille. :)

ViPHP
ViPHP | 3607 Messages

17 févr. 2011, 10:23

Bonjour,

non ça a à voir avec ça:
[4] => Array
(
[NO_CLI_VPC] => V000017
)
Il faut que NO_CLI_VPC devienne value

C'est pour ça que j'avais ajouté dans ta requête "as value"

Eléphanteau du PHP | 49 Messages

17 févr. 2011, 10:29

Okidoki. Je comprends la logique. Du coup maintenant j'ai ça en retour pour json_encode($res)

Code : Tout sélectionner

{"VALUE":"V000000"},{"VALUE":"V000014"},{"VALUE":"V000015"},{"VALUE":"V000016"},{"VALUE":"V000017"},{"VALUE":"V000018"},{"VALUE":"V000019"},{"VALUE":"V000020"},{"VALUE":"V000021"},{"VALUE":"V000022"},{"VALUE":"V000023"},{"VALUE":"V000024"},{"VALUE":"V000025"},{"VALUE":"V000026"},{"VALUE":"V000027"},{"VALUE":"V000028"},{"VALUE":"V000029"},{"VALUE":"V000030"},{"VALUE":"V000031"},...
Mais toujours rien de proposé dans l'autocomplete. Je cherche du coup ce que l'autocomplete veut réellement recevoir.

Je poste ici chaque étape pour permettre à quelqu'un d'autre que moi de saisir le truc, trop souvent sur les forums je vois des "j'ai un problème" "voici une solution spécifique pour ton cas" et aucune étape intermédiaire pour la compréhension. Si ça vous embête je peux zapper mes étapes et revenir ici que quand je suis réellement bloqué. Je ne veux pas flooder. :)

ViPHP
ViPHP | 3607 Messages

17 févr. 2011, 10:32

value et non pas VALUE ;)
Et le LIMIT ? il est où?

Eléphanteau du PHP | 49 Messages

17 févr. 2011, 10:35

value est en minuscule dans ma requête. :s
LIMIT n'existe pas sous Oracle.

Voici la requête actuellement. Elle retourne bien un tableau json mais rien n'est affiché pour l'autocomplete.

Code : Tout sélectionner

<?php $dsn = Zend_Registry::get('ZendConfig')->pdo->dsn; $username = Zend_Registry::get('ZendConfig')->pdo->username; $password = Zend_Registry::get('ZendConfig')->pdo->password; // Connexion $dbConn = new PDO($dsn, $username, $password); $search = $_GET['term']; $search = $search."%"; // Preparation de le requete $pdoStmt = $dbConn->prepare("SELECT NO_CLI_VPC as value FROM VCCLICGP WHERE NO_CLI_VPC LIKE '$search'"); // Execution de la requete $pdoStmt->execute(); $res = $pdoStmt->fetchAll(PDO::FETCH_ASSOC); Courrier_Log::getInstance()->logDebug(print_r(json_encode($res), true)); // Fermeture connexion $dbConn = null; echo json_encode($res); ?>
--edit: peut-être un lien avec ce paramètre que l'on retrouve dans la demo JQuery:
http://jqueryui.com/demos/autocomplete/#remote

Code : Tout sélectionner

select: function( event, ui ) { log( ui.item ? "Selected: " + ui.item.value + " aka " + ui.item.id : "Nothing selected, input was " + this.value ); }
Mais j'ai plutôt l'impression que c'est inhérent à leur code (pour remplir le tableau en dessous de l'autocomplete).

ViPHP
ViPHP | 3607 Messages

17 févr. 2011, 10:47

Si tu vas directement sur l'url fichier.php?term=abc
Qu'est-ce que tu obtiens? copie-colle ici!

Et pour le LIMIT si ça n'existe pas sous oracle, il doit bien y avoir un moyen de ne pas prendre tout les résultats? non?
De toute façon tu vas en utiliser seulement 10!

Eléphanteau du PHP | 49 Messages

17 févr. 2011, 10:52

En faisant ?term=V0000 j'obtiens la même chose que mon log:

Code : Tout sélectionner

[{"VALUE":"V000000"},{"VALUE":"V000014"},{"VALUE":"V000015"},{"VALUE":"V000016"},{"VALUE":"V000017"},{"VALUE":"V000018"},{"VALUE":"V000019"},{"VALUE":"V000020"},{"VALUE":"V000021"},{"VALUE":"V000022"},{"VALUE":"V000023"},{"VALUE":"V000024"},{"VALUE":"V000025"},{"VALUE":"V000026"},{"VALUE":"V000027"},{"VALUE":"V000028"},{"VALUE":"V000029"},{"VALUE":"V000030"},{"VALUE":"V000031"},{"VALUE":"V000032"},{"VALUE":"V000033"},{"VALUE":"V000034"},{"VALUE":"V000035"},{"VALUE":"V000036"},{"VALUE":"V000037"},{"VALUE":"V000038"},{"VALUE":"V000039"},{"VALUE":"V000040"},{"VALUE":"V000041"},{"VALUE":"V000042"},{"VALUE":"V000043"},{"VALUE":"V000044"},{"VALUE":"V000045"},{"VALUE":"V000046"},{"VALUE":"V000047"},{"VALUE":"V000048"},{"VALUE":"V000049"},{"VALUE":"V000050"},{"VALUE":"V000051"},{"VALUE":"V000052"},{"VALUE":"V000053"},{"VALUE":"V000054"},{"VALUE":"V000055"},{"VALUE":"V000056"},{"VALUE":"V000057"},{"VALUE":"V000058"},{"VALUE":"V000059"},{"VALUE":"V000060"},{"VALUE":"V000061"},{"VALUE":"V000062"},{"VALUE":"V000063"},{"VALUE":"V000064"},{"VALUE":"V000065"},{"VALUE":"V000066"},{"VALUE":"V000067"},{"VALUE":"V000068"},{"VALUE":"V000069"},{"VALUE":"V000070"},{"VALUE":"V000071"},{"VALUE":"V000072"},{"VALUE":"V000073"},{"VALUE":"V000074"},{"VALUE":"V000075"},{"VALUE":"V000076"},{"VALUE":"V000077"},{"VALUE":"V000078"},{"VALUE":"V000079"},{"VALUE":"V000080"},{"VALUE":"V000081"},{"VALUE":"V000082"},{"VALUE":"V000083"},{"VALUE":"V000084"},{"VALUE":"V000085"},{"VALUE":"V000086"},{"VALUE":"V000087"},{"VALUE":"V000088"},{"VALUE":"V000089"},{"VALUE":"V000090"},{"VALUE":"V000091"},{"VALUE":"V000092"},{"VALUE":"V000093"},{"VALUE":"V000094"},{"VALUE":"V000095"},{"VALUE":"V000096"},{"VALUE":"V000097"},{"VALUE":"V000098"},{"VALUE":"V000099"}]
Autocomplete a besoin d'un truc sous la forme array("V000000","V000001",...), du coup j'imagine que si je peux transformer ce truc au dessus sans les value et les accolades peut-être que ça passerait?

Je n'ai pas besoin de LIMIT puisque je limite déjà l'affichage de l'autocomplete à 5 caractères (soit V0000xx, donc 100 résultats maximum). Je ne suis pas limité à 10, je n'en affiche que 10 et ensuite il y a une scrollbar. :)

ViPHP
ViPHP | 3607 Messages

17 févr. 2011, 10:58

Non!
Il faut garder la structure:

Code : Tout sélectionner

[ {"value":"a"}, {"value":"b"}, {"value":"c"} ]
Donc tu te débrouilles pour mettre ta requête dans un tableau comme ceci:
<?php

$results = array(
    array('value'=>'a'),
    array('value'=>'b'),
    array('value'=>'c')
);
Allez hop! :)

Eléphanteau du PHP | 49 Messages

17 févr. 2011, 11:30

Je n'y parviens pas. J'essaye explode, sans encoder en json, en mettant des arrays partout je n'y parviens pas. :(

Je débute tout ça, il y a un mois je ne savais même pas ce qu'était un ordinateur (ouais bon j'exagère, j'avais déjà codé mais en C seulement). Là entre Zend, php, json etc. je suis un peu perdu quant aux trucs et astuces j'imagine très simple à savoir.

ViPHP
xTG
ViPHP | 7331 Messages

17 févr. 2011, 11:33

$results= array();
foreach($res as $r)
  $results[] = array('value' => $r);
;)