Forum Moderators: open

Message Too Old, No Replies

AJAX ideas

What uses could you put this technology to?

         

isorg

3:55 pm on May 17, 2005 (gmt 0)

10+ Year Member



I have just added an AJAX tool on my site, basically, it validates a username when a user tries to log in.

Seems pretty cool, but I'm wondering what other uses AJAX could be put to. There are a number of examples on the web, but they are pretty academic/theoretical so far.

Implementing AJAX is actually quite straight forward, if you are already using some Javascript on your site and PHP/ASP on your server.

Bernard Marx

4:46 pm on May 17, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



It's true then. Someone comes up with a snappy term for a collection of technologies that have been used together for years, and now it's all over the place. I suppose it's a good thing, but I do wonder though whether it will end up confusing people like "DHTML". I have even seen tutorials that suggest DHTML is a language. For a while it seemed many people were under just that impression.

The intended use is for web applications, but ,traditionally, it's most commonly use is for tracking and spying.

BlobFisk

5:35 pm on May 17, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I have used xmHTTPrequest quite extensively in the web application that we are developing. One example would be inline searching for a person. So, we have a form where one of the fields is a person field. Rather than have to round trip the whole page, use and iFrame or force the user to type in the exact username, we do a background request to the database.

Another example is list filtering. Users can filter long lists based on keyword and we highlight the filter matches. This could be done inline, but we also allow for the user filtering on a RegEx!

This is a very powerful tool for web applications as Bernard Marx has said.

isorg

7:35 am on May 18, 2005 (gmt 0)

10+ Year Member



Thanks.

Having mastered the basics, I am now trying to do something a bit more complicated.

I want to add a input text box on a form, for example, "city name", and when the user types in a few letters, the form shows a drop-down list (populated from the database) from which to select possible cities. Like Google Suggest.

I can do the database bit, and I can do the XMLHTTPRequest part.

But I am puzzled how to populate and display the drop-down list with the returned database data.

Could anyone offer any tips/ideas?

Many thanks.

Bernard Marx

7:48 am on May 18, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I can do the database bit, and I can do the XMLHTTPRequest part.
But I am puzzled how to populate and display the drop-down list with the returned database data.

A perfect match. What form does the response come back in?
XML? - How is it structured?

Presumeably you are using an asynchronous request, so we could start from the callback function.

isorg

7:55 am on May 18, 2005 (gmt 0)

10+ Year Member



In my simple experiments so far (username authentication), I have been using .responseText to receive the server response and process it accordingly.

isorg

8:10 am on May 18, 2005 (gmt 0)

10+ Year Member



My thinking was:

1) Send the user input (i.e. first few letters of the city name) to the server as a XMLHttpRequest.send
2) The server queries the database, and returns as a string, say 10 most likely cities in the form "LondonXXXNew YorkXXXParisXXXSydneyXXXBeijingXXXTokyoXXXChicago" (this is just an example!)
3) The client receives this as .responseText, and explodes the string into an array around "XXX"
4) That array is used to populate the drop-down box, which presumably was css-hidden initially and then made visible when there is data available.

Is this sensible / is there a better way?

If I get this working, hopefully I'll reduce the number of mis-spellings of names, cities etc. users make when entering data into the database.

Bernard Marx

8:39 am on May 18, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Is this sensible? I'll give that a provisional "yes"

is there a better way? There always is.

This might be easier using the "create new script element" technique.
It wouldn't involve ActiveX in IE, but there may be other problems.

So I'm considering the XMLHTTP approach. I'll knock something together over coffee.

BTW. If possible, how about using \n as a delimiter?

London\nNew York\nParis

isorg

8:42 am on May 18, 2005 (gmt 0)

10+ Year Member



>how about using \n as a delimiter?

As you said, there's always a better way... :)

Thanks for your help!

isorg

9:28 am on May 18, 2005 (gmt 0)

10+ Year Member



You know, I think I am making progress on this. It's remarkably simple.

1) With CSS, you make a hidden DIV under the text input box in question, and assign them the same widths.

2) In the XMLHTTPRequest callback function,

document.getElementById("hiddenDIV").style.visibility="visible";
document.getElementById("hiddenDIV").innerHTML=xhr.responseText;

3) Server-side, format the return string as a <SELECT>, with each item as an <OPTION>.

So when the server passes the result back, it is displayed as a drop-down box which can be selected.

isorg

11:11 am on May 18, 2005 (gmt 0)

10+ Year Member



Yes, I can insert a SELECT box into the DIV, populated with the database result.

But the problem is that I cannot seem to generate any events for the SELECT. If the "onclick" or "onchange" could trigger an update of the original input box with a OPTION value, the job would be complete!

Maybe this is why you said it would need the "create new script element" technique?

Bernard Marx

12:16 pm on May 18, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



"create a new script element":
In IE you can load more JS code by simply changing the src attribute of a script element.
In Moz, I believe you need to create A new element. In either case, the src url could be a PHP script.

