Buggy AJAX autocomplete feature

Κώδικας, πληροφορίες, ερωτήσεις και απαντήσεις σχετικές με την JavaScript.

Συντονιστές: WebDev Moderators, Super-Moderators

Απάντηση
lakritidis
Δημοσιεύσεις: 401
Εγγραφή: 04 Αύγ 2005 14:35
Τοποθεσία: Katerini
Επικοινωνία:

Buggy AJAX autocomplete feature

Δημοσίευση από lakritidis » 18 Ιούλ 2007 23:13

Σε μερικές υπηρεσίες όπως η ask.com, υπάρχει ένα πολύ ωραίο autocomplete (ή autosuggest) feature, που κάτω από το textbox, προτείνονται αυτόματα κάποια keywords.

Τι θέλουμε; Μόλις ο user πληκτρολογήσει τους τρεις πρώτους χαρακτήρες μίας λέξης ή φράσης, να γίνει αυτόματα ένα query σε μία MySQL database (μέσω ενός php script) και κάτω από το textbox να εμφανιστούν τα αποτελέσματα του query. Μόλις δώσει τον τέταρτο να γίνει νέο query klp.

Το παρακάτω σκριπτάκι κάνει αυτή τη δουλειά, παίρνει αυτό που έχει δώσει ο user, πραγματοποιεί το query και επιστρέφει τις 15 πιο συχνά χρησιμοποιούμενες keywords σε μορφή xml.

suggest.php

Κώδικας: Επιλογή όλων

<?php
$InputQuery = $_POST&#91;'query'&#93;;
include&#40;'constants.php'&#41;;
$cache = mysql_connect&#40;HOSTNAME, USERNAME, PASSWORD&#41; or trigger_error&#40;mysql_error&#40;&#41;, E_USER_ERROR&#41;; 
mysql_select_db&#40;DATABASE, $cache&#41;;
mysql_query&#40;'SET character_set_results="utf8"'&#41;;
mysql_query&#40;"SET CHARACTER SET utf8"&#41;;
mysql_query&#40;"SET NAMES 'utf8'"&#41;;

if &#40;strlen&#40;$InputQuery&#41; >= 3&#41; &#123;
	$select_suggest = sprintf&#40;"
	SELECT query_string, COUNT&#40;query_string&#41; FROM queries 
	WHERE query_string LIKE '%s'
	GROUP BY query_string
	ORDER BY COUNT&#40;query_string&#41; DESC 
	LIMIT 0, 15",
	mysql_real_escape_string&#40;$InputQuery&#41; . "%"&#41;;
	$suggest_query = mysql_query&#40;$select_suggest, $cache&#41; or die&#40;mysql_error&#40;&#41;&#41;;
	$row_suggest = mysql_fetch_assoc&#40;$suggest_query&#41;;
	$totalRows_suggest = mysql_num_rows&#40;$suggest_query&#41;;

	if &#40;class_exists&#40;'DOMDocument'&#41;&#41; &#123;
		$xmlDoc = new DOMDocument&#40;'1.0', 'utf-8'&#41;;
		$xmlDoc->formatOutput = true;
		$root = $xmlDoc->createElement&#40;'root'&#41;;
		$root = $xmlDoc->appendChild&#40;$root&#41;;
	&#125; else &#123;
		$xmlDoc  = '<?xml version="1.0" encoding="utf-8"?>';
		$xmlDoc .= '<root>';
	&#125;

	$key = 0;
	if &#40;$totalRows_suggest > 0&#41; &#123;
		do &#123;
			$key = $key + 1;
			if &#40;class_exists&#40;'DOMDocument'&#41;&#41;&#123;
				$item = $xmlDoc->createElement&#40;'item'&#41;;
				$item = $root->appendChild&#40;$item&#41;;
				$item->setAttribute&#40;'id', $key&#41;;
				$item->setAttribute&#40;'label', rawurlencode&#40;$row_suggest&#91;'query_string'&#93;&#41;&#41;;
			&#125; else &#123;
				$xmlDoc .= '<item id="' . $key . '" label="' . rawurlencode&#40;$row_suggest&#91;'query_string'&#93;&#41; . '"></item>';
			&#125;
		&#125; while &#40;$row_suggest = mysql_fetch_assoc&#40;$suggest_query&#41;&#41;;
	&#125;
	header&#40;"Content-type&#58;application/xml; charset=utf-8"&#41;;

	if &#40;class_exists&#40;'DOMDocument'&#41;&#41;&#123;
		echo $xmlDoc->saveXML&#40;&#41;;
	&#125; else &#123;
		$xmlDoc .= '</root>';
		echo $xmlDoc;
	&#125;
