Web Hosting Talk







View Full Version : Need AJAX+DOM suggestion/help


NE-Andy
07-05-2006, 04:19 PM
I'm running into a small snag here.
I have an AJAX application right now which pulls HTML content and insert the retrieved content into a div box.
In one of the contents that it retrieves, I need to instanciate a special custom object for a form element in the newly retrieved object. To be more precisely put, I need to initialize a suggestion service object on an input field.
I included the script that it needs to execute in the HTML that is retrieved only to realize that code inserted into the HTML via this method does NOT get executed.

IE:
AJAX request content; server replies mixed HTML + Javascript content to AJAX; AJAX plops retrieved content into div element in current object, but does not execute the retrieved Javascript.

Is there any way I can make the retrieved Javascript be executed?

tobiasly
07-06-2006, 01:00 AM
Wow, that's a pretty perverse thing you're trying to do there, Javascript calling the server to get more Javascript! :)

How are you passing this Javascript back, just a regular <script> block? The best way I could think to do this is by making the server return two distinct chunks, one with the XHTML and one with the Javascript, and then split those chunks back out on the client side, and eval() the Javascript part.

So the server's response would be something like:

<?xml version="1.0" encoding="UTF-8"?>
<response>
<html>
html contents...
</html>
<script>
javascript contents...
</script>
</response>
Of course it gets a bit tricky because you have to create HTML DOM nodes from the XML nodes, but it should be very doable. But the question I have is, why are you passing back Javascript code from the server? What do you want that Javascript to do on your page?

NE-Andy
07-06-2006, 01:25 AM
Ah, eval, that's what I was planning to try but haven't gotten around to trying.
Here's a brief as to what I'm doing.

My client requested to have an application that will refresh as little as possible, so the end-users doesn't have to keep on waiting for page to load etc. I need to load a 'page' for end-users to add records to a database, but provide hints to user if the record being entered is similar to an existing record on the server.

I made a custom object in javascript, that'd monitor a particular field on the 'page', and after what is entered is longer than 4 characters/2 big char for asian text, it'll contact the server and query for a list of similar entries. Think... Google suggest or vBulletin's nick auto completion.

However, the way I designed this object is that it needs to be initialized with the DOM object of the field it needs to monitor, so it cannot be instanciated until the 'page' is loaded (this page comes and goes, so we can't just instanciate it and leave it). Hence why I need to execute the chunk of code after it's pulled from the AJAX response.

So, I guess this is what my response would (or rather, should) look like:
<?xml version="1.0" encoding="UTF-8"?>
<response>
<html>
<!-- my form stuff here -->
<input type="text" name="Name" id="InputField" />
<!-- more of my form stuff here -->
</html>
<script>
var suggest = new Suggest( document.getElementById("InputField"), document.getElementById("SuggestDiv") );
</script>
</response>

And then eval that particular line?

Would DOM be able to access the InputFiled I just retrieved and inserted into a div block on the current display?

emevas1977
07-06-2006, 01:28 AM
NE-Andy, I had todo something similiar to a project i am currently working on and found that after i created the element via "document.createElement(...", i had to do a .innerHTML instead of .appendChild(... and it would like a charm.

I also had to put... hmmm, can't think of the code off hand but instead of putting "<" in the xml file, i had to put the code for "<", but can't think of what it is off hand. sry, if i think of it when i am look at the code and will repost.

emevas1977
07-06-2006, 01:32 AM
andy, take a look at the prototype.js stuff, i know there is something about a listener that should help you with what you are trying todo.

also, take a look at the below link, i personally have not delt with it, but a co-worker swairs by it.

http://dojotoolkit.org/

tobiasly
07-06-2006, 02:01 AM
OK, I'm beginning to understand... first of all, I'm assuming you're aware that several others have created these Google Suggest type objects, just Google "google suggest javascript" and you'll find some examples. But it sounds like you've already got that piece working.

I'd try to avoid the whole returning Javascript business if possible. For one thing it will drive you crazy trying to debug; for another, AJAX is already prone to cause memory leaks in some browsers due to the circular references it tends to create.

How about instead, you give a particular class to any field that you want to monitor using your Suggest object. Then, once you're finished loading up the HTML (in the AJAX callback function), use getElementsByTagName("input") on the DIV you used to load up the custom HTML, and inspect the class of each input box to then instantiate your Suggest objects appropriately.

So your HTML response is just the form:

<form>
<input type="text" name="Name" class="AllowSuggest" />
<input type="text" name="Info" />
</form>

And in your AJAX callback function (assuming that "ContainerDiv" is the DIV into which you loaded the HTML):

var allInputs = getElementById('ContainerDiv').getElementsByTagName('input');
for (var i = 0; i <= allInputs.length; i++) {
if(allInputs[i].getAttribute('class') == "AllowSuggest"
var suggest = new Suggest(allInputs[i], document.getElementById(allInputs[i].name + "SuggestDiv"));
}
(Notice how with this method, the div containing the suggestion for element "Name" must have id="NameSuggestDiv")

A completely different approach would be to use a hidden field on your form, the value of which contains the id's of the DIVs you want to suggest:


<form>
<input type="text" name="Name" id="Name" />
<input type="text" name="Info" id="Info" />
<input type="text" name="PartNumber" id="PartNumber" />
<input type="hidden" name="SuggestDivs" value="Name,PartNumber" />
</form>

And in the callback:

var suggestDivs = document.getElementById("SuggestDivs").value.split(",");
for (var i = 0; i <= suggestDivs.length; i++ ) {
var suggest = new Suggest(document.getElementById(suggestDivs[i]), document.getElementById(suggestDivs[i] + "SuggestDiv"));
}

NE-Andy
07-06-2006, 03:18 AM
Ah, nice stuff, I think I'll go with the callback that initializes per class instead!

I'm sort of stuck with the AJAX engine now as is because A) I'm late, and B) there are no visible alternative that will achieve my client's needs/request.

Thank you for the inputs, I really appreciate them! :)