Page 1 sur 1

problème d'affichage

Posté : 03 juil. 2007, 11:20
par béka
Bonjour, je vous exlique mon problème.

Dans un fichier search-engine.php, j'offre la possibilité à l'internaute de sélectionner plusieurs critères de recherche à travers des checkbox.
Les valeurs de ces checkbox sont renvoyées en POST à la page result-request.php.
Et c'est là que j'ai un problème. Je n'arrive pas à faire en sorte d'afficher à la suite les différents résultats trouvés. Ils s'affichent les uns après les autres. Les n effaçant les n-1.

Voici mon code du formulaire :
<script>
function AfficheResult() {
  var critInputs = document.criteria.elements;
  var myInput;
  for ( var i = 0 ; i < critInputs.length ; i++ ) {
    myInput = critInputs[i];
    if ( myInput.type == 'checkbox' && myInput.checked ) {
      var explode = myInput.value.split('/');
      var id_cat = explode[0];
      var id_crit = explode[1];
      getByAjax('result-request.php', document.getElementById('ajax'), 'cat='+id_cat+'&crit='+id_crit); 
    }
  }  
}
</script>

<div id="content">
<?
echo "<br /><br />Choose the different criteria which correspond to your request : ";
/*---------------------------------*/
//on ouvre le fichier criteria.xml
$criteriaFile = $cfg['ressources_root'].'criteria.xml';
$domCriteria = new DOMDocument('1.0','UTF-8');
$domCriteria->load($criteriaFile);
$xpCriteria = new DOMXPath($domCriteria);
$cat_criteria = $domCriteria->getElementsByTagName('cat');
$result_find_criteria = $domCriteria->getElementsByTagName('criteria');?>


<form name="criteria">
<?
echo "<table align='center'><tr>";
foreach($cat_criteria as $cat){
  $name_cat = $cat->getAttribute('name');
  $id_cat = $cat->getAttribute('id');
  echo "<td valign='top'><br /><strong>".$name_cat." : </strong>";
  foreach ($cat->childNodes as $criteria)
  {
    if ($criteria->nodeType != XML_ELEMENT_NODE) continue;
    if ($criteria->tagName == 'criteria')
    {
      $name_criteria = $criteria->getAttribute('name');
      $id_criteria = $criteria->getAttribute('id');      
      echo "<ul><input type='checkbox' id='crit' name='crit[]' value='$id_cat/$id_criteria'>$name_criteria</input></ul>";
    }
  }
}
echo "</tr></table>";

?>
</form>
<div align="center"><button onClick="AfficheResult();">Search</button></div>

<div id="ajax"></div>


Voici mon code pour récupérer les variables et les afficher :
<?php
session_name('SEEC');
session_start(session_name());
include('php-includes/common.php');

/*-----------------------------------------------------*/
//on affiche le résultat en fonction d'un seul critère //
/*-----------------------------------------------------*/

$link_file = $cfg['ressources_root'].'/matrix/criteria-practice.xml';
$xml = simplexml_load_file($link_file);//on ouvre le fichier xml

//on vérifie l'existence des varaibles passées par le formulaire si elle n'existe pas, on lui affecte une valeur vide
if (!isset($_POST['crit'])) { $_POST['crit'] = ''; }
if (!isset($_POST['cat'])) { $_POST['cat'] = ''; }