There are probably some kinks in this approach, not least the asynchronicity - without a built-in callback mechanism. So forget I mentioned it for now.

I hadn't thought of formatting, server-side, the whole markup for the SELECT. Right now, I can't see why it wouldn't work. It might be fine, with a little tweak. I always prefer a pure DOM approach - without using innerHTML. Each time innerHTML is changed the select is a 'new object'. There is also, at the back of my mind, the fact that strict XHTML 1.1 mode doesn't allow innerHTML as a setter.
...

Bernard Marx

12:20 pm on May 18, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Here's a basic emulation of what I had in mind.
The final version with defensive details will depend on the choice of synch/asynch call (I'm for asynch myself).

--- relevant HTML ---

<select id="selCountries">
<option value="">select country..</option>
</select>

--- SCRIPT ---

function ID(id){ return document.getElementById(id);}

var responseCities = "Chicago\nLos Angeles\nNew York\nWashington";

window.onload = function()
{
HTTPResponse(responseCities);
ID('selCountries').onchange = onCitySelection;

}

function HTTPResponse(text)
{
var select = ID('selCountries');
var vals = text.split('\n');
var option, D = document;
for(var k=-1, val;val=vals[++k];)
{
option = D.createElement('option');
option.setAttribute('value',val);
option.appendChild(D.createTextNode(val));
select.appendChild(option);
}
}

function onCitySelection()
{
alert(this.options[this.selectedIndex].value);
}

Bernard Marx

12:31 pm on May 18, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Oh yeah. The option list will keep getting longer
Small corection needed. Watch this space...
[-here-]

Bernard Marx

12:58 pm on May 18, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



All Pastebinned: [pastebin.com...]

isorg

5:51 pm on May 18, 2005 (gmt 0)

10+ Year Member



Wow! Bernard_Marx you're a genius :) Thanks to your help I have got this working.

1) This is the main HTML file that brings it all together.


<html>
<head>

<style>
#form1{position:relative;z-index:0;border:1px solid black}
#city{width:250px;}

.leftcolumn{width:250px;}
.hiddenselect{width:250px;position:absolute;z-index:1;visibility:hidden;top:30px;left:260px;}
</style>

<script type='text/javascript' src="js_dynamic.js">
</script>
</head>
<body>
<form action="action.php" method="post" name="form1" id="form1">

<table>
<tr>
<td class="leftcolumn">
<p>Your city of residence:
</td>
<td>
<input type="text" name="city" id="city" onkeyup="return populate(this.value, 'selCities', 'city');">

<select id="selCities" class="hiddenselect" multiple size=10 onblur="this.style.visibility='hidden';">
<option value="">select city..</option>
</select>

</td></tr></table>
</form>

</body>
</html>

2)This is the JS file called js_dynamic.js


function ID(id){return document.getElementById(id);}

window.onload = function()
{
ID('selCities').onchange = function () {ID('city').value=this.options[this.selectedIndex].value;}
}

function HTTPResponse(text, control)
{
var select = ID(control);
var vals = text.split('\n'), val;
var options = select.getElementsByTagName('option'), option;
var k, D = document;

/* empty all options but first */
while(options.length>1)
select.removeChild(options[options.length-1]);

/* (re)fill */
for(k=-1;val=vals[++k];)
{
option = D.createElement('option');
option.setAttribute('value',val);
option.appendChild(D.createTextNode(val));
select.appendChild(option);
}
}

function populate(typed, control, type)
{
if (window.XMLHttpRequest) {xhr = new XMLHttpRequest();}
else if (window.ActiveXObject) {xhr = new ActiveXObject("Microsoft.XMLHTTP");}

address="http://www.example.com/prefetch.html?type="+type;
xhr.open("POST",address, true);
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded; charset=UTF-8');
xhr.send(typed);
xhr.onreadystatechange=function()
{
if (xhr.readyState==4)
{
if (xhr.responseText!="")
{
HTTPResponse(xhr.responseText, control);
ID(control).style.visibility="visible";
}
else
{
ID(control).style.visibility="hidden";
}
}
}
}

3) This is the PHP server script prefetch.html


<?
include("config.html");
$incoming = urldecode(implode(file('php://input')));

if ($type=="city" and $incoming!="" and $incoming!=" ")
{
$incoming.="%";
$SQL = "SELECT city, count(city) as CityCount FROM profiles WHERE city like '$incoming' GROUP by city ORDER by CityCount desc LIMIT 10";
$result = mysql_query("$SQL",$cid);
while($row = mysql_fetch_array($result))
{
$city .= trim(ucwords(strtolower($row["city"]))) . "XXXisorgXXX";
}

$citya= explode("XXXisorgXXX", $city);
$cityb= array_unique($citya);
$city= implode("\n", $cityb);
echo $city;
exit;
}
?>

This is the first time I have ever posted so much code in a message on WW, and I apologise in advance for my crude programming style (needless to say, I am not a programmer by trade... :) ) But I thought it may help others to know how I got this working, and to thank those who have helped along the way.

