Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: advAjax - suggestion
Forum PHP.pl > Forum > XML, AJAX
JaRoPHP
WITAM!!!

Widziałem kilka projektów AJAX typu suggestion tool i sam postanowiłem zbudować podobny w oparciu o bibliotekę advAJAX.
Działanie jest proste - użytkownik wpisuje słowo, jeśli w bazie danych są podobne, to wyświetlane jest okno podpowiedzi, jesli nie,
to musi sam dokończyć wpisywanie smile.gif. Następnie słowo to dodawane jest do bd (jeśli go nie było).
Efekt pracy przedstawię poniżej, ale nie jest to w 100% działający projekt, ponieważ po wyborze słowa (jak są polskie litery, np. brązowy),
a następnie skasowaniu z niego kilku ostatnich liter - w oknie podpowiedzi nie wyświetla się nic, dopóki są polskie litery (miły wyjątek stanowi przeglądarka IE).
Jak ktoś będzie wiedział jak to rozwiazać to proszę, oraz proszę o wypowiedzenie się na temat tego "narzędzia"...

Pliki wchodzące w skład projektu:

Oczywiście wymagany jest plik advajax.js

Baza danych z której są pobierane słowa:
  1. CREATE TABLE words
  2. (
  3. id int AUTO_INCREMENT,
  4. value varchar(50),
  5. PRIMARY KEY (id)
  6. )type=MyISAM;
  7.  
  8. INSERT
  9. INTO words
  10. VALUES("1", "czerwony");
  11. INSERT
  12. INTO words
  13. VALUES("2", "pomarańczowy");
  14. INSERT
  15. INTO words
  16. VALUES("3", "żółty");
  17. INSERT
  18. INTO words
  19. VALUES("4", "zielony");
  20. INSERT
  21. INTO words
  22. VALUES("5", "niebieski");
  23. INSERT
  24. INTO words
  25. VALUES("6", "błękitny");
  26. INSERT
  27. INTO words
  28. VALUES("7", "fioletowy");
  29. INSERT
  30. INTO words
  31. VALUES("8", "brązowy");
  32. INSERT
  33. INTO words
  34. VALUES("9", "czarny");
  35. INSERT
  36. INTO words
  37. VALUES("10", "piaskowy");
  38. INSERT
  39. INTO words
  40. VALUES("11", "granatowy");
  41. INSERT
  42. INTO words
  43. VALUES("12", "seledynowy");
  44. INSERT
  45. INTO words
  46. VALUES("13", "biały");
  47. INSERT
  48. INTO words
  49. VALUES("14", "purpurowy");
  50. INSERT
  51. INTO words
  52. VALUES("15", "różowy");
  53. INSERT
  54. INTO words
  55. VALUES("16", "szary");
  56. INSERT
  57. INTO words
  58. VALUES("17", "srebrny");

Plik start.html zawierający prosty formularz:
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  2. <title>Suggestion advAjax</title>
  3. <meta http-equiv="Content-type" content="text/html; charset=iso-8859-2" />
  4. <script type="text/javascript" src="advajax.js"></script>
  5. <script type="text/javascript" src="suggest.js"></script>
  6. <link rel="stylesheet" href="css.css" type="text/css" />
  7. </head>
  8. <div id="inputBox">
  9.      <form action="add.php" method="post">
  10.      Poszukiwana fraza: <input type="text" id="string" name="string" autocomplete="off" onkeyup="showWords(); return false;" />
  11.      <input type="submit" value="Dalej" id="button" />
  12.      </form>
  13.      <div id="suggestion"></div>
  14. </div>
  15.  
  16. </body>
  17. </html>

Plik suggest.js wykorzystujący AJAX:
Kod
function $(id) {
    return document.getElementById(id);
}

// zmiana koloru wiersza (onmouseover)
function highlight() {
    this.className = "highlight";
}

// zmiana koloru wiersza (onmouseout)
function unHighlight() {
    this.className = "unhighlight";
}

// akceptacja podpowiedzi
function selectWord() {
    $("string").value = this.innerHTML;
    $("suggestion").style.display = "none";
}

// konwersja dokumentu XML na elementy span
function parseRecords(xml) {
    // zapisanie danych bieżącej strony
    with (xml.getElementsByTagName("words").item(0)) {
        var count = getAttribute("count")*1;
    }
    
    if(count == 0)
        $("suggestion").style.display = "none";
    
    // wpisanie odpowiednich słów do pola suggestion
    var space = $("suggestion");
    space.innerHTML = ""; // wyczyszczenie poprzedniej listy
    var word = xml.getElementsByTagName("word");
    for (i = 0; i < word.length; i++) {
        spanNode = document.createElement("span");
        spanNode.innerHTML = word[i].childNodes[0].nodeValue;
        spanNode.onmouseover = highlight;
        spanNode.onmouseout = unHighlight;
        spanNode.onmousedown = selectWord;
        space.appendChild(spanNode);
    }
}