&#125;
?>
Οκ από την php. Τώρα σαν νέος στην ajax έψαξα κάτι παρόμοιο και βρήκα αυτό:

http://www.rafaeldohms.com.br/2006/07/1 ... jaxphp/en/

Τροποποίησα λίγο τον κώδικα για να το φέρω στα μέτρα μου. Δεν θα παραθέσω τον κώδικα για λόγους μεγέθους. όσοι επιθυμούν να βοηθήσουν μπορούν να τον δούνε εδώ:

http://quadsearch.csd.auth.gr/test/autocomplete.js

Το αποτέλεσμα δουλέυει, αλλά εχει ενα bug. Μόλις εμφανίζεται η λίστα με τα suggestions, χάνονται όλα τα select controls της φόρμας!

Δείτε το live
http://quadsearch.csd.auth.gr/test/index.php

Ο κώδικας αυτής της σελιδας είναι:

index.php

Κώδικας: Επιλογή όλων

<html>
<head>
<title>AJAX Suggestion</title>
<script src="autocomplete.js"></script>

<style type="text/css">
#acDiv&#123; border&#58; 1px solid #9F9F9F; background-color&#58;#F3F3F3; padding&#58; 3px; font-size&#58;10px; font-family&#58;Verdana, Arial, Helvetica, sans-serif; color&#58;#000000; display&#58;none; position&#58;absolute; z-index&#58;999;&#125;
#acDiv UL&#123; list-style&#58;none; margin&#58; 0; padding&#58; 0; &#125; 
#acDiv UL LI&#123; display&#58;block;&#125;
#acDiv A&#123; color&#58;#000000; text-decoration&#58;none; &#125;
#acDiv A&#58;hover&#123; color&#58;#000000; &#125;
#acDiv LI.selected&#123; background-color&#58;#7d95ae; color&#58;#000000; &#125;
</style>
</head>
<body onLoad="document.testform.query.focus&#40;&#41;">

<form action="#" method="POST" name="testform">
<input name="query" type="text" id="query" maxlength="200" size="45" />
<select name="sel1">
<option value="1">Select 1 Option 1</option>
<option value="2">Select 1 Option 2</option>
</select>
<select name="sel2" >
<option value="1">Select 2 Option 1</option>
<option value="2">Select 2 Option 2</option>
</select>&nbsp;&nbsp;&nbsp;
<input type="checkbox">test checkbox
<div id="acDiv"></div>
</form>

<img src="nopic" width="100" height="100" alt="We have a picture here">
<script language="javascript">
var AC = new dmsAutoComplete&#40;'query','acDiv'&#41;;
AC.clearField = false;
AC.chooseFunc = function&#40;id,label&#41; &#123; alert&#40;id+'-'+label&#41;; &#125;
</script>

</body>
</html>
Που οφείλεται αυτό ρε παιδιά;

Και κάτι ακόμα. Είναι αυτός ο κώδικας επικίνδυνος για memory leaks (κυρίως στον ΙΕ); Έχει κάποιο άλλο πρόβλημα ασφάλειας;

lakritidis
Δημοσιεύσεις: 401
Εγγραφή: 04 Αύγ 2005 14:35
Τοποθεσία: Katerini
Επικοινωνία:

Buggy AJAX autocomplete feature

Δημοσίευση από lakritidis » 02 Αύγ 2007 23:28

Παιδιά το πρόβλημα λύθηκε. Δεν ήταν bug, αλλά μια παράμετρος του js αρχείου. Απλά θέτουμε:

this.hideSelects = false;

και ολα οκ.

Intefix
Δημοσιεύσεις: 186
Εγγραφή: 22 Σεπ 2007 16:21
Τοποθεσία: Ηράκλειο Κρήτης
Επικοινωνία:

Buggy AJAX autocomplete feature

Δημοσίευση από Intefix » 01 Ιουν 2010 08:41

Σε ευχαριστούμε...
To constants.php τι περιέχει?
Ερώτημα αν έχω άντληση autocomplete από διαφορετικούς πίνακες μπορώ να το κάνω πιο έξυπνο; Συγγνώμη για την τόσο μακρυνή ερώτηση αλλά έπεσα επάνω σου...

Αυτό που θάθελα... φτιάχνω μια σελίδα καταχώρησης ...εκει λοιπόν έχω και ένα combobox που μου φέρνει σε μια λίστα "επώνυμο - 'ονομα - πατρώνυμο" από ένα πίνακα. Οι εγγραφές είναι πολλές και αργεί λίγο και έχω μεγάλη κίνηση για να φέρει 300000 εγγραφές πράγμα βλακεία.