[isorg.pastebin.com...] is the HTML file
[isorg.pastebin.com...] is the JS file
[isorg.pastebin.com...] is the PHP script.

dcrombie

8:08 am on May 19, 2005 (gmt 0)



You might have problems with Safari as I think it ONLY accepts a return type of text/xml (ie. proper XML content).

It's probably a better practice anyway to use XML rather than just returning Text or HTML.

Bernard Marx

10:46 am on May 19, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I know you're probably right about it being better practice, but it has it's downsides.

The information, which after all is quite simple in structure, would have to be wrapped in tags, adding an overhead, and strenously checked for validity, with dodgy characters turned into entities.

Getting the information takes a little more time & effort on the client side too.

While it's not such a big deal, I can't really see any 'big deal' benefits either.

There are some that see JSON [crockford.com] as a better, lightweight alternative (easy on the client, possibly fiddly on the server).

Thinking aloud, while XML might leave some room for flexibility and further development, JSON serialised objects can include their own methods, so there's room for encapsulation and polymorphism. Possibly more options are open that way.

Bernard Marx

10:56 am on May 19, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



P.S. I'm hoping for a counter argument on that topic, especially the last point.

"XML documents can include their own methods, because..."

I'm sure it's possible. I just can't work out a simple way.

dcrombie

11:10 am on May 19, 2005 (gmt 0)



My concern is that if people follow Google's lead and use scripts returning text, HTML or some other unstructured format, that the whole system becomes 'balkanized' and breaks down.

At the moment, the only realistic option for this is XML, although something like JSON would make more sense in the long run (interesting link).

IMHO what we need is for some of the 'authorities' in this area to very quickly provide more C&P examples for generating and reading XML data using XMLHttpRequest so that beginners can get off on the right foot.

Bernard Marx

11:57 am on May 19, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



My knowledge & experience is limited, but...

"balkanized":

Yes. I know what you mean.

Using basic strings...,
while XML has the capacity to...

<Warning: switching metaphorically from geopolitical to natural>

However XML documents can be snowflakes instead. In the end, one still needs some 'contract' and central central authority. XHTML, dtds etc.

XML docs support an interface, DOM, but it would be nice to arrange a subinterface that enables the "information package" to tell you about itself. This could funnel the multiplicity of tags into something maneagable. Actually this is doubtless possible in XML already (see my first statement).

Anyway, I'll express it as Javascript because that I can get my head around.


{
getOptions:function(){return ['London','Birmingham','Leicester']}
country: 'UK',
init: function(){ alert('Mum: Time for dinner')}
}

The options array is encapsulated, so its getter could be changed at the server so as to choose its output in some other way (don't quite know what for the specific example).

country: Make sure we get what we asked for.

init: Perhaps the only necessary interface component. This could do anything if the client chooses to execute it.

-------------------------------------

The dark cloud for XMLHTTP is ActiveX blocking in IE. Hopefully that will be sorted out soon in one way or another .

isorg

12:34 pm on May 19, 2005 (gmt 0)

10+ Year Member



>ActiveX blocking

One thing I have learnt is that you should not rely on XMLHTTPRequest for your site's functionality. It may not work at all, for a number of reasons, including Javascript being turned off. So only use it to enhance something that is already there.

Case in point - I came to work this morning and tried to play with the scripts I made yesterday, but it doesn't work. I thought my entire day would be ruined because the script had crashed but then realised - my work computer runs IE5.0 and this is the reason it doesn't work!

Bernard Marx

4:16 pm on May 19, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



One thing I have learnt is that you should not rely on XMLHTTPRequest for your site's functionality

In fact, "if Javascript is disabled" is definitely the most commonly appearing 25-character string on Javascript forums.

my work computer runs IE5.0 and this is the reason it doesn't work!

IE5 does support XMLHTTP (I have 5.01 elsewhere and that does). The solution is probably a try..catch block like the one at Jibbering [jibbering.com] - although someone posted a better one here once (lost link).

I'm just wondering whether IE's in-built download behavior [msdn.microsoft.com] will work at higher security settings than XMLHTTP. It could be a fallback.

isorg

4:34 pm on May 19, 2005 (gmt 0)

10+ Year Member



I think it is a javascript issue with IE5, because the SELECT is correctly populated, but the user cannot interact with the SELECT - you cannot click on it / select an option etc. and it does not update the original text field.

Bernard Marx

5:18 pm on May 19, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Hmmmmm. Have you been checking poulation with innerHTML?

Perhaps (?) IE5 would prefer us to use the old style, Option constructor.

So I'm saying what I said here:
[webmasterworld.com ]

..only the complete opposite.

isorg

6:59 pm on May 19, 2005 (gmt 0)

10+ Year Member



>checking poulation with innerHTML

Now that's a great idea, I will see what happens.

I've been looking at my webalizer stats, and only 1.67% of my visitors were using IE5.0. So maybe it's better left alone - Google Suggest doesn't work on that computer either (gives same error), so I'm in good company :)