How To Use Ajax?
Will I be able to squeeze an Ajax How-To in to one blog entry? Or will it need an article? Probably the latter, but I can point you in the right directions if you don't want to wait for that.
Really there's little need for me to go over how it's done again. It's well documented in lots of places already. What I will try and do is write a Domino-specific how-to. All I've got for you in the mean time is an NSF you can download.
There's a good primer on Ajax called Ajax: A New Approach to Web Applications. I'd suggest reading this first. Then you can move on to Very Dynamic Web Interfaces at O'Reilly's XML.com, which contains all the code you should need.
If you prefer to rip things apart rather than read boring articles download this database. It's got the code from the O'Reilly article already in it.
Anyway, about the code. I won't pretend you don't need at least an intermediate JavaScript knowledge to get your head round it all. The trouble is that it's not easy to separate the Ajax "logic" from your own code. There's a reason for this and it's something that caught me out for a while.
The way Ajax works is confusing at first. Your code calls a function which triggers the request for some XML. Obviously this is not an instantaneous transaction and so the code has to wait until the response has been received. Once the XML has been returned it is passed back to the same calling function for processing. Hence, this function runs twice - once to fetch the results and once to process them. What you can't do is something like the function below, where checkModifedDate() is the function which both requests the XML and processes it:
function doSubmit() {
if ( checkModifiedDate( sUNID ) ) {
document.forms0.submit();
}
There's a simple reason for this. The first time the checkModifiedDate() function is called it's simply calling for the XML. There's no logic involved at this point. So the if() statement always processes and the form submits. To get round this we have to move the form submit() call inside of the checkModifiedDate() function to the point where the XML is processed! This makes it harder to hide the more complicated code away in a library somewhere.
Apart from that it's fairly straight-forward stuff. I'll try and get round to an article at some point that talks about how we can use it with Domino.
Other Reading:
- Ajax Matters - Everything you need!
Ah the light bulb comes on. The function calling the XMLHTTP request calls itself with an additional flag to indicate when it has data.
I was looking at Bobs Ultimate View article and I noticed he uses a timeout loop to check to see when a value has been returned.
The demo database works great by the way.
Mark
Confusin' innit. Although there's no need for a timeout. I guess Bob's is there for some other reason - like waiting to make sure everything present and correct.
Ok, what am I doing wrong. The demo database doesn't work for me. It happily saves from different windows.
Hmm....Works from Firefox, not from IE.
Strange indeed mr veer. Not sure why. Scripting permissions? Does my online demo version work for you in IE?
mr jake :)
your online version doesn't work in my IE either ...
Which IE are you using? Works in my IE6 on XP.
Mark,
Really no difference here, I didn't want to pin the CPU by going back and forth between the two functions that make the XMLHttp call and the function that test for a result. I figured a 1/10 second pause would lighten this load slightly and be almost unnoticable to the user. All you'd have to do on mine is remove the setTimeout and call the function directly at the same spot.
Maybe I'm missing the bigger picture here, but why is this suddenly so exciting?
I've used the XML Http object in Domino and .Net projects I've worked on over the last 2 years so why is it only now that people are starting to get excited about it?
It's been available for use since IE 5 was around I think...
I am seeing the same thing as veer.
Works perfect in Firefox but in IE it saves the second doc without prompting.
I am running IE 6 on WinXP Sp2.
I agree it could be a scripting setting in IE.
Giles,
It's actually been around in some form since IE3 (I'm not so sure I believe that but I read it somewhere yesterday, and if it's in print... it MUST be true, right?)
It's only recently that it works in Safari (1.2) and Opera (8.0). As far as I'm concerned, lack of support in those two browsers would be critical. IE only solutions... well... suck.
Giles. Why now? Why not? Now is as good a time as any. You knew about it already - good for you. Do you think everybody does? No, and they need to. That's why. Also, it's exciting, because it's now a workable solution in all the browsers and not merely IE. It will work in anything >= Opera 7.6, Safari 1.2, Firefox 1.0 and IE5.
Steve & veer. Are you both running it on servers or locally?
Jake,
I too am running IE 6 on Win XP SP2. Running it on local. But I think putting it on the server might give the same results, as your online demo is not working for us either.
Jake,
I have no problems running the online example or locally. IE6 SP2.
@Bob Surely the function is setting up an Event listener so there is no CPU load ? The script cant be in a continous loop until the request is returned can it ?
Mark,
This is one area where I still want to make improvements to my solution. I thought the event listener should be able to handle this without me returning to the function that makes the call... but it was failing. Yes, currently it can be in a continuous loop, but that should be easy to fix. Actually... I'm going to piggyback on the solution you sent me to just fall back to display the same thing that would be displayed in unsupported browsers. Definitly some work needs to be done here...
Jake-
There is an option in .open to set asynchronous to false. Of course, waiting for the response could be fatal if it never comes.
Also, the loadXMLDoc is not called twice, but the processReqChange function is called multiple times. You could make processReqChange generic by removing your code and adding something like processResponse(response) to it. processResponse could be custom for each form/page. This would allow the loadXMLDoc and processReqChange to be moved to a library.
For your checkModified you could break out the code to only check the modified date and using setTimeout check every few ms for the results, you would need to set a maxmium timeout and decide what to do if you never get a result back.
Not sure if this was on your site or one of site you linked to, but this article really helped me get started with this
{Link}
Niel,
Take a look at my article @ {Link} . I'm doing exactly what you are suggesting except I don't have a maximum timeout which I need to fix (as I mentioned in the comment directly above yours where I took about continuous loops).
The one thing Jake is doing that I really like and think I will add to my code is checking for a HTTP 200. I'd rather do that and fallback to a different solution if it fails.
Bob,
Damn I thought I had it but now I am confused again (doesnt take much).
Correct me if I am wrong but looking at Jakes code the processReqChange function gets called 4 times 1 for each of the readyState - once it reaches 4 it continues. So the code is not in a continous loop but rather waiting for a state change.
Are you saying Bob that when you did your view navigator the event handler never called drawViewNav() ? Because if it did you wouldnt need the timeout right ? As for handling a timeout wont that return a different HTTP status code which means you can handle it (aka non javascript version of the navigator).
Mark
Bob-
Saw the article, loved it! I must admit I skipped your code and looked at Julian's. One other difference to mention is I like how Julian's just uses evaluate instead of parsing of xml.
Also, thanks for wasting about 3 hours of my day with that video link while you were updating the article. I was on that site all day watching videos! :)
All this asynchronous javascript just cries out for something way cool like signals and slots from the netwindows.org project {Link}
Basically instead of only being able to attach event listeners to DOM events it lets you connect any 2 functions so that when function 1 is called, function 2 is automatically called (and passed the same arguments by default). It does a lot of other spiffy things too.
It's perfect for asynchronous event handling in Ajax based UIs and lets you do away with timeouts and such.
I have to concur...this demo simply does not work in IE...I'm using IE6 and it cheerfully saves both without any messages of any sort. Sorry, not excited yet. Don't ya just love sending out demos to an uncontrolled anonymous audience? ;-)
Julian. What would be nice from the uncontrolled audience is a little more feedback than "It doesn't work". How about finding out why or giving me a few more clues?
I've just taken a look and found that my IE settings on this PC (different to development machine) had an effect. Make sure your cache settings don't cache anything at all.
Okay. Add the following line to the checkModifiedThenSubmit() function, just below the if(response) tests:
alert(response[0].firstChild.data +"\n"+ sLastModified);
See what that say. If they're always the same. That's the problem.
i am trying to call xmlHttp object twice for 2 different requests, in one go, but i am having a problem where it doesnt fully complete the first request, then deletes the xmlhttp.responseText data, and only completes the 2nd request.. however if i put in an alert(); in between it works okay, but thats not the solution..
any help appreciated!
thanks,
P.
Interesting question Paul. Not sure exactly what order you're doing things in, but you need to understand the internal working of the XMLHTTP obect to know what it's doing and why what you're doing won't work.
How did I get to this site? I was looking for porn.
Well - time ago from last (sensible lol) post in this blog. For those still reading this and having problems (see Julian's post): there is really problem with caching, might be on server side also.
If you don't like to change IE settings - i overcome that problem by adding a dummy parameter (random number) which prevents using of cached files, for example like this url line instead of original one (blog example database, form Test, JSHeader):
url = sFullPath + 'xml/' + input +'?OpenDocument&'+Math.random().
Regards from Slovenia, B
Hi. I am having problems with Ajax in my code and my browser. Running the server on my own computer and accessing it locally.
Somehow everything seems to be going ok until the line
XMLHttpRequestObject.send(null);
after that, the next function which is supposed to be called on any state change never gets called. I am wondering why. Do things work differently locally?
I am guessing that after I use the send command, nothing is returned and there is no state change. On my server logs, I notice there is indeed a request for that page. When I manually type in the url in my brower, I get a response. Not sure what is going on here. Thanks so much.
This site is providing reliable information about AJAX to use in Domino Applications
Hello friends,
i have been using ajax and have been having problem s lately, i am calling a function twice, to populate a combo box, my problem is that though i am calling the same function twice, only the first combo box is getting filled up, can any one help?