Wednesday, August 12, 2009

A error in jquery.jqGrid 3.5 in file grid.base.js

By inspect element for style integration and I found error in code.
in grid.base.js, line 251
var gv = $("<div class='ui-jqgrid-view'</div>"), ii,

And it should be
var gv = $("<div class='ui-jqgrid-view'></div>"), ii,

I have written a commit to the official site, and it was filtered out by the admin.

I guess they should know the error already, and hope they will give the official patch to the version as soon as possible.

Also, the jqgird 3.5 do run much faster than the previous version.

Hey Man! Good job!

Tuesday, August 4, 2009

Beware of moving element with script node by jquery

My colleague hit a strange error when he implement the code in to move element with following code (with simplification):


<div id="moveMe">hihi
<a id="clickMeAlertOnce"> Click Me Alert Once </a>
<script type="text/javascript">
//Script Code inside moveMe
$('#clickMeAlertOnce').click(function(){alert(' Click Me Alert Once');});
</script>
</div>

<div id="'newLocation'" />

<script type="text/javascript">
//Code to move Node
$('#newLocation').append($('#moveMe'));
//omit some code as clean up old node<br />
</script>


The cause of the error is because the 'append' method in Jquery will invoke the below method
domManip: function( args, table, callback ) {
if ( this[0] ) {
var fragment = (this[0].ownerDocument || this[0]).createDocumentFragment(),
scripts = jQuery.clean( args, (this[0].ownerDocument || this[0]), fragment ),
first = fragment.firstChild;

if ( first )
for ( var i = 0, l = this.length; i <>
callback.call( root(this[i], first), this.length > 1 || i > 0 ?
fragment.cloneNode(true) : fragment );
if ( scripts )
jQuery.each( scripts, evalScript );
}

return this;
function root( elem, cur ) {
return table && jQuery.nodeName(elem, "table") && jQuery.nodeName(cur, "tr") ?
(elem.getElementsByTagName("tbody")[0] ||
elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
elem;
}
}

Its logic will eval each script node within a html Dom being manipulate.
As a result, "Script Code inside moveMe" was being eval twice time. First is the page render, and second is the appending node.

Possible solution is to remove the script node before the DOM append action.

//This is prevent the script block being event again during append.
$("#"+item.Id+" script").remove();
$('#newLocation').append($('#moveMe'));

Patch of jQuery.windowName.js to support XML content for cross domain ajax

By default, jquery cross domain ajax plugin jQuery.windowName.js is only support data type in json.
The trick to let it support xml, mock the xml object request header content-type is xml, and the following is the patch for jQuery.windowName.js, and it is depend on createXMLDocument plugin:

http://plugins.jquery.com/project/createXMLDocument

onreadystatechange = function(isTimeout) {
if (!requestDone && xhr && (xhr.readyState === 4 || isTimeout === "timeout")) {
requestDone = true;
if (ival) {
clearInterval(ival);
ival = null;
}
status = isTimeout === 'timeout' && 'timeout' || !$.httpSuccess(xhr) && "error" || 'success';
if (status === 'success') {
try {
//Patched by Cyrus
// When the response is XML, the XML response is in xhr.responseText instead of
// xhr.responseXML. We think it is a bug in jQuery.windowName.js.
var ct = xhr.getResponseHeader("content-type");
var isXml = s.dataType == "xml" || !s.dataType && ct && ct.indexOf("xml") >= 0;
if (isXml) {
var xmlText = xhr.responseText;
// During server side XML serialization, in some cases (to be determined exactly where)
// we have a '?' in front of an xml response. Need to take it out.
if (xmlText.indexOf('?') == 1) {
xmlText = xmlText.substring(1);
}
//IE 8 cannot handle start with <?xml version="1.0" encoding="utf-8"?>. Need to take it out
if (xmlText.indexOf('<?xml version="1.0" encoding="utf-8"?>') == 1) {
xmlText = xmlText.substring('<?xml version="1.0" encoding="utf-8"?>'.length + 1);
}
xhr.responseXML = $.createXMLDocument(xmlText);
console.log('Mocking xml');
}
/////////////////////////
data = $.httpData(xhr, s.dataType, s.dataFilter);
} catch (er) {
status = 'parsererror';
}
}