Discussion:
Ajax Dom Replacement
gregor
2008-09-08 11:43:35 UTC
Permalink
I would like to change a DOM Object with a turbogears ajax call.
At the moment the ajax call returns a string with the html of the node
that should be replaced. How can I swap the existing DOM Object with
the new one I got from the ajax callback?

InnerHTML replaces the inner part of the element, but I want to
replace the whole thing. OuterHtml seems to what I need but it does
not work in Firefox. swapDOM takes two DOM-Objects, but I've only got
a string for the replacement. How can I convert a string to a DOM
object?

Pseudo example:

<html>
<table>
<tr><td id="thisisatd" colspan="2">A text</td></tr>
</table>
</html>
From the Ajax call I get the string back "<td id="thisisatd"
colspan="3">A new text</td></tr>".
How can I replace the td with this new string?

My current function to do this looks like this:

var doReplace = function (req) {
for (var e in req.changes) {
var element = document.getElementById(e)
if (element) {
element.outerHTML = req.changes[e]; // <- Does not work in Firefox
}
else {
alert("element not found:" + e);
}
}
}

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "MochiKit" group.
To post to this group, send email to ***@googlegroups.com
To unsubscribe from this group, send email to mochikit+***@googlegroups.com
For more options, visit this group at http://groups.google.com/group/mochikit?hl=en
-~----------~----~----~----~------~----~------~--~---
Amit Mendapara
2008-09-08 12:32:45 UTC
Permalink
As your Ajax result is a TD, innerHTML wont work if you don't create
whole TABLE with TBODY. You should do this:

var old = $('thisisatd');

var tr = TR(null);
var tbl = TABLE(null, TBODY(null, tr));

tr.innerHTML = '<td id="thisisatd" colspan="3">A new text</td>';

swapDOM(old, tr.firstChild);

For your information, I'm implementing a jQuery style helper module
(see previous post) that will easy such tasks, for example:

