getting the current row in a repeating table
-
Friday, March 16, 2007 4:05 PMHi,
I have a repeating table with an "on change" event for one of the columns. When a value in this column changes, I need to update the value of another field in the same row. So far, I have been unable to get the current row within the "on change" event handler. Here's some more information that may be helpful in coming up with a solution:
- Although I used the terms row and field, let me be clear that the datasource is actually an XmlDocument returned from a web service, not a database. The various "fields" displayed in a row of the repeating table are various attributes on the same node.
- The solution, whatever it is, must work in a browser-enabled form. The InfoPath client will not be used, only browsers.
- I don't think using a "rule" will work since I need the logic to happen whenever the value in the field has changed, regardless of what the actual value is. Also, the logic must not happen if the value hasn't changed. Rules don't appear to allow for this.
- The "sender" object for the on change event handler is an attribute - the one whose change is triggering the event. Unfortunately, I can't seem to get a reference to the object for which it is an attribute. (The value of e.OldParent is null. Using a relative xpath such as "./@otherattribute" or "../@otherattribute" returns a null reference. And when I tried using an absolute xpath with the current() function in it, such as "/dfs:myfields/dfs:datafields/.../record[@alias = current()/@alias]", I get an error saying that an XsltReference is needed due to an unknown function. In other words, it doesn't recognize the current() function.
I've been trying to get this working for a while and I'm getting frustrated. This should be fairly easy. It is a show-stopper on a project with high visibility in the company. Please help! Thanks in advance!
All Replies
-
Monday, March 19, 2007 3:13 PMHi. I had this problem two or three weeks ago.
Here is the answer for your problem (i hope):
public void myFieldInRow_Changed(object sender, XmlEventArgs e)
{
XPathNavigator node2 = getBrother(e.Site, "my:myFieldInRow2");
node2.SetValue("hello... here is my node myFieldInRow2 in the row of this node... I'm good.. i can get it with a few lines of code");
}
// this method returns the brother node of node whith the name "nameBrother"
private XPathNavigator getBrother(XPathNavigator node, string nameBrother)
{
XPathNodeIterator it = node.SelectAncestors(XPathNodeType.Element, false);
it.MoveNext();
XPathNavigator nodeFather = it.Current;
XPathNodeIterator brothers = nodeFather.SelectChildren(XPathNodeType.Element);
foreach (XPathNavigator brother in brothers)
{
if (brother.Name.Equals(nameBrother))
return brother;
}
return null;
} -
Thursday, March 22, 2007 12:53 PM
Hi,
During the Changed Event of the repeating Table, initially you should check whether the XmlOperation is Value Change operation. This you can achieve by comparing "e.Operation" with the Enumeration of XmlOperation.
Now once you are confirmed that the Value change operation has occured in the Repeating Table changed Event, to get the current instance of the Row of the repeating table, you can use "e.Site". This would give the XPathNavigator of the current inserted row.
Once you have got the XPathNavigator of the inserted row, you can easily update the value of any field in that row by using "e.Site.SelectSingleNode("xPath of node", this.NamespaceManager).SetValue("Your Value");
Regards,
Amit
-
Saturday, April 28, 2007 10:53 AM
Amit, shame you didn't include a code example. The first blog does work...though probably not the most effecient mechanism. The 2nd Blog seems to be missing something as referencing e.site isn't enough. I've included a code sample of what it should be. Please include the routine DeleteNil as you can't assign a value to a null node. If theres a more effecient way..by all means post a blog. Cheers
public void Items_UnitGross_Changed(object sender, XmlEventArgs e){
// Check if value has changed and not a table insertion if (e.Operation == XmlOperation.ValueChange){
// Get Current Row XPathNavigator xNavigator = e.Site; bool bParent = xNavigator.MoveToParent(); // Get Reference to the Gross Value XPathNavigator xField = xNavigator.SelectSingleNode("boc:UnitGross", this.NamespaceManager);DeleteNil(xField);
double dGross = Convert.ToDouble(xField.Value); // Get Reference and set the Net ValuexField = xNavigator.SelectSingleNode(
"boc:UnitNet", this.NamespaceManager);DeleteNil(xField);
xField.SetValue(getNet(dGross).ToString());
}
}
public void DeleteNil(XPathNavigator node){
if (node.MoveToAttribute("nil", "http://www.w3.org/2001/XMLSchema-instance"))node.DeleteSelf();
}
private double getNet(double Gross){
// Calculates the Net Value (without Tax) from the Gross value double dNet = Gross / C_VATRATE_DIV; return dNet;}

