AutoComplete Widget

أكتب الكلمة العربية التي تريد ترجمتها:


Traditional search:
A search user interface component consists of a text field and a “search” button. User types and when finished typing, he presses “search”. Then the results are displayed. If user misspells a word or does not find any useful results, then user must correct search term in input field and press “search” button again.

Problems here involve that people often misspells words. Google registered 593 ways of spelling Britney Spears, and a study (that we mentioned earlier) showed that 3% of all searches are misspelled. (I wonder if that number has raised since 1997). Jakob Nielsen found that only 51% find what they’re looking for in the first search.

That concludes that users are likely to refine results when searching. Refining results multiple times can be tedious using traditional search.

Live search:
The search user interface is identical to traditional search. But results are fetched whenever the user “hesitates” — for instance stop typing for a brief moment. An example of this is Google Suggest where the most popular results are presented as-you-type.

Google suggest autocomplete feature

The user experience is very different that traditional search: Here you type, hesitate, and get results. This has some benefits:

  • Relevant alternatives are presented as you type, so the best match can be picked immediately.
  • Its easy to refine your search: Just continue typing
  • If the search typed is too narrow its easy to press backspace and remove characters.
  • In the better implementations (like Google Suggest above), the best match is highlighted in the input field. In this way, the user can press “enter” and immediately go to the content page. Traditional search involves an extra click on the results page.

Live search can be a big time saver for a user, especially considering that at 49% of all searches will be refined. Furthermore, misspellings can be corrected immediately (there is no need to wait until the results show up.

Any system designer should consider it, given the performance advantages it can give for the end user. On the downside, live search requires more processing power as multiple searches are performed every second (depending on setup of course).


Source of Arabic-English dictionary data:
The Arabic-English dictionary is essentially a morphological dictionary with English translations. It does not contain usual part-of-speech information nor proper citation forms. Instead, an entry key is a morphological stem, typically a sub-string of an inflected word. All stem variants for the same word are listed. Each entry contains a morphological category (number of the inflectional paradigm for that stem, field. The following table shows the common stem categories:

  • 001..025 Common noun stems without orthographic change
  • 026..055 Common noun stems with orthographic change
  • 056..057 Function Words
  • 058..059 Proper Noun stems
  • 060..081 Perfect verbs stems
  • 082..088 Perfect/Imperfect verb stems
  • 089..129 Imperfect verb stems
The Arabic-English dictionary file made available for download is in XML format and contains 122920 entries including the Arabic proper names.

For more information, please see those URL's:
http://crl.nmsu.edu/Resources/lang_res/ArabicMorphology-1.pdf
http://crl.nmsu.edu/Resources/lang_res/arabic.html

To download dictionary XML file:
http://crl.nmsu.edu/Resources/dictionaries/download.php?lang=Arabic


Please find below the script I wrote to import previouse XML data file and export same data to MySQL database:

<?php
   mysql_connect
('localhost','root','');
   
mysql_select_db('test');

   
$file  'dictionary.xml';
   
$depth = array();
   
$loop  0;
   
$ord   0;
   
$sql   '';
   
$sqlvalues '';
   
$createTbl '';
   
$prev_ord  0;

   function 
startElement2($parser$name$attrs)
   {
       global 
$depth$loop$ord$sql$createTbl;
       if(
$depth[$parser] == 1){
          
$loop++;
          
$sql "INSERT INTO `$name` (";
       }
       if(
$depth[$parser] == && $loop == 1){
          
$createTbl "CREATE TABLE `$name` (";
       }
       if(
$depth[$parser] == && $loop == 1){
          
$createTbl .= "`$name` VARCHAR(255),";
       }
       if(
$depth[$parser] == 2){
          
$ord++;
          
$sql .= "`$name`,";
       }
       
$depth[$parser]++;
   }

   function 
characterData2($parser$data)
   {
       global 
$depth$ord$prev_ord$sqlvalues;
       
$data addslashes($data);

       if(
$depth[$parser] == && $ord == && $prev_ord != $ord){ 
          
$sqlvalues " VALUES ("
       }

       if(
$depth[$parser] == && $prev_ord != $ord){ 
          
$sqlvalues .= "'$data',"
       }

       if(
$depth[$parser] == && $prev_ord == $ord){ 
          
$sqlvalues substr($sqlvalues,0,strlen($sqlvalues)-2)."$data',"
       }

       if(
$depth[$parser] == 3){ $prev_ord $ord; }
   }

   function 
endElement2($parser$name)
   {
       global 
$depth$loop$ord$sql$sqlvalues$createTbl;
       
$depth[$parser]--;
       if(
$depth[$parser] == && $loop == 1){
          
$createTbl substr($createTbl0strlen($createTbl)-1
          
$createTbl .= ") TYPE=MyISAM";
          
mysql_query($createTbl) or die(mysql_error());
       }
       if(
$depth[$parser] == 1){
           
$ord  0;
           
$sql  substr($sql0strlen($sql)-1) . ")" 
           
$sql .= substr($sqlvalues0strlen($sqlvalues)-1) . ")";
           
mysql_query($sql) or die(mysql_error());
       }
   }

   
$xml_parser xml_parser_create();
   
xml_set_element_handler($xml_parser"startElement2""endElement2");
   
xml_set_character_data_handler($xml_parser"characterData2");

   if (!(
$fp fopen($file"r"))) {
      die(
"could not open XML input");
   }

   while (
$data fread($fp4096)) {
      if (!
xml_parse($xml_parser$datafeof($fp))) {
         die(
sprintf("XML error: %s at line %d",
                      
xml_error_string(xml_get_error_code($xml_parser)),
              
xml_get_current_line_number($xml_parser)));
      }
   }
   
xml_parser_free($xml_parser);
   
mysql_close();
   echo 
'Done :-)';
?>