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.
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… 😉
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>
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?
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) )
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…
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
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 🙂
Oops, forgot to remove my site so that the email would show up 🙂
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.
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.
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
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)
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.