views:

32

answers:

2

Hi all,

I currently have a method whereby there is an

<input type="text" id="politician" name="politician" 
onkeyup="showResult(this.value)" value="Enter a politician's name"/>

tag. In that same file that includes the input tag, there is a link to an external javascript file called ajax.js

The contents of that file are as follows:

function showResult(str)
{
    if (str.length==0)
    { 
        document.getElementById("livesearch").innerHTML="";
        document.getElementById("livesearch").style.border="0px";
        return;
    }

    if (window.XMLHttpRequest)
    {// code for IE7+, Firefox, Chrome, Opera, Safari
        xmlhttp=new XMLHttpRequest();
    } 
    else
    {// code for IE6, IE5
        xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
    }
    xmlhttp.onreadystatechange=function()
    {
        if (xmlhttp.readyState==4 && xmlhttp.status==200)
        {
            document.getElementById("livesearch").innerHTML=xmlhttp.responseText;
            document.getElementById("livesearch").style.border="1px solid #A5ACB2";
        }
    }
    xmlhttp.open("GET","livesearch.php?politician="+str,true);
    xmlhttp.send();
}

Basically, what the javascript file does is say that whenever a value is inserted into the input textbox, a request is sent to a php file called "livesearch.php" which parses the content of a hardcoded XML document called politicians.xml.

The livesearch.php file is as follows:

<?php

//Make sure we have something set before we go doing work
if (isset($_GET["politician"])){

    $q = $_GET["politician"];
    if ($q == "")
        exit();

    $xmlDoc = new DOMDocument();
    $xmlDoc->load("politicians.xml");
    $x=$xmlDoc->getElementsByTagName('Politicians');

    $hint = "";   

    for($i=0; $i<($x->length); $i++)
    {
        $y=$x->item($i)->getElementsByTagName('name');
        $z=$x->item($i)->getElementsByTagName('url');
        $w=$x->item($i)->getElementsByTagName('location');
        $v=$x->item($i)->getElementsByTagName('position');
        $u=$x->item($i)->getElementsByTagName('photo');

        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 .= "<br />";
                }
                $hint .= "<h1 id='poli'><a id='blue' href='";
                $hint .= $z->item(0)->childNodes->item(0)->nodeValue;
                $hint .= "'>";
                $hint .= $y->item(0)->childNodes->item(0)->nodeValue;
                $hint .= "</a> <br /><a id='green'>";
                $hint .= $v->item(0)->childNodes->item(0)->nodeValue;
                $hint .= "</a><a id='green'>";
                $hint .= $w->item(0)->childNodes->item(0)->nodeValue;
                $hint .= "</a><br/><img width='30' height='40' id='schmidt' src='politicians/";
                $hint .= $u->item(0)->childNodes->item(0)->nodeValue;
                $hint .= ".png' /></h1>";
            }
        }
    }
}

// Set output to "no suggestion" if no hint were found
// or to the correct values
if($hint == "")
    echo "No suggestions";
else
    echo $hint;
?>

A friend of mine recently told me that JSON is a great alternative to XML because using JSON will put less strain on the server since it wont need to rely on PHP to parse the content of the XML document. The client would parse it instead.

But, I don't have enough experience with JSON to rewrite this function so that it works with a JSON document. Could anyone give me a few tips?

Any help would be greatly appreciated!

+1  A: 

Okay. I have a better idea of what you're doing now. First of all, I'd recommend using MongoDB (or maybe even Redis) to store the politicians, not an XML file. Think about it. Many people will be doing searches. If you're searching and then I try to search, I'll have to wait for you to finish accessing the XML file before I can. Databases should be used instead of files if many people will be accessing the same data concurrently. Even if just one person is searching, the file must be opened & closed every time you type something. Databases are much faster for this kind of thing, esp. MongoDB cause this happens all in ram. Just remember to put an index on what you're searching for, in this case, the politician's name.

Also, how many politicians are there? If it's less than 5,000 or so, you could do what Facebook used to do with your friends: insert a JSON array of all your friends' ids on the initial page load. So, you could output upfront a JSON array of all the politician's names & ids and then do the livesearch all on the client with JavaScript. Look into jQuery. http://ejohn.org/blog/jquery-livesearch/

If you're going to use AJAX, I recommend using jQuery as well because it's easier and takes care of browser compatibility issues for you. (Your code might not work in certain browsers.) And jQuery is also very helpful for other event handling and modifying the DOM, which you're also doing in your code. So, you could use it for a lot of things you're already doing a more difficult way with JavaScript. Also, use MongoDB (check out MongoHQ for free hosting). I also think you'll find Sinatra much easier than PHP, and it's free & easy to host on Heroku, and you can also hook it up to MongoDB. That's what I'm doing with acani http://github.com/acani/acani

http://webhole.net/2009/08/31/how-to-read-json-data-with-php/

Scala or Node.js would also be faster than PHP or Ruby.

Matt

MattDiPasquale
Thanks. I've learned how to parse JSON with php. But, now I sort of need to use PHP to dynamically output a result based upon what the user enters in the <input type="text" /> field.
Lance Newman
For example, in my JSON file, I have the names, locations, and positions of 586 politicians. It's all hard coded. So, lets just say one of the names of the politicians in my JSON file is Barack Obama.
Lance Newman
How do I make is so that if a user enters "Bara" or something similar to that in the input field, that it will automatically display Barack Obama's name along with his location, position in a division right under the <input /> tag
Lance Newman
Okay, I have 586 politicians and I'm predicting that number will increase as users will be submitting the names of more thru forms. I think I'll do what facebook did with the JSON array and use the jquery. Thanks a lot, dude.
Lance Newman
np. If users are going to be adding more, then use a database for the backend. Again, I strongly suggest MongoDB. That's what Foursquare is using. You should not be storing this stuff in a text file. Also, I suggest using WebSockets (checkout socket.io) with node.js for the fastest implementation. Then, have node talk to mongodb. PHP is dead.
MattDiPasquale
A: 

php can return a json object using echo json_encode($array). All you need is to format the data as a php array. The json object is accessable as jsonObject['php_array_keyname']

Sydenam