//si les variables ne sont pas vides
if ( ($_POST['crit'] != '') && ($_POST['cat'] != ''))
{
  foreach($xml->link as $value)
  {
     if( $value->criteria[0]['idcrit'] == $_POST['crit'] and $value->criteria[0]['idcat'] == $_POST['cat'])
     {
        $practice[]=( (int)$value->practice[0]['id'] );
        if (isset($practice[0]))
        {
          $id_practice = $practice[0];
        }
        else $id_practice = '';
     }
  }
  if ( (isset($id_practice)) and ($id_practice != '') ) // si $id_practice n'est pas vide
  { 
    //on ouvre le document xml qui correspond à la recherche
    $practiceFile = $cfg['ressources_root'].'content/practice/'.$id_practice.'.xml';
    $domPractice = new DOMDocument('1.0','UTF-8');
    $domPractice->load($practiceFile);
    $xpPractice = new DOMXPath($domPractice);
    $item_practice = $domPractice->getElementsByTagName('item');


    foreach ($item_practice as $item) 
    {
      foreach ($item->childNodes as $child)
      {
        if($child->nodeType != XML_ELEMENT_NODE) continue;
        if($child->tagName == 'title')
        {
          $titre = utf8_decode($child->firstChild->nodeValue);
        }
        elseif ($child->tagName == 'short_description')
        {
          $short_description = utf8_decode($child->firstChild->nodeValue);
        }
      //$msg = "<table width='600'><tr><th>Title of the practice</th><th>Short description</th><th>Viewed</th><th>Used</th></tr>";
      //$msg .= "<tr><td>$titre</td><td>$short_description</td></tr>";
      //$msg .= "</table>";
      //echo $msg;
      }
    }
      $msg = "<table width='600'><tr><th>Title of the practice</th><th>Short description</th><th>Viewed</th><th>Used</th></tr>";
      $msg .= "<tr><td>$titre</td><td>$short_description</td></tr>";
      $msg .= "</table>";
  }
  else
  { 
    $msg = "<p align='center'>There is no practice which correspond to your request. Please refine your search !</p>";
  }
  echo "<h3>Result of your search : </h3>";
  echo "<p>List of practices which correspond to the different criteria you checked : <br /></p>";
  echo $msg;
}
?>
Si quelqu'un pouvait m'aider..

Posté : 04 juil. 2007, 10:51
par Ryle
Il y a quelque chose que je ne comprends pas dans ton code : tu as plusieurs cases à cocher nommée crit[], donc si une au moins est cochée, la variable $_POST['crit'] que tu vas recevoir sera un tableau. Cette comparaison n'a donc aucun sens si tu ne parcours pas les éléments de ton tableau un par un :
$value->criteria[0]['idcrit'] == $_POST['crit'] 
Par ailleurs, au lieu de mettre vide comme valeur par défaut si $_POST['crit'] n'est pas défini, à ta place je respecterais le type et mettrais donc array() pour avoir un tableau vide. Tu pourras ainsi tester la taille du tableau et le parcourir pour récupérer les valeurs des cases cochées :)

Posté : 04 juil. 2007, 14:12
par béka
je ne comprends pas ce que tu dis ?
En faisant ainsi, je récupère bien tous les éléments que j'ai sélectionner.

Posté : 04 juil. 2007, 14:26
par orgerix
$_POST['crit'] est un tableau, donc tu ne peux pas comparer une chaine avec un tableau.

IL faudrait que tu rajoute une boucle pour le parcourire.

Posté : 04 juil. 2007, 15:02
par béka
la boucle elle se fait dans le premier fichier php celui où il y a le formulaire. Dans le code javascript.

Posté : 04 juil. 2007, 15:08
par orgerix
Désolé, je n'avais pas vu que tu utilisais AJAX.

Sinon, on peut avoir le code de la fonction getByAjax ? Ca viens de la. Elle remplace le contenu du conteneur par le résultat retourné ou lieu de l'ajouter

Posté : 04 juil. 2007, 15:15
par béka
Mais biensur, voici le code de la fonction getByAjax:

Code : Tout sélectionner