// funkcja wywołująca skrypt php i pobierająca dokument XML
function showWords() {
    var string = $("string").value;
    if(string) { // przy pustym polu nie następuje wysyłanie żądania
        advAJAX.get({
            url : "suggest.php?prefix="+$("string").value,
          
            onInitialization : function() {
                $("suggestion").style.display = "block";
            },
        
            onSuccess : function(obj) {
                parseRecords(obj.responseXML);
            },
        
            onError : function(obj) {
          alert("Nie można nawiązać połączenia z serwerem.");
            }
        });
    }
    else { // ukrycie warstwy
  $("suggestion").style.display = "none";
    }
}

Plik suggest.php (wywoływany przez suggest.js)
  1. <?php
  2. header('Content-type: text/xml; charset=iso-8859-2');
  3.  
  4. $dbhost = 'localhost';
  5. $dbuser = 'root';
  6. $dbpass = 'l';
  7. $db = 'ajax';
  8. $dbtable = 'words';
  9.  
  10. @mysql_connect($dbhost, $dbuser, $dbpass);
  11.  
  12. $prefix = @$_GET['prefix'];
  13. $query = @mysql_query('SELECT * FROM words WHERE value LIKE "'.$prefix.'%" ORDER BY value LIMIT 0,20');
  14. $countRow = @mysql_num_rows($query);
  15.  
  16. echo '<?xml version="1.0" encoding="iso-8859-2"?>';
  17. echo '<words count="'.$countRow.'">';
  18. while ($row = @mysql_fetch_assoc($query)) {
  19. echo '<word>'.htmlspecialchars($row['value']).'</word>';
  20. }
  21. echo '</words>';
  22. ?>

Plik add.php odpowiedzialny za dodanie słowa do bazy danych:
  1. <?php
  2.  
  3. $dbhost = 'localhost';
  4. $dbuser = 'root';
  5. $dbpass = '';
  6. $db = 'ajax';
  7. $dbtable = 'words';
  8.  
  9. @mysql_connect($dbhost, $dbuser, $dbpass);
  10.  
  11. $query = @mysql_query('SELECT * FROM words WHERE value = "'.$_POST["string"].'"');
  12. if(@mysql_num_rows($query) ==0)
  13. $query = @mysql_query('INSERT INTO words VALUES("NULL", "'.$_POST["string"].'")');
  14.  
  15. header("Location: start.html");
  16. ?>

Oraz plik kaskadowych arkuszy stylów (css.css):

html, body{
padding: 0;
margin: 0;
font-family : Arial, sans-serif;
}
Kod
#inputBox {
    border: 3px double #000;
    background: #CCF;
    margin: 1em;
    padding: 0.5em;    
}

#suggestion {
    background: #FFF;
    height: 100px;
    width : 200px;
    border: 1px solid #000;
    margin: 0.1em;
    position: relative;
    left: 140px;  
    overflow : auto;
    float : left;
    display: none;
    cursor: default;
}

#suggestion span {
    display: block;
}

#string {
    width : 200px;
    font-size : 13px;
    padding-left : 2px;
    border: 1px solid #000;
}

#button {
    width: 100px;
    color: #FFF;
    background: #000;
    border: 1px solid #FFF;
}    

.highlight {
    background-color: #69F;
    color: #FFF;
}

.unhighlight {
    background-color: #FFF;
    color: #000;
}

Gdyby nie omówiona wada, byłbym zadowolony z funkcjonalności (pomimo, że wystarczy sam js, ale czego sie nie robi dla praktyki smile.gif).
anAKiN
Argument
Kod
url : "suggest.php?prefix="+$("string").value

jest błędny - każdy parametr żądania powinien być przepuszczony przez funkcję encodeURIComponent i właśnie po to w AdvancedAJAX jest argument parameters:
Kod
url : 'suggest.php',
parameters : {
  prefix : $('string').value
}

lub, jako, że parametr o nazwie "prefix" nie jest rozpoznawany przez AdvancedAJAX:
Kod
url : 'suggest.php',
prefix : $('string').value
JaRoPHP
Dzięki anAKiN za sugestie, choć nie do końca rozumiem.
Otóż na stronie na której prezentujesz advAJAX jest przykład,
Cytat
w którym jeden z argumentów został umieszczony bezpośrednio w argumencie url

