SitePoint Sponsor

User Tag List

Results 1 to 14 of 14
  1. #1
    SitePoint Addict
    Join Date
    Jun 2007
    Posts
    396
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)

    Optimising my javascript/Ajax code

    Hi guys,

    I've wrote some Ajax (heavily inspired by the Livesearch on W3Tutorials may I add :P) that searches an xml document and outputs information accordingly.

    It works kinda fine, but since the xml document is 200kb long, and it's looping through it like something crazy, it's taking a few minutes for every search and I've just managed to temporarily crash the web server :P

    I'm after something that'll hopefully optimise the code, but I can't think for the life of me what the best way around this is.

    Here's my Javascript code at present:

    Code JavaScript:
    <?php
    $xmlDoc = new DOMDocument();
    $xmlDoc->load("get_xml.xml");
     
    $x=$xmlDoc->getElementsByTagName('user');
     
    //get the q parameter from URL
    $q=$_GET["q"];
     
    //lookup all links from the xml file if length of q>0
    if (strlen($q) > 0)
    {
    $hint="";
    for($i=0; $i<($x->length); $i++)
     {
     $y=$x->item($i)->getElementsByTagName('name');
     $z=$x->item($i)->getElementsByTagName('collar');
     if ($y->item(0)->nodeType==1)
      {
      //find a link matching the search text
      if (stristr($y->item(0)->childNodes->item(0)->nodeValue,$q))
       {
       if ($hint=="")
        {
        $hint="<a href='#' onclick='employee_form.Line_Manager_Staff_No.value=" . 
        $z->item(0)->childNodes->item(0)->nodeValue . 
        ";checknumber('Line_Manager_Staff_No','displayusername');'>" . 
        $y->item(0)->childNodes->item(0)->nodeValue . "</a>";
        }
       else
        {
        $hint=$hint . "<br /><a href='#' onclick='employee_form.Line_Manager_Staff_No.value=" . 
        $z->item(0)->childNodes->item(0)->nodeValue . 
        ";checknumber('Line_Manager_Staff_No','displayusername');'>" . 
        $y->item(0)->childNodes->item(0)->nodeValue . "</a>";
        }
       }
      }
     }
    }
     
    // Set output to "no suggestion" if no hint were found
    // or to the correct values
    if ($hint == "")
     {
     $response="no suggestion";
     }
    else
     {
     $response=$hint;
     }
     
    //output the response
    echo $response;
    ?>
    Any help would be awesome, thank you.

  2. #2
    SitePoint Enthusiast cheap freelancer's Avatar
    Join Date
    Jun 2007
    Posts
    99
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Move $x->length out of for loop

  3. #3
    SitePoint Addict
    Join Date
    Jun 2007
    Posts
    396
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    Thanks, so that it reads like this?

    Code:
    $x->length;
    for($i=0; $i<($x); $i++)
    Oh btw, here's my actual js file:

    Code JAVASCRIPT:
    var xmlHttp
     
    function showResult(str)
    {
    if (str.length==0)
     { 
     document.getElementById("livesearch").
     innerHTML="";
     document.getElementById("livesearch").
     style.border="0px";
     return
     }
     
    xmlHttp=GetXmlHttpObject()
     
    if (xmlHttp==null)
     {
     alert ("Browser does not support HTTP Request")
     return
     } 
     
    var url="employee/live/livesearch.php"
    url=url+"?q="+str
    url=url+"&sid="+Math.random()
    xmlHttp.onreadystatechange=stateChanged 
    xmlHttp.open("GET",url,true)
    xmlHttp.send(null)
    } 
     
    function stateChanged() 
    { 
    if (xmlHttp.readyState==4 || xmlHttp.readyState=="complete")
     { 
     document.getElementById("livesearch").
     innerHTML=xmlHttp.responseText;
     document.getElementById("livesearch").
     style.border="1px solid #A5ACB2";
     } 
    }
     
    function GetXmlHttpObject()
    {
    var xmlHttp=null;
    try
     {
     // Firefox, Opera 8.0+, Safari
     xmlHttp=new XMLHttpRequest();
     }
    catch (e)
     {
     // Internet Explorer
     try
      {
      xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
      }
     catch (e)
      {
      xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
      }
     }
    return xmlHttp;
    }

  4. #4
    SitePoint Wizard
    Join Date
    Nov 2004
    Location
    Nelson BC
    Posts
    2,310
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    XML is notoriously slow - it would be quicker if your data was stored in a database and you did a sql lookup.

    If you absolutely can't, maybe you can do a lookup using XPath to return only the xml nodes you want instead of manually looping and checking each one.

  5. #5
    SitePoint Addict
    Join Date
    Jun 2007
    Posts
    396
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    D'oh, many thanks for the reply, but yes that would be absolutely ideal!

    All of the information is currently stored within a database and I'm currently trying to work out how to extract the information to the XML file on a daily basis, if I can bypass this and extract the information directly from the database (Oracle, fwiw) to the page that'd be utterly fantastic, especially if it'll be a lot quicker too!

    Is it a fairly easy process?

    Many thanks again

  6. #6
    SitePoint Wizard
    Join Date
    Nov 2004
    Location
    Nelson BC
    Posts
    2,310
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Yes it would be simple to convert this to use a database - not sure offhand of the syntax but check the PHP forum. Basically:
    - connect to oracle database with php
    - execute a query similar to:
    "select name, collar from users where name like '&#37;" . $q . "%'"
    - loop through the results and create your $hint

  7. #7
    SitePoint Addict
    Join Date
    Jun 2007
    Posts
    396
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    Awesome, thank you so much! I'll admit I'm completely new to a lot of this, but I'll definitely give it my best show, cheers

  8. #8
    SitePoint Addict
    Join Date
    Jun 2007
    Posts
    396
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    jimfraser, just curious, I currently have the following code to output the bulk of my XML:

    Code PHP:
    	    $xml_output .= "\t<user>\n";
    $xml_output .= "\t\t<collar>" . oci_result($sqlListings, "Gc_Staff_Number") . "</collar>\n";
    $xml_output .= "\t\t<name>" . oci_result($sqlListings, "Surname") . ", " . oci_result($sqlListings, "Forenames") . "</name>\n";
    $xml_output .= "\t</user>\n";

    Is that the section you would recommend I use/modify to create the hint?

    Thanks

  9. #9
    SitePoint Wizard
    Join Date
    Nov 2004
    Location
    Nelson BC
    Posts
    2,310
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Right - you want to create the $hint string which contains html to display, and then output it.

    It looks like oci_result is a recordset of sorts - so you'd loop through the recordset and create the <a> tags etc using the data contained.
    Code:
    if ($hint != "") {
    	$hint .= "<br />";
    }
    
    $hint .= "<a href='#' onclick='employee_form.Line_Manager_Staff_No.value=" 
    	. oci_result($sqlListings, "Gc_Staff_Number")
    	. ";checknumber('Line_Manager_Staff_No','displayusername');'>" 
    	. oci_result($sqlListings, "Surname") . ", " . oci_result($sqlListings, "Forenames")
    	. "</a>";

  10. #10
    SitePoint Addict
    Join Date
    Jun 2007
    Posts
    396
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    Huge thanks once again for the reply and the code, really appreciate it!

    I've thrown something together, it isn't working at the moment, I presume it's due to the second if statement although I'm not too sure... On a side note, what's 'displayusername'?

    Code PHP:
    <?php
     
    $network = new COM("WScript.Network");
    include_once('../../../functions/datalib.php');
     
    $db = new oracleClass();
    $conn = $db->connect();
     
    //get the q parameter from URL
    $q=$_GET["q"];
     
    //lookup all links from the xml file if length of q>0
    if (strlen($q) > 0)
    {
    	$hint="";
     
    	// connect to the database
    	$sqlstatement = 'select * from TEST."WFO_REPORTS_ALLEMPS" order by "Surname", "Forenames"';
    	$sqlListings = OCI_Parse($conn, $sqlstatement);
     
    	OCI_Execute($sqlListings);
    	while(OCI_Fetch($sqlListings)) {
     
    		$name = oci_result($sqlListings, "Forenames") . ($sqlListings, "Surname")
     
    		//find a link matching the search text
    		if (strchr($name,$q))
    		{
    			if ($hint != "") {
    				$hint .= "<br />";
    			}
     
    			$hint .= "<a href='#' onclick='employee_form.Line_Manager_Staff_No.value=" 
    			. oci_result($sqlListings, "Gc_Staff_Number")
    			. ";checknumber('Line_Manager_Staff_No','displayusername');'>" 
    			. oci_result($sqlListings, "Surname") . ", " . oci_result($sqlListings, "Forenames")
    			. "</a>";
    		}
    	}
    }
     
    // Set output to "no suggestion" if no hint were found
    if ($hint == "")
     {
     $response="No user found.";
     }
    else
     {
     $response=$hint;
     }
     
    //output the response
    echo $response;
    ?>

    Thanks again, and help would be ace, I think I'm getting kinda close with this now

  11. #11
    SitePoint Wizard
    Join Date
    Nov 2004
    Location
    Nelson BC
    Posts
    2,310
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    You don't need to check each record in the database to see if it's a match if you use a better SQL query that does it for you:

    'select * from TEST."WFO_REPORTS_ALLEMPS" WHERE Surname=' . $q . ' order by "Surname", "Forenames"';

    Then you can eliminate
    //find a link matching the search text if (strchr($name,$q))

  12. #12
    SitePoint Addict
    Join Date
    Jun 2007
    Posts
    396
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    Huge thanks for the info, that's a very good idea actually and will help improve the efficiency no end! For some reason though it still isn't working, when I type something into the box nothing is displayed

    Also, a complete longshot, is there anyway to get it so that it'll select according to both the sirname and first name? Fore example the name John Smith, if you type in John it'll bring up the name, and likewise if you type in Smith it'll bring up the name?

  13. #13
    SitePoint Wizard
    Join Date
    Nov 2004
    Location
    Nelson BC
    Posts
    2,310
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    All of that can be accomplished by using the correct SQL query. That (and php heh) is out of the scope of this particular forum however, and something that perhaps could be answered better by a real SQL expert.

  14. #14
    SitePoint Addict
    Join Date
    Jun 2007
    Posts
    396
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    Ah thank you, I'll do a post on the PHP forum then (or the SQL one!) and see how I get on.

    Once again a massive thanks for all of your help, I really, really appreciate it!


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •