View Full Version : setNodes and gridcolumn/text refresh
frethog
03-25-2008, 11:41 AM
Upon clicking of the merge button, which execute setNodes, you can see that the replication manager clones is a merged resultset by typing allGridId.clones in the debug window and noting the array length or inspecting each clones[x] node.
However, why isn't the updated data represented with a refreshed grid?
Any suggestions on how to make that happen?
Thanks, frethog
<canvas debug="true">
<dataset name="afupDS" >
<Rows><Row record_status="c"><case>brief</case><cs_office>2</cs_office><barney>dinosaur</barney></Row></Rows>
</dataset>
<dataset name="casesDS">
<Rows><Row record_status="u"><case>book</case><cs_office>3</cs_office></Row><Row record_status="z"><case>suit</case><cs_office>1</cs_office></Row></Rows>
</dataset>
<grid id="allGridId" datapath="casesDS:/Rows" contentdatapath="Row" height="100" >
<gridcolumn >Case<text datapath="case/text()" /></gridcolumn>
<gridtext datapath="cs_office/text ()" editable="false" >Office</gridtext>
<gridtext datapath="@record_status" editable="false" >flag</gridtext>
</grid>
<button name="action1" text="Merge" onclick="merge()">
<method name="merge">
var afup_list = new Array(afupDS.getPointer().xpathQuery("afupDS:/Rows/Row"));
var new_map = appendDataset(afup_list);
allGridId.datapath.setNodes(new_map);
</method>
<method name="appendDataset" args="list1">
<![CDATA[
var map = casesDS.getPointer().xpathQuery("casesDS:/Rows/Row");
var lasti = map.length;
for(var i=0;i<list1.length;i++) map[lasti+i]=list1[i];
return map;
]]>
</method>
</button>
<simplelayout/>
</canvas>
senshi
03-25-2008, 12:34 PM
This works for me:
<button name="action1" text="Merge" >
<handler name="onclick">
var toArray = function(a) {
return a ? a instanceof Array ? a : [a] : [];
}
var afup_list = toArray(afupDS.getPointer().xpathQuery("afupDS:/Rows/Row"));
var cases_list = toArray(casesDS.getPointer().xpathQuery("casesDS:/Rows/Row"));
var repl = allGridId._getReplicator();
if (repl instanceof LzReplicationManager) {
repl.setNodes(afup_list.concat(cases_list));
} else {
repl.datapath.setNodes(afup_list.concat(cases_list ));
}
</handler>
</button>
frethog
03-25-2008, 01:04 PM
"This was the code I was looking for..."
Worked for me too. Thank you Senshi,
frethog
senshi
03-25-2008, 01:10 PM
May the force be with you! :D
frethog
03-26-2008, 09:30 AM
Ok, here's a wrinkle...
If there's a second grid (id="urgentGridId") having same datapath, but with contentdatapath="Row[@record_status='u']" and we take the same approach of explicitly grabbing the replication manager and using setNodes... the second grid displays as if the @record_status attribute isn't being examined at all. :eek: All rows are displayed in the second grid.
My attempts, post-merge, to explicitly set the contentdatapath to "Row[@record_status='u']" yields a display of rows equivalent of pre-merge. (That code not included here.) It's as if the replication manager binds the grid back to the original dataset and not the merged copy.
Here's code that demonstrates the apparent ignoring :confused: of contentdatapath.
<canvas debug="true">
<dataset name="afupDS" >
<Rows><Row record_status="u"><case>brief</case><cs_office>2</cs_office><barney>dinosaur</barney></Row></Rows>
</dataset>
<dataset name="casesDS">
<Rows><Row record_status="o"><case>book</case><cs_office>3</cs_office></Row><Row record_status="u"><case>suit</case><cs_office>3</cs_office></Row></Rows>
</dataset>
<text>ALL CASES:</text>
<grid id="allGridId" datapath="casesDS:/Rows" contentdatapath="Row" height="100" >
<gridcolumn >Case<text datapath="case/text()" /></gridcolumn>
<gridtext datapath="cs_office/text ()" editable="false" >Office</gridtext>
<gridtext datapath="@record_status" editable="false" >flag</gridtext>
</grid>
<text>URGENT CASES:</text>
<grid id="urgentGridId" datapath="casesDS:/Rows" contentdatapath="Row[@record_status='u']" height="100" >
<gridcolumn >Case<text datapath="case/text()" /></gridcolumn>
<gridtext datapath="cs_office/text ()" editable="false" >Office</gridtext>
<gridtext datapath="@record_status" editable="false" >flag</gridtext>
</grid>
<button name="action1" text="Load another case" >
<handler name="onclick">
var toArray = function(a) {
return a ? a instanceof Array ? a : [a] : [];
}
var afup_list = toArray(afupDS.getPointer().xpathQuery("afupDS:/Rows/Row"));
var cases_list = toArray(casesDS.getPointer().xpathQuery("casesDS:/Rows/Row"));
var repl = allGridId._getReplicator();
if (repl instanceof LzReplicationManager) {
repl.setNodes(afup_list.concat(cases_list));
} else {
repl.datapath.setNodes(afup_list.concat(cases_list ));
}
var repl_urg = urgentGridId._getReplicator();
if (repl_urg instanceof LzReplicationManager) {
repl_urg.setNodes(afup_list.concat(cases_list));
} else {
repl_urg.datapath.setNodes(afup_list.concat(cases_ list));
}
</handler>
</button>
<simplelayout/>
</canvas>
The 2nd grid should only display those having a record_status of 'u'.
Any hints/suggestions/thoughts welcome...
Thanks, frethog
senshi
03-26-2008, 12:50 PM
If there's a second grid (id="urgentGridId") having same datapath, but with contentdatapath="Row[@record_status='u']" and we take the same approach of explicitly grabbing the replication manager and using setNodes... the second grid displays as if the @record_status attribute isn't being examined at all. :eek: All rows are displayed in the second grid.
As expected: when you use the "setNodes"-method, you actually say to ignore any xpath and instead to use all nodes passed to the "setNodes" for replication.
untested:
var toArray = function(a) {
return a ? a instanceof Array ? a : [a] : [];
}
var afup_list = toArray(afupDS.getPointer().xpathQuery("afupDS:/Rows/Row"));
var cases_list = toArray(casesDS.getPointer().xpathQuery("casesDS:/Rows/Row"));
var repl_urg = urgentGridId._getReplicator();
var arrUrg = afup_list.concat(cases_list);
for (var i=0; i<arrUrg.length;) {
if (arrUrg[i].getAttr('record_status') != 'u') {
arrUrg.splice(i, 1);
} else {
i += 1;
}
}
if (repl_urg instanceof LzReplicationManager) {
repl_urg.setNodes(arrUrg);
} else {
repl_urg.datapath.setNodes(arrUrg);
}
frethog
03-27-2008, 05:28 AM
Senshi,
Your answer sounds like a definitive answer. And I appreciate that type of certainty.
And yes, in retrospect I see how ignoring-of-xpath should be expected when using setNodes.
However, I guess I expected a way to impose xpath on the newly-updated replication manager nodes. From your answer I'm betting that type of functionality is not part of OL 4.0.10 (to the best of your knowledge).
I understand the alternative is to maintain separate nodeslists, as you demonstrated, but I would prefer an re-imposing of xpath if possible.
Is that something you can speak to? Whether xpath can be re-imposed on post-setNodes replication manager datanodes.
Danke, frethog
senshi
03-27-2008, 08:11 AM
However, I guess I expected a way to impose xpath on the newly-updated replication manager nodes. From your answer I'm betting that type of functionality is not part of OL 4.0.10 (to the best of your knowledge).
I understand the alternative is to maintain separate nodeslists, as you demonstrated, but I would prefer an re-imposing of xpath if possible.
Is that something you can speak to? Whether xpath can be re-imposed on post-setNodes replication manager datanodes.
As far as I know, there is no public API to perform that kind of operation. You could use the internal API of LzDatapointer, but be aware of, internal means: not officially supported and it may change in future versions.
Btw, the "instanceof"-test is unnecessary, because on a ReplicationManager, the datapath property also points to that ReplicationManager, so: "repl.datapath === repl".
(Just found that while digging in the LzReplicationManager sources :))
<button name="action1" text="Merge" >
<handler name="onclick"><![CDATA[
var toArray = function(a) {
return a ? a instanceof Array ? a : [a] : [];
}
var afup_list = toArray(afupDS.getPointer().xpathQuery("afupDS:/Rows/Row"));
var cases_list = toArray(casesDS.getPointer().xpathQuery("casesDS:/Rows/Row"));
//normales grid
allGridId._getReplicator().datapath.setNodes(afup_ list.concat(cases_list));
//urgent grid
var repl_urg = urgentGridId._getReplicator().datapath;
var dp = new LzDatapointer(null);
var pp = repl_urg.parsedPath;
var result = [];
var arrUrg = afup_list.concat(cases_list);
for (var i=0; i<arrUrg.length; ++i) {
//3rd arg: '1' b/c "Row" is 1st selector (index 0),
//"[@record_status='u']" is 2nd selector (index 1)
var p = dp.__LZgetNodes(pp, arrUrg[i], 1);
if (p) {
//valid result
result.push(p);
}
}
repl_urg.setNodes(result);
]]></handler>
</button>
frethog
03-28-2008, 11:52 AM
For the benefit of those who find this thread and want to know the outcome...
merely changing this:
var pp = repl_urg.parsedPath;
to this:
var pp = repl_urg.parsePath("[@record_status='u']");
and senshi's deep-magic suggestion nailed it.
(Not shabby for untested code...IMO)
Thanks again for sharing your thoughts, senshi
*** END THREAD *** ;)
vBulletin® v3.8.4, Copyright ©2000-2012, Jelsoft Enterprises Ltd.