MochiKit.Query('#thisisatd').replaceWith('<td id="thisisatd"
colspan="3">A new text</td>');

The MochiKit.Query will take care of creating valid DOM from the given
row html text and also executes JavaScript within the text if any.
Though almost finished, the module is still not made public. I'm
reviewing some of the code and will release the code within a week or
so...

Regards
..
Amit Mendapara
Post by gregor
I would like to change a DOM Object with a turbogears ajax call.
At the moment the ajax call returns a string with the html of the node
that should be replaced. How can I swap the existing DOM Object with
the new one I got from the ajax callback?
InnerHTML replaces the inner part of the element, but I want to
replace the whole thing. OuterHtml seems to what I need but it does
not work in Firefox. swapDOM takes two DOM-Objects, but I've only got
a string for the replacement. How can I convert a string to a DOM
object?
<html>
<table>
<tr><td id="thisisatd" colspan="2">A text</td></tr>
</table>
</html>
From the Ajax call I get the string back "<td id="thisisatd"
colspan="3">A new text</td></tr>".
How can I replace the td with this new string?
    var doReplace = function (req) {
        for (var e in req.changes) {
            var element = document.getElementById(e)
            if (element) {
                element.outerHTML = req.changes[e];  // <- Does not work in Firefox
           }
            else {
                alert("element not found:" + e);
            }
        }
    }
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "MochiKit" group.
To post to this group, send email to ***@googlegroups.com
To unsubscribe from this group, send email to mochikit+***@googlegroups.com
For more options, visit this group at http://groups.google.com/group/mochikit?hl=en
-~----------~----~----~----~------~----~------~--~---
Gregor Horvath
2008-09-08 12:48:09 UTC
Permalink
Post by Amit Mendapara
As your Ajax result is a TD, innerHTML wont work if you don't create
ok. That's another problem.
What I want is a generic solution that works for all html elements
without special cases (like this) in Javascript.
Post by Amit Mendapara
MochiKit.Query('#thisisatd').replaceWith('<td id="thisisatd"
colspan="3">A new text</td>');
That looks exactly like what I am looking for. Cool!
Thank's. Looking forward to your realease!

--
Gregor

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "MochiKit" group.
To post to this group, send email to ***@googlegroups.com
To unsubscribe from this group, send email to mochikit+***@googlegroups.com
For more options, visit this group at http://groups.google.com/group/mochikit?hl=en
-~----------~----~----~----~------~----~------~--~---
Arnar Birgisson
2008-09-08 12:52:03 UTC
Permalink
Hey there,
Post by gregor
I would like to change a DOM Object with a turbogears ajax call.
At the moment the ajax call returns a string with the html of the node
that should be replaced. How can I swap the existing DOM Object with
the new one I got from the ajax callback?
InnerHTML replaces the inner part of the element, but I want to
replace the whole thing. OuterHtml seems to what I need but it does
not work in Firefox. swapDOM takes two DOM-Objects, but I've only got
a string for the replacement. How can I convert a string to a DOM
object?
First of all, not that in general a string can represent a HTML
fragment containing more than one element. Consider:

"<td>number1</td><td>number2</td>"

My point is that you cannot take any string and convert it to just one
DOM element. However, say your strings always contain one complete
element, or that you just want to pick out the first one, you can
create a temporary element (not injected in the document) to use
innerHTML on, and the use swapDOM to inject the first child. I.e.
(note, this is untested code written directly in the email):

var str = "<td>something from an ajax call</td>";
var container = DIV();
container.innerHTML = str;
swapDOM("id-of-element-to-remove", container.firstChild);

Actually, if you did want *all* elements from the fragment, you could
to this I guess:

var str = "<td>something from an ajax call</td>";
var container = DIV();
container.innerHTML = str;
insertSiblingNodesAfter("id-of-element-to-remove", container.childNodes);
removeElement("id-of-element-to-remove");

However, you should note that with the proper content-type for the
ajax response and depending on your specific use, you might already
have a ready-made DOM object in the XMLHttpRequest object under the
property responseXML

cheers,
Arnar
Post by gregor
<html>
<table>
<tr><td id="thisisatd" colspan="2">A text</td></tr>
</table>
</html>
From the Ajax call I get the string back "<td id="thisisatd"
colspan="3">A new text</td></tr>".
How can I replace the td with this new string?
var doReplace = function (req) {
for (var e in req.changes) {
var element = document.getElementById(e)
if (element) {
element.outerHTML = req.changes[e]; // <- Does not work in Firefox
}
else {
alert("element not found:" + e);
}
}
}
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "MochiKit" group.
To post to this group, send email to ***@googlegroups.com
To unsubscribe from this group, send email to mochikit+***@googlegroups.com
For more options, visit this group at http://groups.google.com/group/mochikit?hl=en
-~----------~----~----~----~------~----~------~--~---
Arnar Birgisson
2008-09-08 13:13:10 UTC
Permalink
Post by Arnar Birgisson
Post by gregor
I would like to change a DOM Object with a turbogears ajax call.
At the moment the ajax call returns a string with the html of the node
that should be replaced. How can I swap the existing DOM Object with
the new one I got from the ajax callback?
InnerHTML replaces the inner part of the element, but I want to
replace the whole thing. OuterHtml seems to what I need but it does
not work in Firefox. swapDOM takes two DOM-Objects, but I've only got
a string for the replacement. How can I convert a string to a DOM
object?
First of all, not that in general a string can represent a HTML
"<td>number1</td><td>number2</td>"
My point is that you cannot take any string and convert it to just one
DOM element. However, say your strings always contain one complete
element, or that you just want to pick out the first one, you can
create a temporary element (not injected in the document) to use
innerHTML on, and the use swapDOM to inject the first child. I.e.
var str = "<td>something from an ajax call</td>";
var container = DIV();
container.innerHTML = str;
swapDOM("id-of-element-to-remove", container.firstChild);
Here's a quick test:
http://www.hvergi.net/arnar/public/test/load.html

cheers,
Arnar

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "MochiKit" group.
To post to this group, send email to ***@googlegroups.com
To unsubscribe from this group, send email to mochikit+***@googlegroups.com
For more options, visit this group at http://groups.google.com/group/mochikit?hl=en
-~----------~----~----~----~------~----~------~--~---
Amit Mendapara
2008-09-08 13:44:33 UTC
Permalink
Yes, exactly. In that case:

var old = $('thisisatd');

var tr = TR(null);
var tbl = TABLE(null, TBODY(null, tr));

tr.innerHTML = '<td id="thisisatd" colspan="3">A new text</td><td
id="thisisanothertd" colspan="3">A new text</td>';

forEach(tr.childNodes, function(td){
old.parentNode.insertBefore(td, old);
});

removeElement(old);

Regards
..
Amit Mendapara
Post by Arnar Birgisson
Hey there,
Post by gregor
I would like to change a DOM Object with a turbogears ajax call.
At the moment the ajax call returns a string with the html of the node
that should be replaced. How can I swap the existing DOM Object with
the new one I got from the ajax callback?
InnerHTML replaces the inner part of the element, but I want to
replace the whole thing. OuterHtml seems to what I need but it does
not work in Firefox. swapDOM takes two DOM-Objects, but I've only got
a string for the replacement. How can I convert a string to a DOM
object?
First of all, not that in general a string can represent a HTML
"<td>number1</td><td>number2</td>"
My point is that you cannot take any string and convert it to just one
DOM element. However, say your strings always contain one complete
element, or that you just want to pick out the first one, you can
create a temporary element (not injected in the document) to use
innerHTML on, and the use swapDOM to inject the first child. I.e.
var str = "<td>something from an ajax call</td>";
var container = DIV();
container.innerHTML = str;
swapDOM("id-of-element-to-remove", container.firstChild);
Actually, if you did want *all* elements from the fragment, you could
var str = "<td>something from an ajax call</td>";
var container = DIV();
container.innerHTML = str;
insertSiblingNodesAfter("id-of-element-to-remove", container.childNodes);
removeElement("id-of-element-to-remove");
However, you should note that with the proper content-type for the
ajax response and depending on your specific use, you might already
have a ready-made DOM object in the XMLHttpRequest object under the
property responseXML
cheers,
Arnar
Post by gregor
<html>
<table>
<tr><td id="thisisatd" colspan="2">A text</td></tr>
</table>
</html>
From the Ajax call I get the string back "<td id="thisisatd"
colspan="3">A new text</td></tr>".
How can I replace the td with this new string?
   var doReplace = function (req) {
       for (var e in req.changes) {
           var element = document.getElementById(e)
           if (element) {
               element.outerHTML = req.changes[e];  // <- Does not work in Firefox
          }
           else {
               alert("element not found:" + e);
           }
       }
   }
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "MochiKit" group.
To post to this group, send email to ***@googlegroups.com
To unsubscribe from this group, send email to mochikit+***@googlegroups.com
For more options, visit this group at http://groups.google.com/group/mochikit?hl=en
-~----------~----~----~----~------~----~------~--~---
Per Cederberg
2008-09-08 13:48:29 UTC
Permalink
I guess it is just a matter of taste, but I'd use
MochiKit.DOM.replaceChildNodes instead of multiple insert and remove
calls.

Cheers,

/Per
Post by Amit Mendapara
var old = $('thisisatd');
var tr = TR(null);
var tbl = TABLE(null, TBODY(null, tr));
tr.innerHTML = '<td id="thisisatd" colspan="3">A new text</td><td
id="thisisanothertd" colspan="3">A new text</td>';
forEach(tr.childNodes, function(td){
old.parentNode.insertBefore(td, old);
});
removeElement(old);
Regards
..
Amit Mendapara
Post by Arnar Birgisson
Hey there,
Post by gregor
I would like to change a DOM Object with a turbogears ajax call.
At the moment the ajax call returns a string with the html of the node
that should be replaced. How can I swap the existing DOM Object with
the new one I got from the ajax callback?
InnerHTML replaces the inner part of the element, but I want to
replace the whole thing. OuterHtml seems to what I need but it does
not work in Firefox. swapDOM takes two DOM-Objects, but I've only got
a string for the replacement. How can I convert a string to a DOM
object?
First of all, not that in general a string can represent a HTML
"<td>number1</td><td>number2</td>"
My point is that you cannot take any string and convert it to just one
DOM element. However, say your strings always contain one complete
element, or that you just want to pick out the first one, you can
create a temporary element (not injected in the document) to use
innerHTML on, and the use swapDOM to inject the first child. I.e.
var str = "<td>something from an ajax call</td>";
var container = DIV();
container.innerHTML = str;
swapDOM("id-of-element-to-remove", container.firstChild);
Actually, if you did want *all* elements from the fragment, you could
var str = "<td>something from an ajax call</td>";
var container = DIV();
container.innerHTML = str;
insertSiblingNodesAfter("id-of-element-to-remove", container.childNodes);
removeElement("id-of-element-to-remove");
However, you should note that with the proper content-type for the
ajax response and depending on your specific use, you might already
have a ready-made DOM object in the XMLHttpRequest object under the
property responseXML
cheers,
Arnar
Post by gregor
<html>
<table>
<tr><td id="thisisatd" colspan="2">A text</td></tr>
</table>
</html>
From the Ajax call I get the string back "<td id="thisisatd"
colspan="3">A new text</td></tr>".
How can I replace the td with this new string?
var doReplace = function (req) {
for (var e in req.changes) {
var element = document.getElementById(e)
if (element) {
element.outerHTML = req.changes[e]; // <- Does not work in Firefox
}
else {
alert("element not found:" + e);
}
}
}
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "MochiKit" group.
To post to this group, send email to ***@googlegroups.com
To unsubscribe from this group, send email to mochikit+***@googlegroups.com
For more options, visit this group at http://groups.google.com/group/mochikit?hl=en
-~----------~----~----~----~------~----~------~--~---
Amit Mendapara
2008-09-08 14:03:24 UTC
Permalink
Post by Per Cederberg
I guess it is just a matter of taste, but I'd use
MochiKit.DOM.replaceChildNodes instead of multiple insert and remove
calls.
Yes, me too if I have to replace all children ;)

Regards
..
Amit Mendapara
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "MochiKit" group.
To post to this group, send email to ***@googlegroups.com
To unsubscribe from this group, send email to mochikit+***@googlegroups.com
For more options, visit this group at http://groups.google.com/group/mochikit?hl=en
-~----------~----~----~----~------~----~------~--~---
Gregor Horvath
2008-09-09 06:07:39 UTC
Permalink
Hi,

Thank you all for your help. I ended up using jQuery.replaceWith because
it just works.

--
Gregor
Post by Arnar Birgisson
Hey there,
First of all, not that in general a string can represent a HTML
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "MochiKit" group.
To post to this group, send email to ***@googlegroups.com
To unsubscribe from this group, send email to mochikit+***@googlegroups.com
For more options, visit this group at http://groups.google.com/group/mochikit?hl=en
-~----------~----~----~----~------~----~------~--~---

Loading...