I have following grid in a component.
<t:grid t:id="resultsGrid" id="resultsGrid" inPlace="true"
source="results" row="result" rowIndex="rowIndex" rowsPerPage="50"
pagerPosition="top" model="model">
InPlace=true renders grid inside a zone and then each new page request
simply updates that zone. But in following case, zone update does not
take place.
Let's say for page 3, the grid data(rows) contains single quote. Page 3
is rendered fine but after that if you click on any other page number
then the zone is not updated. Browser does receive data from server for
new page but the zone update does not take place.
This happens only when data/text of grid contains a single quote e.g.
when there is "Adam's" in some row of grid. The zone is updated fine if
grid data does not contain single quote.
On more debugging I found that the issue starts in following function of
tapestry.js file.
In the process of updating zone, following function calls
purgeChildren(element) function.
/**
* Updates the zone's content, and invokes either the update
function (to
* highlight the change) or the show function (to reveal a hidden
element).
* Lastly, fires the Tapestry.ZONE_UPDATED_EVENT to let listeners
know that
* the zone was updated.
*
* @param content
*/
show : function(content) {
Tapestry.purgeChildren(this.updateElement);
this.updateElement.update(content);
var func = this.element.visible() ? this.updateFunc :
this.showFunc;
func.call(this, this.element, this.endcolor);
this.element.fire(Tapestry.ZONE_UPDATED_EVENT);
},
Following is purgeChildren(element) function which calls purge(element)
function.
/**
* Invokes purge() on all the children of the element.
*/
purgeChildren : function(element) {
var children = element.childNodes;
if (children) {
var l = children.length, i, child;
for (i = 0; i < l; i++) {
var child = children[i];
/* Just purge element nodes, not text, etc. */
if (child.nodeType == 1)
Tapestry.purge(children[i]);
}
}
}
And finally, following is purge(element) function which is where the
zone update process breaks. In this function 'Unexpected identifier'
exception is thrown when grid data contains single quote.
//this is where the problem is.
/**
* Purges the element of any event handlers (necessary in IE to
ensure that
* memory leaks do not occur, and harmless in other browsers). The
element
* is purged, then any children of the element are purged.
*/
purge : function(element) {
// removes all functions/handlers attached to this element
/* Adapted from http://javascript.crockford.com/memory/leak.html
*/
var attrs = element.attributes;
if (attrs) {
var i, name;
for (i = attrs.length - 1; i >= 0; i--) {
if (attrs[i]) {
name = attrs[i].name;
/* Looking for onclick, etc. */
if (typeof element[name] == 'function') {
element[name] = null;
}
}
}
}
/* Get rid of any Prototype event handlers as well. */
Event.stopObserving(element);
Tapestry.purgeChildren(element);
},
As mentioned in comment purge(element) function removes all handler
functions of the element and is perhaps necessary in IE for memory
leaks.
I could fix the issue by changing purge(element) function in following
way. Comment out the code which removes handlers of the element. Upon
making this change the zone is updated fine, even if the data contains
single quote.
purge : function(element) {
// removes all functions/handlers attached to this element
/* Adapted from http://javascript.crockford.com/memory/leak.html */
// var attrs = element.attributes;
// if (attrs) {
// var i, name;
// for (i = attrs.length - 1; i >= 0; i--) {
// if (attrs[i]) {
// name = attrs[i].name;
// // Looking for onclick, etc
// if (typeof element[name] == 'function') {
// element[name] = null;
// }
// }
// }
// }
/* Get rid of any Prototype event handlers as well. */
Event.stopObserving(element);
// Tapestry.purgeChildren(element);
},
But this is not a good fix. I have following questions, any help with
them would be great.
1: Why does the code in purge function break with single quote in data
while removing handlers of the passed element?
2: The data is fed to grid from a source class which extends
GridDataSource interface. Thus, the grid data is generated by tapestry
from that source class and hence handling of special characters is also
supposed to be done by tapestry. Will it help if I add toString() method
in data container class for grid?
3: Is there any other way of implementing purge(element) function so
that it does not break with single quotes in data?
4: I am using tapestry version 5.2.4 , can this issue be fixed if I
upgrade to latest version?
5: What can be potential problems in changing purge(element) function
the way I have changed it to avoid the exception? How unsafe/safe that
change is?
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]