:
Kod
advAJAX.get({
    url: "http://www.example.com/page.html?var1=value1",
    queryString : "var2=value2",
    parameters : {
      "var3" : "value3"
    },
    onSuccess : function(obj) { alert(obj.responseText); },
    onError : function(obj) { alert("Error: " + obj.status); }
});


Czy więc argument var1=value1 jest źle podany?

Oraz kolejne pytanie, jaka jest różnica między podanymi przez Ciebie rozwiązaniami.
Które jest lepsze i powinno zawsze działać?
anAKiN
Cytat
Czy więc argument var1=value1 jest źle podany?

Jest dobrze podany, ale zauwaz, ze jest to stala "value1", ktora nie musi byc przepuszczona przez encodeURIComponent, bo to zwyczajnie widac i znamy jej wartosc.
Przesylana przez ciebie wartosc do skryptu php jest zalezna od tego, co poda uzytkownik, takze nie masz pewnosci, ze nie znajda sie tam znaki, ktore musza byc przekonwertowane przed wyslaniem.

Dwie opisane metody sa zamienne. Druga jest o tyle gorsza, ze wprowadza balagan w kodzie i uniemozliwia stworzenie parametru o nazwie, ktora pozpoznaje AdvancedAJAX, np. "url". Lepsze jest wiec wykorzystanie parametru "parameters".
JaRoPHP
Dzięki anAKiN!

A teraz moze ktoś wie, jak rozwiązać problem z polskimi znakami...
mariuszn3
Polskie znaki, w ogóle jakiekolwiek ciągi znaków jak już sugerował Ci Anakin powinenes przepuszczać przez encodeURIComponent().. ewentualnie gdy przesyłasz dane poprzez POST to zdaje się musisz juz ich tym filtrować (ale tego nie jestem na tę chwilę pewien). Też pracuj w kodowaniu utf-8.. oszczędzi Ci to wielu problemów własnie związanych z kodowaniem znaków.
JaRoPHP
No tak, ale z kodowaniem utf-8 też są problemy - nie wszytskie edytory zapisują, lub odczytują poprawnie tak zapisane dokumenty...
dyktek
przez encodeURIComponent() musze przepuścić to co jest zwracane czyli np tak
  1. encodeURIComponent(obj.responseText)

bo w ten sposób jak robie to nada widze krzaki tylko teraz zamiast questionmark.gifquestionmark.gifquestionmark.gif zwraca %EF%BF%BD%EF%BF%BD
mariuszn3
Cytat
No tak, ale z kodowaniem utf-8 też są problemy - nie wszytskie edytory zapisują, lub odczytują poprawnie tak zapisane dokumenty...

No to trzeba korzystać z takich edytorów, które radzą sobie z UTF-8 (nawet zwykły notatnik to potrafi).
Cytat
przez encodeURIComponent() musze przepuścić to co jest zwracane czyli np tak
  1. <?php
  2.  
  3. encodeURIComponent(obj.responseText)
  4.  
  5. ?>

bo w ten sposób jak robie to nada widze krzaki tylko teraz zamiast questionmark.gifquestionmark.gifquestionmark.gif zwraca %EF%BF%BD%EF%BF%BD

encodeURIComponent() jest to funkcja javascript nie php. Przez nią przepuszczasz ciągi znaków, które wysyłasz na serwer (do skryptu php).
dyktek
no tak masz racje przez pomyłke wstawiłem to w bbcode php


no ale dane przenoszone bez tej funkcji są zapisywane w bazie w porządku dopiero gdy wyjmuje dane z bazy i chce wstawić je w pole teksowe to w to pole zamiast znaków PL są te krzaki



  1. iden.innerHTML = '<input id="s" name="s" type="text" value="'+obj.responseText+'" onBlur="upKatNa(''+ide+'', 's', ''+kat+'', ''+param+'');" style="border:1px solid #535353; width:100%;" />';
i zwraca zamiast zanków pl questionmark.gifquestionmark.gifquestionmark.gif

robie tak
  1. iden.innerHTML = '<input id="s" name="s" type="text" value="'+encodeURIComponent(obj.responseText)+'" onBlur="upKatNa(''+ide+'', 's', ''+kat+'', ''+param+'');" style="border:1px solid #535353; width:100%;" />';
zwraca %EF%BF%BD%EF%BF%BD%E6%B6%B6%EF%BF%BD
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.