How do I copy elements that include <script> children from an AJAX-loaded document?
I'm currently trying to hack a kind of edit-in-place functionality into the JIRA bugtracker without changing its page templates. So, on the detail page for an issue, I'm attaching dblclick events to fields that replace the static field with an editable form element (from the edit page, which has been ajax-loaded and cached at the beginning of the script). Some of these elements are开发者_运维知识库 JS widgets, such as a calendar widget, and they have <script> elements within the <td> for the field. I want to carry these elements across with the rest of the HTML, and have them executed in the page.
So, the original static field looks like this:
<td bgcolor="#ffffff" width="80%"> 2008/Sep/22 </td>
The one I'm trying to copy across looks like this:
<td class="fieldValueArea">
<input type="text" name="duedate" id="duedate" value="" size="10">
<img id="duedate_trigger_c" src="/jira/images/icons/cal.gif" width="16" height="16" border="0" alt="Select a date" title="Select a date">
<script type="text/javascript">
Calendar.setup({
firstDay : 0, // first day of the week
inputField : "duedate", // id of the input field
button : "duedate_trigger_c", // trigger for the calendar (button ID)
align : "Tl", // alignment (defaults to "Bl")
singleClick : true,
ifFormat : "%e/%b/%y" // our date only format
});
</script>
</td>
I want to keep the <script> element and have it execute in the target page (after the copy) so that the Calendar widget inits properly.
I'm using jQuery to AJAX-load the edit page like so:
$.get(editlink, function(data){
jeip_editpage = data;
}, "text");
And replacing the field like so:
this.innerHTML = $("#"+fieldname+"FieldArea .fieldValueArea",jeip_editpage).html();
(where this = the field TD)
After the $.get(), jeip_editpage contains the <script> element in the right place, but when I try and grab the element as above, it's gone. I've done some Googling and found that jQuery moves <script> elements around in the page during the parsing stage, which is a right pain. I suppose I could do a search & grab & replace on the text right after the $.get() to make sure I have all the <script> elements separately, but I figure there has to be an easier way, right?
Note that I'm not changing any of JIRA's page templates, so answers involving the HTML coming back in a more useful layout aren't going to work for me.
The jQuery Ajax "$.load" API lets you include a selector after the URL (sort-of "inside" the URL parameter). With that, it looks through the returned content for what you specify in the selector. Thus you might be able to load directly into the table cell:
$(this).load(editLink + ' #' + fieldname + 'FieldArea .fieldValueArea *';
The "this" pointer would be the "td" that you want to update. I'm not 100% sure however that that selector will work; it might however. (What I'm trying to express there is to select the "td" in the response HTML, and then get its contents.)
Scripts are stripped from jQuery ajax requests. This is from the source code.
58 // inject the contents of the document in, removing the scripts 59 // to avoid any 'Permission Denied' errors in IE 60 .append(res.responseText.replace(rscript, ""))
Source: http://dev.jquery.com/browser/trunk/jquery/src/ajax.js
You could still write your own ajax function to grab the html (with scripts) and then have jQuery insert it.
You should be able to do the following:
success: function(data) {
$(content).html(data); // this should evaluate the data from an ajax call
// when injected...
},
format: "text"
Basically when just setting html with data, jquery evals that data in the global context. Just don't tell jquery that the data is html/json/etc, just text.
The only thing I've had problem with is that google chrome / safari won't accept tags in the data. However this is jquery 1.2.6 so I don't know if that was fixed, I just don't do it anymore :)
Am I missing something in the question that is preventing the above behavior?
Edit: It looks like you are sending a td in your ajax response. Jquery does weird things when trying to just inject that content. Wrap the td with a table tag, then just select the td by doing $(...).html($(data).find("> tr"));
You don't need to pass in the Calendar script via ajax. Ajax has a calendar function:
function SetupCal(string fieldSelector, string buttonSelector){
Calendar.setup({
firstDay : 0, // first day of the week
inputField : fieldSelector, // id of the input field
button : buttonSelector, // trigger for the calendar (button ID)
align : "Tl", // alignment (defaults to "Bl")
singleClick : true,
ifFormat : "%e/%b/%y" // our date only format
});
}
Then in on the page load: $(function (){ $.get(editlink, function(data){ jeip_editpage = data; }, "text");
var fieldArea = $("#"+fieldname+"FieldArea .fieldValueArea");
fieldArea.html(jeip_editpage);
//call calendar function
SetupCal("duedate","duedate_trigger_c");
});
So the code in the static field goes from:
<td bgcolor="#ffffff" width="80%"> 2008/Sep/22 </td>
To:
<td class="fieldValueArea">
<input type="text" name="duedate" id="duedate" value="" size="10">
<img id="duedate_trigger_c" src="/jira/images/icons/cal.gif" width="16" height="16" border="0" alt="Select a date" title="Select a date">
</td>
精彩评论