/* * Moteur Ajax */ function getXhr(){ var xhr = null; if(window.XMLHttpRequest) // Firefox et autres xhr = new XMLHttpRequest(); else if(window.ActiveXObject){ // Internet Explorer try { xhr = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { xhr = new ActiveXObject("Microsoft.XMLHTTP"); } } else { // XMLHttpRequest non supporté par le navigateur alert("Votre navigateur ne supporte pas les objets XMLHTTPRequest..."); xhr = false; } return xhr; } /** * Méthode qui appelle un script serveur et renvoit sa réponse * * serveur: l'url du script serveur appelé * reponse: objet HTML donné par référence à un conteneur HTML de la page chargée * paramètres: liste des paramètres éventuellement passés au script serveur (param1=valeur1&param2=valeur2...) */ function getByAjax(serveur, reponse, parametres){ var xhr = getXhr(); //Nouvelle instance Ajax if (xhr && serveur){ // On défini la fonction observant la communication Ajax/serveur xhr.onreadystatechange = function(){ // le code 4/200: détermine que Ajax a reçu une réponse du serveur if(xhr.readyState == 4 && xhr.status == 200){ reponse.innerHTML = xhr.responseText; //renvoit la réponse du serveur dans le conteneur reponse } } // Déclenchement de l'appel Ajax/serveur (avec passage de paramètres en POST) xhr.open("POST" ,serveur ,true); xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded'); xhr.send(parametres); } } /* * fin du moteur AJAX */
et le code de la fonction creerDiv :

Code : Tout sélectionner

function creerDiv(id_donne, contenu_donne, avant_ou_apres, emplacement_donne){ // crée un nouveau div var div = document.createElement("div"); // fixer l'id div.setAttribute("id", id_donne); // placer son contenu var contenu = document.createTextNode(contenu_donne); div.appendChild(contenu); // insère le div avant_ou_après l'emplacement donné if (avant_ou_apres == 'avant') emplacement_donne.parentNode.insertBefore(div, emplacement_donne); else emplacement_donne.parentNode.insertBefore(div, emplacement_donne.nextSibling); }

Posté : 04 juil. 2007, 16:25
par orgerix

Code : Tout sélectionner

reponse.innerHTML = xhr.responseText; //renvoit la réponse du serveur dans le conteneur reponse
C'est la que ca coince. Pour ajouter, il faut faire

Code : Tout sélectionner

reponse.innerHTML = reponse.innerHTML + xhr.responseText; //renvoit la réponse du serveur dans le conteneur reponse
Cependnat, si tu utilise la fonction dans d'autres script, tu aura des problèmes.Le mieux serait de créer un nouveau parametre qui dis s'il faut remplacer ou completer.

Ca donnerai quelque chose de ce genre.

Code : Tout sélectionner

function getByAjax(serveur, reponse, parametres,ajout=false){ var xhr = getXhr(); //Nouvelle instance Ajax if (xhr && serveur){ // On défini la fonction observant la communication Ajax/serveur xhr.onreadystatechange = function(){ // le code 4/200: détermine que Ajax a reçu une réponse du serveur if(xhr.readyState == 4 && xhr.status == 200){ if(ajout) { reponse.innerHTML = reponse.innerHTML + xhr.responseText; //renvoit la réponse du serveur dans le conteneur reponse } else { reponse.innerHTML = xhr.responseText; //renvoit la réponse du serveur dans le conteneur reponse } } } // Déclenchement de l'appel Ajax/serveur (avec passage de paramètres en POST) xhr.open("POST" ,serveur ,true); xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded'); xhr.send(parametres); } }

Posté : 04 juil. 2007, 16:55
par béka
Cette fonction n'est utilisée qu'ici et dans aucun autre script donc on peut faire ta première solution.

Seulement comme ça, le 1er résultat trouvé est écrasé par le deuxième résultat trouvé lorsqu'on coche plusieurs checkbox. Ils ne se rajoutent pas. C'est pourquoi j'avais la fonction creeerdiv mais je n'arrive pas à l'utiliser correctement.

Comment faire alors ?

Posté : 04 juil. 2007, 17:10
par orgerix
OU est ce que tu appelle la foncito creerDiv ? Je ne la voix pas.

Sinon, j'ai testé la syntaxe et elle marche.

Posté : 04 juil. 2007, 17:30
par béka
ha oui zut, c'est pas mis à jour les fichiers.

Voilà ce que j'ai maintenant.

page search-engine.php :
<?php
session_name('SEEC');
session_start(session_name());
include('php-includes/common.php');?>

<?
include('html_head.php');
include('header.php');
?>

<script>
function AfficheResult() {
  var critInputs = document.criteria.elements;
  var myInput;
  for ( var i = 0 ; i < critInputs.length ; i++ ) {
    myInput = critInputs[i];
    if ( myInput.type == 'checkbox' && myInput.checked ) {
      var explode = myInput.value.split('/');
      var id_cat = explode[0];
      var id_crit = explode[1];
      getByAjax('result-request.php', document.getElementById('ajax'), 'cat='+id_cat+'&crit='+id_crit);
      creerDiv('div_1', '$msg', 'apres', document.getElementById('ajax')); 
    }
  }  
}

function creerDiv(id_donne, contenu_donne, avant_ou_apres, emplacement_donne){
 // crée un nouveau div
 var div = document.createElement("div");

 // fixer l'id
 div.setAttribute("id", id_donne);

 // placer son contenu
 var contenu = document.createTextNode(contenu_donne);
 div.appendChild(contenu);

 // insère le div avant_ou_après l'emplacement donné
 if (avant_ou_apres == 'avant') emplacement_donne.parentNode.insertBefore(div, emplacement_donne);
 else emplacement_donne.parentNode.insertBefore(div, emplacement_donne.nextSibling);
}
</script>

<div id="content">
<?
echo "<br /><br />Choose the different criteria which correspond to your request : ";
/*---------------------------------*/
//on ouvre le fichier criteria.xml
$criteriaFile = $cfg['ressources_root'].'criteria.xml';
$domCriteria = new DOMDocument('1.0','UTF-8');
$domCriteria->load($criteriaFile);
$xpCriteria = new DOMXPath($domCriteria);
$cat_criteria = $domCriteria->getElementsByTagName('cat');
$result_find_criteria = $domCriteria->getElementsByTagName('criteria');?>


<form name="criteria">
<?
echo "<table align='center'><tr>";
foreach($cat_criteria as $cat){
  $name_cat = $cat->getAttribute('name');
  $id_cat = $cat->getAttribute('id');
  echo "<td valign='top'><br /><strong>".$name_cat." : </strong>";
  foreach ($cat->childNodes as $criteria)
  {
    if ($criteria->nodeType != XML_ELEMENT_NODE) continue;
    if ($criteria->tagName == 'criteria')
    {
      $name_criteria = $criteria->getAttribute('name');
      $id_criteria = $criteria->getAttribute('id');      
      echo "<ul><input type='checkbox' id='crit' name='crit[]' value='$id_cat/$id_criteria'>$name_criteria</input></ul>";
    }
  }
}
echo "</tr></table>";

?>
</form>
<div align="center"><button onClick="AfficheResult();">Search</button></div>

<div id="ajax"></div>
<?
include('html_foot.php');  
?>
page result-request.php :
<?php
session_name('SEEC');
session_start(session_name());
include('php-includes/common.php');

/*-----------------------------------------------------*/
//on affiche le résultat en fonction d'un seul critère //
/*-----------------------------------------------------*/

$link_file = $cfg['ressources_root'].'/matrix/criteria-practice.xml';
$xml = simplexml_load_file($link_file);//on ouvre le fichier xml

//on vérifie l'existence des varaibles passées par le formulaire si elle n'existe pas, on lui affecte une valeur vide
if (!isset($_POST['crit'])) { $_POST['crit'] = ''; }
if (!isset($_POST['cat'])) { $_POST['cat'] = ''; }

//si les variables ne sont pas vides
if ( ($_POST['crit'] != '') && ($_POST['cat'] != ''))
{
  foreach($xml->link as $value)
  {
     if( $value->criteria[0]['idcrit'] == $_POST['crit'] and $value->criteria[0]['idcat'] == $_POST['cat'])
     {
        $practice[]=( (int)$value->practice[0]['id'] );
        if (isset($practice[0]))
        {
          $id_practice = $practice[0];
        }
        else $id_practice = '';
     }
  }
  if ( (isset($id_practice)) and ($id_practice != '') ) // si $id_practice n'est pas vide
  { 
    //on ouvre le document xml qui correspond à la recherche
    $practiceFile = $cfg['ressources_root'].'content/practice/'.$id_practice.'.xml';
    $domPractice = new DOMDocument('1.0','UTF-8');
    $domPractice->load($practiceFile);
    $xpPractice = new DOMXPath($domPractice);
    $item_practice = $domPractice->getElementsByTagName('item');


    foreach ($item_practice as $item) 
    {
      foreach ($item->childNodes as $child)
      {
        if($child->nodeType != XML_ELEMENT_NODE) continue;
        if($child->tagName == 'title')
        {
          $titre = utf8_decode($child->firstChild->nodeValue);
        }
        elseif ($child->tagName == 'short_description')
        {
          $short_description = utf8_decode($child->firstChild->nodeValue);
        }
      }
    }
      $msg = "<table width='600'><tr><th>Title of the practice</th><th>Short description</th><th>Viewed</th><th>Used</th></tr>";
      $msg .= "<tr><td>$titre</td><td>$short_description</td></tr>";
      $msg .= "</table>";
  }
  else
  { 
    $msg = "<p align='center'>There is no practice which correspond to your request. Please refine your search !</p>";
  }
  echo "<h3>Result of your search : </h3>";
  echo "<p>List of practices which correspond to the different criteria you checked : <br /></p>";
  echo $msg;
}
?>
et ma fonction ajax est ici :
/*
* Moteur Ajax
*/
function getXhr(){
var xhr = null;
if(window.XMLHttpRequest) // Firefox et autres
xhr = new XMLHttpRequest();
else if(window.ActiveXObject){ // Internet Explorer
try {
xhr = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
}
else { // XMLHttpRequest non supporté par le navigateur
alert("Votre navigateur ne supporte pas les objets XMLHTTPRequest...");
xhr = false;
}
return xhr;
}

/**
* Méthode qui appelle un script serveur et renvoit sa réponse
*
* serveur: l'url du script serveur appelé
* reponse: objet HTML donné par référence à un conteneur HTML de la page chargée
* paramètres: liste des paramètres éventuellement passés au script serveur (param1=valeur1&param2=valeur2...)
*/
function getByAjax(serveur, reponse, parametres){
var xhr = getXhr(); //Nouvelle instance Ajax
if (xhr && serveur){
// On défini la fonction observant la communication Ajax/serveur
xhr.onreadystatechange = function(){
// le code 4/200: détermine que Ajax a reçu une réponse du serveur
if(xhr.readyState == 4 && xhr.status == 200){
reponse.innerHTML = reponse.innerHTML + xhr.responseText; //renvoit la réponse du serveur dans le conteneur reponse
}
}

// Déclenchement de l'appel Ajax/serveur (avec passage de paramètres en POST)
xhr.open("POST" ,serveur ,true);
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
xhr.send(parametres);
}
}
/*
* fin du moteur AJAX
*/
Et avec tout ça, je n'arrive pas à faire que les résultat soient dans un tableau, dans des lignes les unes après les autres.

Posté : 04 juil. 2007, 17:41
par orgerix
Enleve la ligne creerdiv, normalement tu n'en a pas besoin.

EDIT : j'ai repris tes codes (avec la fonciton creerDiv) et Il y a des réponses Ajax. IL ya des petites choses améliorer mais c'est un début.

Posté : 05 juil. 2007, 08:52
par béka
Bonjour, oui effectivement, il n'y a pas besoin de la ligne creerdiv. Les résultats s'affichent à la suite. Mais d'ailleurs quand l'internaute fait une nouvelle recherche, comment faire pour effacer ces résultats précédents ?

[EDIT] en mettant ceci :

Code : Tout sélectionner

reponse.innerHTML = reponse.innerHTML + xhr.responseText;
effectivement, on écris à la suite les résultats trouvés.

Mais les résultats enregistrés ne s'effacent pas lors d'une nouvelle requête. C'est à dire que si je clique plusieurs fois sur le bouton search avec les mêmes critères sélectionnés, j'aurais à chaque fois les résultats (plusieurs fois les mêmes résultats).

Comment faire pour effacer les résultats d'une requête précédente ?