Μπορεί το autocoplete να είναι σε select? να ξεκινάς πχ να συμπληρώνεις και στο 4-5 χαρακτήρα να φέρνει 15 εγγραφές; η να ανοίγεις τη λίστα και να επιλέγεις; η τιμή βέβαια που καταχωρείς να είναι το ID του πελάτη πχ...?

lakritidis
Δημοσιεύσεις: 401
Εγγραφή: 04 Αύγ 2005 14:35
Τοποθεσία: Katerini
Επικοινωνία:

Buggy AJAX autocomplete feature

Δημοσίευση από lakritidis » 01 Ιουν 2010 22:32

Intefix έγραψε:To constants.php τι περιέχει?
περιέχει τις πληροφορίες σύνδεσης με τη βάση username, password, database name κλπ
Intefix έγραψε:αν έχω άντληση autocomplete από διαφορετικούς πίνακες μπορώ να το κάνω πιο έξυπνο;
Δεν καταλαβαίνω τι εννοείς
Intefix έγραψε:Μπορεί το autocoplete να είναι σε select?
Δεν το έχω δοκιμάσει, κυρίως επειδή τα select controls παρουσιάζουν διαφορετικές συμπεριφορές από browser σε browser. Αν θέλεις να χρησιμοποιήσεις κατι σε select-style, ψάξε για καποιο activeX control.

Νομίζω ότι για τη δουλειά που το θελεις αυτο το auto-complete είναι ιδανικό. Μπορείς να το πάρεις copy-paste και με ελαφριές τροποποιήσεις (πχ πρέπει να αλλάξεις το sql query) να το προσαρμοσεις στις ανάγκες σου. Λειτουργεί και αυτό μόνο όταν ο χρήστης δώσει τρεις η περισσότερους χαρακτήρες και αν ορίσεις σωστά τους indexes στους tables, είναι και σχετικά γρήγορο.

Intefix
Δημοσιεύσεις: 186
Εγγραφή: 22 Σεπ 2007 16:21
Τοποθεσία: Ηράκλειο Κρήτης
Επικοινωνία:

Buggy AJAX autocomplete feature

Δημοσίευση από Intefix » 02 Ιουν 2010 07:43

lakritidis έγραψε:

Κώδικας: Επιλογή όλων

...SELECT query_string, COUNT&#40;query_string&#41; FROM queries 
	WHERE query_string LIKE '%s'
	GROUP BY query_string
	ORDER BY COUNT&#40;query_string&#41; DESC 
	LIMIT 0, 15"
Αυτό εννοείς είναι το ερώτημα; ΔΕΝ το πολυκαταλαβαίνω ...στο LIKE το s είναι το όνομα του input? ...στη δικιά μου περίπτωση όπως είπα έχω select...πχ

Κώδικας: Επιλογή όλων

<span>
<?php
$link = mysql_connect&#40;$dbhost, $dbuser, $dbpass&#41;;
$query ="SELECT * FROM bs_melos ORDER by lname, fname, f_fname";
$result = mysql_query &#40;$query&#41;;
echo "<select style="height&#58;22px; width&#58;150px; font-family&#58; Arial Narrow;" name=melos_id value=''>Μέλος</option>";
echo "<option value='-1'></option>\n";
						
while&#40;$row=@mysql_fetch_array&#40;$result, MYSQL_BOTH&#41;&#41;
&#123;
if&#40;$row&#91;'melos_id'&#93;==$relation_id&#41; $SELECTED="SELECTED";
else $SELECTED="";
echo "<option value='".$row&#91;'melos_id'&#93;."' $SELECTED>".$row&#91;'lname'&#93;."-".$row&#91;'fname'&#93;."-".$row&#91;'f_fname'&#93;."</option>\n";
&#125;
echo "</select>";// Closing of list box
?>
<label for="fname" style="text-align&#58;center" >Δημότης</label>
</span>

lakritidis έγραψε:...Δεν καταλαβαίνω τι εννοείς...
Εννοώ για κάθε autocomplete να υπάρχει ένα js και μια σύνδεση...
lakritidis έγραψε:
Intefix έγραψε:Μπορεί το autocoplete να είναι σε select?
Δεν το έχω δοκιμάσει, κυρίως επειδή τα select controls παρουσιάζουν διαφορετικές συμπεριφορές από browser σε browser...
Έχω βρει...κάτι εδώ παρουσιάζει αρκετό ενδιαφέρον...
Σε ευχαριστώ...

Απάντηση

Επιστροφή στο “JavaScript και Frameworks”

Μέλη σε σύνδεση

Μέλη σε αυτήν τη Δ. Συζήτηση: Δεν υπάρχουν εγγεγραμμένα μέλη και 2 επισκέπτες