|
This thread is locked; no one can reply to it. |
1
2
|
XmlHttpRequest and friends |
Marco Radaelli
Member #3,028
December 2002
|
If I understand it, XmlHttpRequest allows manipulating data after the page has loaded. E.g. I can show a button and when the user clicks it a javascript function can use the object to retrieve the MOTD and place it somewhere in the page. How would I go having it working in different browsers? Does each one have it's own way to create the object and interact with it? I found that for IE it's while for FF (according to this page). What's for other browsers?
|
miran
Member #2,407
June 2002
|
Quote: What's for other browsers? Should be either the same as for FF or not supported at all. -- |
Marco Radaelli
Member #3,028
December 2002
|
Good. What's best to check browser type? Client-side with JS or server-side looking at UserAgent (if someone is faking it I wouldn't care)
|
miran
Member #2,407
June 2002
|
I use code that looks like this in JS to asynchronously get data from the server with xmlhttprequest:
-- |
Marco Radaelli
Member #3,028
December 2002
|
Wow, thanks
|
miran
Member #2,407
June 2002
|
Note that some of that code is a little specific for my project. I'm talking about that check that makes sure no other request can be made until data was received from the previous request. In your project you will probably want to change this... -- |
FMC
Member #4,431
March 2004
|
[FMC Studios] - [Caries Field] - [Ctris] - [Pman] - [Chess for allegroites] |
Jonny Cook
Member #4,055
November 2003
|
See, now those are good tutorials. They just give you the facts, plain and simple. I really hate it when they pad the tutorial with a bunch useless crap to "ease" the learning process. It just makes it so you have to sift through it all to really get anything done... the whole world should think exactly like I do!>:( [edit] The face of a child can say it all, especially the mouth part of the face. |
Marco Radaelli
Member #3,028
December 2002
|
miran said: Note that some of that code is a little specific for my project. I'm talking about that check that makes sure no other request can be made until data was received from the previous request. In your project you will probably want to change this... I was in a hurry when I posted that reply, I didn't closely look at the code. Now I do, I'll keep the checking part. FMC said: This might help [rajshekhar.net] [edit]and this http://aleembawany.com/weblog/webdev/000051_ajax_instant_tutorial.html Thanks, but both do not seem to use XML in their example. I finally found how to get the XML tree
|
Marcello
Member #1,860
January 2002
|
Marco Radaelli
Member #3,028
December 2002
|
50 websites... o_O
It looks like my troubles aren't finished I managed to access that xml document I have and read its XML-tree. Now the problem is that I'll add its childs to a xhtml element. While I can removeChild(), it doesn't let me appendChild(), I can't understand why. xml file <?xml version="1.0" ?> <options> <option value="0">Zero</option> <option value="1">Uno</option> <option value="2">Due</option> <option value="3">Tre</option> <option value="4">Quattro</option> </options> xhtml page <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html> <head> <script language="Javascript"> function go() { /* Recupero file XML */ xmlobj = new ActiveXObject("Msxml2.XMLHTTP.3.0"); xmlobj.open("GET", "http://localhost/xml-test/x.xml", false); xmlobj.send(); /* Lettura albero XML */ xmldoc = xmlobj.responseXML; sel = document.getElementById("comuni"); sel.removeChild(sel.lastChild); /* lastChild because it seems that firstChild is <xml>... */ opt = xmldoc.lastChild.childNodes; //options = xmldoc.getElementsByTagName("option"); for(i = 0; i < opt.length; i++) { sel.appendChild(opt.item(i)); } } </script> </head> <body> <input type="button" value="o_O" onclick="go()" /> <form> <select id="comuni" size="1" disabled="disabled"> <option selected>Scegliere una provincia</option> </select> </form> </body> </html> In short, in the webpage there's a <select> with a single <option>, which says "Select a province", when the button is clicked I want that <option> to be deleted (which works) and then the five <option>s in the xml to be added there (which doesn't work, keeps saying 'interface not supported' on the appendChild() line) I still have to integrate the browser check, will do it when it all works
|
Matthew Leverton
Supreme Loser
January 1999
|
You cannot add a node from one document into another. You need to import it (importNode ?), but of course IE6 doesn't support that. The whole "AJAX" name is a joke. No one seriously uses XML with it. It's really "AJAJ" or "AJAH". Look for what's known as "JSON". It's basically a way to convert XML like data into a string that represents a JavaScript object. AJAJ example: server generates: {options:[{value:0,text:"zero"},{value:1,text:"one"}]} client evaluates it: eval("var response = " + json); alert(response.options[0].value);
Or alternatively use AJAH and just pass it as HTML, and use foo.innerHTML = HTML;. |
miran
Member #2,407
June 2002
|
Yes, I was going to say the same thing as Matthew, but was too busy watching football. You will rarely want to handle XML in JS as JSON is so much easier and more convenient and has more support. Even if your source data is XML, it is much easier to convert it to JSON on the server and then just use eval() in JS than it is to manipulate XML in JS. -- |
Matthew Leverton
Supreme Loser
January 1999
|
I meant to comment on this: Quote: What's best to check browser type? Client-side with JS or server-side looking at UserAgent Don't ever check the browser type to determine functionality. Always check browser features, starting with the standard ones first: if (foo.addEventListner) { // W3C Model } else if (foo.attachEvent) { // IE Model } The only times you want to check the user agent string with JS is if a certain browser has a glitch that you need to work around. For example, I check for the literal string "Safari" on the dynamic combobox widget because Safari does not support CSS system colors, so I have to provide default colors. That is the only future compatible method. If I were to check for features, I might get the detection wrong if another browser matches it or Safari changes functionality. (Obviously if they ever fix this problem, then I would need to add a version check as well.) |
Marco Radaelli
Member #3,028
December 2002
|
Ok, I found how to manipulate the <select> childs: Roughly opt = document.createElement("option"); sel.options.add(opt); opt.innerHTML = "Prova"; opt.value = 1; I thought I'd go the easy way:
Of course that doesn't work So? JSON requires more than five minutes to get it to work, but I still don't get how will I retrieve the js source code (either from a file or from a server-side script)
|
miran
Member #2,407
June 2002
|
Quote: I guess it's because the XmlHttpRequest object won't load non-xml data. Of course it does. The server serves plain text. This text can be interpreted on client side as you wish, either as XML or JSON or anything else. On the server you just create a string containing JSON code, write it to the response object and that's it. I only know ASP, but I suppose it's similar in othe server side scripting languages. You just do something like dim json as string json = "{options:[{value:0,text:"zero"},{value:1,text:"one"}]}" Response.Write(json) and on the client in JS you do something like var json = req.responseText; eval("var response = " + json);
-- |
Marco Radaelli
Member #3,028
December 2002
|
I said: I guess it's because the XmlHttpRequest object won't load non-xml data. Ok, call me dumb. I replaced the text in the file and IE started to say "Permission denied" on xmlobj.open() I thought it was due because the file didn't contain valid xml code, but now I have closed and reopened IE completely and it works perfectly Well, for now I'll just directly generate the js script, avoiding that JSON stuff (I'm a bit in a hurry for this project). I'll keep an eye on it tough Too bad I was so optimistic to think that browser capabilities were the only trouble. Consider a whole box of cookies for you all ^_^
|
Matthew Leverton
Supreme Loser
January 1999
|
There are also many JSON classes available for scripting languages. The one I use for PHP works like: $response = array( 'foo' => 'bar' ); $json = new JSON; echo $json->encode($response); It may seem like overkill at first, but it becomes quite nice when you have a very dynamic response to build. Plus, it automatically handles converting UTF-8 encoded strings to proper JS escapes (eg, "\u00A9"). |
Marco Radaelli
Member #3,028
December 2002
|
Mmh... looks like the request ends before the whole code is retrieved, if the latter is too long. Any way to wait for it? I'm thinking at onreadystate, but a busy-wait on it won't work without some sort of sleep()
|
Marcello
Member #1,860
January 2002
|
You're doing something wrong, then. The examples above will not do that. Perhaps include some code? Marcello |
Matthew Leverton
Supreme Loser
January 1999
|
As long as you are waiting for readyState == 4, everything will be there. |
Marco Radaelli
Member #3,028
December 2002
|
Quote: You're doing something wrong, then. The examples above will not do that. Perhaps include some code? Here's it (I still didn't converted it to JSON) Client-side, when the selected item of a <select> changes, this deletes all the current <option>s in it and loads a js from listacomuni.php
Server-side, generates js that will add the new <option>s to the <select>
While the code isn't 100% fixed (I still have issues alternatively in IE and FF ), when the query returns few rows it generates the whole script, but if the rows are many the script gets broken (I saw this by replacing eval() with alert() in the client-side script An example is attached (couldn't resist to try the new upload thing ) Quote: As long as you are waiting for readyState == 4, everything will be there.
while(req.readystate != 4);
|
Matthew Leverton
Supreme Loser
January 1999
|
Quote: while(req.readystate != 4); No, the function will be called multiple times: function onLoad() { if (req.readystate != 4) return; } I would do this: req.open("GET", url, true /* not false */); req.onreadystatechange = function() { if (req.readystate != 4) return; // process }; And use a callback function. It's the only good way to do it. (See Miran's example.) |
BAF
Member #2,981
December 2002
|
Quote:
req.open("GET", All your open()'s have stray php. Is that intended? |
Marco Radaelli
Member #3,028
December 2002
|
BAF said: All your open()'s have stray php. Is that intended? Yes; due to the fact that the xml~ stuff needs an absolute path, that php code ensures everything works if I move the whole directory Great... it doesn't work. I mean, I think I did everything you suggested client-side code
server-side code
But it keeps failing (output is truncated) if the query returns too many rows. I have no idea about what to do, I can't understand why readyState becomes 4 before the script ends its output. I also tried to put every js piece in a variable and echo that only at the end: same result. I don't think it's a timeout issue, because it all ends in 1-2 seconds. I don't even understand why there are those boxes in the generated javascript (long.png in my post above), alert() doesn't have troubles with accented letters. [edit] I changed and now it works in FF (it does wait for the whole data, while IE still doesn't ). But I have another issue to add
|
|
1
2
|