Splitting AJAX Returned Data

21 Oct

I’m working on a new product site for the company I work for at the moment and am trying to utilise as much sensible AJAX as possible in order to enhance the usability of the pages without destroying the IA or accessibility.

One of the intriguing challenges I came across today was using innerHTML in a more refined way.

Lets say I have data I need to return from a PHP script that I need to funnel into separate markup elements when they’re returned to the page. How to do this perplexed me for awhile – my experiences of innerHTML was that results are returned in a big chunk.

First lets have a look at the PHP:

$type = $_GET['type'];

if($type == "1"){
	echo "Vat No";
        echo "";
}

And the markup I wanted to receive each of these two strings was as follows:

<p id="label"></p>
<p id="inputElem"></p>

*NB: No, I didn’t really put my form elements into p tags, this is a smaller example of what I did.*

Obvious what I want to do isn’t it? I want the phrase to go in the ‘label’ id element and the field to go in the ‘inputElem’ element. Here’s the Javascript I started with. First we set up the AJAX connection:

// 'xmlhttp' variable will hold the XMLHttpRequest object
var xmlhttp = false;
        
// If the user is using Mozilla/Firefox/Safari/etc
if (window.XMLHttpRequest) {
        xmlhttp = new XMLHttpRequest();
        xmlhttp.overrideMimeType('text/xml');
}

// If the user is using IE
else if (window.ActiveXObject) {
        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}

And after that I declare a function that can be called onclick later:


function getUK() {
	var lB = document.getElementById("label");
	var iE = document.getElementById("inputElem"); 
 
	var url = "_inc/vat.php?type=1";    
	xmlhttp.open("GET", url, true);
    
	xmlhttp.onreadystatechange = function() {
		if(xmlhttp.readyState == 4) {

			var r = xmlhttp.responseText
			lB.innerHTML = r;

		}else{
			lB.innerHTML = "Error";
		}				
	};
	xmlhttp.send(null);  
}

Which is crap. I can’t get both elements in and seperate them. So what we need to do is make our string passed through from PHP to actually be an array object that we can split. So we change the above PHP to this:

$type = $_GET['type'];

if($type == "1"){
	echo "Vat No|";
}

Now we can refer to the responseText as an array like so:


function getUK() {
	var lB = document.getElementById("label");
	var iE = document.getElementById("inputElem"); 
 
	var url = "_inc/vat.php?type=1";    
	xmlhttp.open("GET", url, true);
    
	xmlhttp.onreadystatechange = function() {
		if(xmlhttp.readyState == 4) {

			var r= xmlhttp.responseText.split("|");
			lB.innerHTML = r[0];
			iE.innerHTML =  r[1];

		}else{
			lB.innerHTML = "Error";
		}				
	};
	xmlhttp.send(null);  
}

The important lines are:

var r= xmlhttp.responseText.split("|");
lB.innerHTML = r[0];
iE.innerHTML =  r[1];

in which we split the string on the ‘|’ character (or any other character you care to use yourself) and then refer to individual elements in the array in the appropriate place.

13 Responses to “Splitting AJAX Returned Data”

  1. Matthew Pennell October 22, 2005 at 10:56 #

    This might be a stupid question, but why don’t you have the PHP script return the results in XML instead of an HTML block?

    Something like this:

    <form>
    <label>Vat No</label>
    <input>
    <type>text</text>
    <name>uk_vat</name>
    <id>uk_vat</id>
    </field>
    </form>

    It looks a bit more cumbersome than just returning the HTML, but it’s much more flexible – you just write one handler script and then it can work with any form setup.

    It’s not really Ajax if you’re not using XML, either… 😉

  2. Matthew Pennell October 22, 2005 at 10:56 #

    Dammit, I knew Textile would screw up my formatting!

    Second try:

    <form>
    <label>Vat No</label>
    <input>
    <type>text</text>
    <name>uk_vat</name>
    <id>uk_vat</id>
    </field>
    </form>

  3. Michael Mahemoff October 25, 2005 at 01:16 #

    Matthew, what’s wrong with plain old text format? split() then s[0] s[1] etc is good enough most of the time, isn’t it?

  4. Kev October 25, 2005 at 04:20 #

    I’d guess Matthew would say (and I’d agree) that with _large_ amounts of data, doing it with XML would be less intensive than iterating through an array (or quasi-array).

    To be honest though, I think the string.split() method is attractive because its easy – I have no idea how to use the XML method i.e. return the XML as a string and place it in the desired element but I’d love to see a walkthrough on it (hint hint Mr Pennell ;o) )

  5. Matthew Pennell October 25, 2005 at 10:40 #

    Ask and you shall receive:

    http://www.xml.com/pub/a/2005/02/09/xml-http-request.html

    The main benefit of doing it that way is that you can then use all your DOM functions like childNode, nextSibling, etc. to traverse the XML object.

    Sure, the string.split method works fine, but if you are likely to add more and more complexity to a system, there will eventually come a time when you are writing such convoluted string manipulation scripts that you might as well have gone with XML in the first place…

  6. Gonzalo October 25, 2005 at 15:15 #

    How about returning Javascript objects (json)?
    Something like:
    { lB: “Vat No”,
    iE: “”,
    etc: “whatever” }

    you then eval+asign it and access it with .lB, .iE, .etc

  7. Joe Clay October 30, 2005 at 18:43 #

    If anyone would like it, yesterday I wrote a class that will form proper XML (except for entities that have attributes or are self-closing—I haven’t got to that yet). It will even include the proper tabbing for nested elements.

    I’d show it to you on my site except that my site has been down for the week 😦 You can email me though, since I’ve put another address up 🙂

  8. Joe Clay October 30, 2005 at 18:44 #

    Oops, forgot to remove my site so that the email would show up 🙂

  9. Joe Clay October 30, 2005 at 18:45 #

    Ok, you’re killing me here (but at least you hide email addresses from bots)…the email is my first name at hexfuse dot com.

  10. Kev October 30, 2005 at 19:40 #

    lol…sorry Joe :o)

    If you’d like to guest-blog an entry for here explaining your class then I’d be happy to put it up with a link to wherever you’d like – in any respect I’d like to see it.

  11. imran November 4, 2005 at 10:34 #

    Hi

    With all the design concepts and other dross floating around in my head, I’ve become completely paralyzed on what to do next.

    On one hand, I want to do something and I want to do it right. On the other hand, I don’t know what this “right” is.

    I want to use controllers, but I don’t really know what they are. Right now, I have a bunch of cobbled together pages. I *could* move them into classes, which would probably help factoring them into more controller oriented things, but I want to get it right the first time. And I know I can’t.

    In this mentality, I think I have bitten off more than I can chew. Every small step means more steps when the final design comes into place, but without small steps I cannot get anywhere.

    I need help.

    Imran Hashmi
    http://www.visionstudio.co.uk

  12. Son November 11, 2005 at 19:39 #

    Anyone has problem if the returned results are huge? Like about a 100k string? When I tried to loaded into innerHTML with such a large text, it failed (for some reason I haven’t been able to identify)

  13. Kev November 14, 2005 at 10:00 #

    I think anything with results over 100k would struggle to be returned without some kind of either preloader or – preferably – breaking the data down into manageable chunks.

Comments are closed.

%d bloggers like this: