Add a field's value to a Repeating Table field programically. - InfoPath Dev Sign in | Join | Help in Newbie Questions InfoPath (Entire Site) InfoPath Dev InfoPath Dev is dedicated to bringing you the information and tools you need to be successful in your Microsoft Office InfoPath development projects. Home Blogs Forums Photos Downloads InfoPath Dev » InfoPath » Newbie Questions » Add a field's value to a Repeating Table field programically. Add a field's value to a Repeating Table field programically. Last post 08-26-2008 12:33 AM by Shiva. 19 replies. Page 1 of 2 (20 items) 1 2 Next > Sort Posts: Oldest to newest Newest to oldest Previous Next 08-11-2008 04:50 PM dlocc Joined on 06-23-2008 San Diego Posts 28 Add a field's value to a Repeating Table field programically. Reply Contact Hello, I have an InfoPath 2007 form template with a repeating table and a button. On-click the button adds a line to the repeating table using the following C# code: string myNamespace = NamespaceManager.LookupNamespace("my"); using (XmlWriter writer = MainDataSource.CreateNavigator().SelectSingleNode("/my:myFields/my:group1", NamespaceManager).AppendChild()) {writer.WriteStartElement("group2", myNamespace); writer.WriteElementString("field1", myNamespace, "Cell 1"); writer.WriteElementString("field2", myNamespace, "Cell 2");writer.WriteElementString("field3", myNamespace, "Cell 3"); writer.WriteEndElement(); writer.Close(); } What I need is for the values of 3 drop-downs to be displayed in the repeating table fields 1,2, and 3 instead the words "Cell 1" "Cell 2" "cell 3". I have tried to do this using rules to set a fields value, but that changes all the fields using that name in the repeating table. I know this is should be simple, I was using a rich text box before and used the following code to display the Fields when the user clicks a button: XPathNavigator nav = MainDataSource.CreateNavigator(); XPathNavigator rtfNav = nav.SelectSingleNode("//my:rtfField", NamespaceManager); using (XmlWriter rtfWriter = rtfNav.AppendChild()) { rtfWriter.WriteStartElement("div", "http://www.w3.org/1999/xhtml"); rtfWriter.WriteString(nav.SelectSingleNode("//my:Actions", NamespaceManager).Value); rtfWriter.WriteString(" By "); rtfWriter.WriteString(nav.SelectSingleNode("//my:ActionEmployee", NamespaceManager).Value); rtfWriter.WriteEndElement(); rtfWriter.WriteStartElement("div", "http://www.w3.org/1999/xhtml"); rtfWriter.WriteString("Date/Time: "); rtfWriter.WriteString(nav.SelectSingleNode("//my:ActionDate", NamespaceManager).Value); rtfWriter.WriteEndElement(); rtfWriter.Close(); } But now I decided to use the Repeating Table instead of Rich Text box and ran into the same problem I had before. Any tips, anwsers, workarounds are greatly appreciated. Thanks, Devin Walkerhttp://www.dlocc.com 08-11-2008 05:06 PM In reply to Hilary Stoupa Joined on 06-20-2008 Posts 13,297 Re: Add a field's value to a Repeating Table field programically. Mark as Not AnswerMark as Answer... Reply Contact Hey there -- If you want to use the code you have, it seems that you need to replace "Cell 1", "Cell 2" etc with the reference to the field in your form that has the value. So, if the code in your second sample is pointed to the nodes you want, you might be able to get away with something like this: string myNamespace = NamespaceManager.LookupNamespace("my");XPathNavigator nav = MainDataSource.CreateNavigator();using (XmlWriter writer = MainDataSource.CreateNavigator().SelectSingleNode("/my:myFields/my:group1", NamespaceManager).AppendChild()) { writer.WriteStartElement("group2", myNamespace); writer.WriteElementString("field1", myNamespace, nav.SelectSingleNode("//my:Actions", NamespaceManager).Value); writer.WriteElementString("field2", myNamespace, nav.SelectSingleNode("//my:ActionEmployee", NamespaceManager).Value); writer.WriteElementString("field3", myNamespace, nav.SelectSingleNode("//my:ActionDate", NamespaceManager).Value); writer.WriteEndElement(); writer.Close(); } Just as an aside, I haven't tested this. But if you are currently getting Cell 1, 2, and 3 from your initial sample, this would replace those values with values from form nodes. Hilary Stoupa 08-11-2008 10:15 PM In reply to dlocc Joined on 06-23-2008 San Diego Posts 28 Re: Add a field's value to a Repeating Table field programically. Mark as Not AnswerMark as Answer... Reply Contact Hi The problem is the code changes all of the field's values in the column instead of just the value of the current row. Thanks, Devin Walkerhttp://www.dlocc.com 08-12-2008 07:29 AM In reply to Hilary Stoupa Joined on 06-20-2008 Posts 13,297 Re: Add a field's value to a Repeating Table field programically. Mark as Not AnswerMark as Answer... Reply Contact I usually just clone the last node in the table or clone it from the sampledata.xml. Here is some sample code that clones the last node of a repeating group and fills values: //get values from a couple of fieldsstring xpath = "/my:myFields/my:field1";XPathNavigator field1 = MainDataSource.CreateNavigator().SelectSingleNode(xpath, NamespaceManager); xpath = "/my:myFields/my:field2";XPathNavigator field2 = MainDataSource.CreateNavigator().SelectSingleNode(xpath, NamespaceManager);//clone last repeating table rowxpath = "/my:myFields/my:group1/my:group2[last()]";XPathNavigator oldGroup = MainDataSource.CreateNavigator().SelectSingleNode(xpath, NamespaceManager);XPathNavigator newGroup = oldGroup.Clone(); //insert the new groupoldGroup.InsertBefore(newGroup); //set the values of the fieldsnewGroup.SelectSingleNode("my:field3", NamespaceManager).SetValue(field1.Value);newGroup.SelectSingleNode("my:field4", NamespaceManager).SetValue(field2.Value); Of course, with this code, the repeating table has to have at least one row present when you click the button that runs it (or change a field, or whatever event you are using). You can always use conditional formatting to hide that blank row. Hilary Stoupa 08-12-2008 08:17 AM In reply to zeroecho Joined on 10-23-2007 Yorkshire, UK Posts 39 Re: Add a field's value to a Repeating Table field programically. Mark as Not AnswerMark as Answer... Reply Contact Hilary,Is there any way other than "[last()]" to find out which row you are submitting a click from? I found out about clone this morning whilst trying to implement a "Copy row" button like the one OOTB Infopath 2007 comes with on the context menu to add it to a browser based form. I tested it and it copied the row just fine, told people it would be in the next version of the form due out in about 1 hour(!!) and then found out testing something else that it only copied the first row. last() works OK for now but ideally current() would be the best scenario. Any ideas?Thanks in advance. string xpath = "my:TimeReporting/my:PerActivity/my:Location"; XPathNavigator field1 = MainDataSource.CreateNavigator().SelectSingleNode(xpath, NamespaceManager);xpath = "my:TimeReporting/my:PerActivity[last()]"; XPathNavigator oldGroup = MainDataSource.CreateNavigator().SelectSingleNode(xpath,NamespaceManager); XPathNavigator newGroup = oldGroup.Clone(); oldGroup.InsertBefore(newGroup); 08-12-2008 08:42 AM In reply to dlocc Joined on 06-23-2008 San Diego Posts 28 Re: Add a field's value to a Repeating Table field programically. Mark as Not AnswerMark as Answer... Reply Contact Hello Hilary, I used your code to clone the repeating table row: //get values from a couple of fieldsstring xpath = "/my:myFields/my:Actions"; XPathNavigator Actions = MainDataSource.CreateNavigator().SelectSingleNode(xpath, NamespaceManager);xpath = "/my:myFields/my:ActionDate"; XPathNavigator ActionDate = MainDataSource.CreateNavigator().SelectSingleNode(xpath, NamespaceManager); //clone last repeating table rowxpath = "/my:myFields/my:group1/my:group2[last()]"; XPathNavigator oldGroup = MainDataSource.CreateNavigator().SelectSingleNode(xpath, NamespaceManager);XPathNavigator newGroup = oldGroup.Clone(); //insert the new group oldGroup.InsertBefore(newGroup); //set the values of the fieldsnewGroup.SelectSingleNode("my:field1", NamespaceManager).SetValue(Actions.Value); newGroup.SelectSingleNode("my:field2", NamespaceManager).SetValue(ActionDate.Value); But the code is still changing all of the values for column 1... Devin Walkerhttp://www.dlocc.com 08-12-2008 09:26 AM In reply to Hilary Stoupa Joined on 06-20-2008 Posts 13,297 Re: Add a field's value to a Repeating Table field programically. Mark as Not AnswerMark as Answer... Reply Contact All the values for one column change, but not the other? Do you have a rule set somewhere that may be running and setting all the values for that column? Hilary Stoupa 08-12-2008 09:34 AM In reply to Hilary Stoupa Joined on 06-20-2008 Posts 13,297 Re: Add a field's value to a Repeating Table field programically. Mark as Not AnswerMark as Answer... Reply Contact Hey, zeroecho: If you have a button in a repeating table, it knows where it is -- look at this on ClickedEventArgs memebers at MSDN. So, instead of using MainDataSource.CreateNavigator(), you'd use: XPathNavigator field4 = e.Source.SelectSingleNode("my:field4", NamespaceManager);MessageBox.Show(field4.Value); to pop up the row's field4 value in a message box, for demonstration purposes. Hilary Stoupa 08-12-2008 09:42 AM In reply to dlocc Joined on 06-23-2008 San Diego Posts 28 Re: Add a field's value to a Repeating Table field programically. Mark as Not AnswerMark as Answer... Reply Contact There's no rules set, All the values for once column change. I have a drop down list field, a date box, and a button. The date field works just fine, but the drop down list is changing all the values when the button clicks. No idea why this is happening as the date column is working properly. Devin Walkerhttp://www.dlocc.com 08-12-2008 09:44 AM In reply to Catharine Joined on 06-14-2007 Posts 324 Re: Add a field's value to a Repeating Table field programically. Mark as Not AnswerMark as Answer... Reply Contact Hi I am following this code as well - but I only know VB (and that not very well) My Xml looks like this <my:History1> <my:Name1></my:Name1> <my:Comment1></my:Comment1> </my:History1> <my:text1></my:text1> <my:text2></my:text2> I have converted the code to VB 'get values from a couple of fields Dim xpath As String = "/my:myFields/my:text1"Dim field1 As XPathNavigator = MainDataSource.CreateNavigator().SelectSingleNode(xpath, NamespaceManager) xpath = "/my:myFields/my:text2"Dim field2 As XPathNavigator = MainDataSource.CreateNavigator().SelectSingleNode(xpath, NamespaceManager) 'clone last repeating table row xpath = "/my:myFields/my:History1[last()]"Dim oldGroup As XPathNavigator = MainDataSource.CreateNavigator().SelectSingleNode(xpath, NamespaceManager) Dim newGroup As XPathNavigator = oldGroup.Clone() 'insert the new group oldGroup.InsertBefore(newGroup) 'set the values of the fieldsnewGroup.SelectSingleNode("name1", NamespaceManager).SetValue(field1.Value) newGroup.SelectSingleNode("comment1", NamespaceManager).SetValue(field2.Value) I am trying to debug and I get System.NullReferenceException was unhandled by user code Message="Object reference not set to an instance of an object." Source="TestInsertRow" StackTrace: at TestInsertRow.FormCode.Insert_Clicked(Object sender, ClickedEventArgs e) at Microsoft.Office.InfoPath.Internal.ButtonEventHost.OnButtonClick(DocActionEvent pEvent) at Microsoft.Office.Interop.InfoPath.SemiTrust._ButtonEventSink_SinkHelper.OnClick(DocActionEvent pEvent) When I try the newGroup.SelectSingleNode("name1", NamespaceManager).SetValue(field1.Value) line. What have I done wrong in my conversion ? 08-12-2008 09:47 AM In reply to dlocc Joined on 06-23-2008 San Diego Posts 28 Re: Add a field's value to a Repeating Table field programically. Mark as Not AnswerMark as Answer... Reply Contact Thanks, I actually would prefer to use VB as well. I just tested the C# code in a new form and it DOES NOT change all the values in the field. I'm clueless as to why my other form went whacko on me. Anyways, thanks for all the input everyone! Devin Walkerhttp://www.dlocc.com 08-12-2008 10:08 AM In reply to zeroecho Joined on 10-23-2007 Yorkshire, UK Posts 39 Re: Add a field's value to a Repeating Table field programically. Mark as Not AnswerMark as Answer... Reply Contact public void CTRL244_5_Clicked(object sender, ClickedEventArgs e) { string xpath = "/my:TimesheetDetails/my:EmployeeInformation/my:TimeReporting/my:PerActivity"; XPathNavigator oldGroup = e.Source.SelectSingleNode(xpath,NamespaceManager); XPathNavigator newGroup = oldGroup.Clone(); oldGroup.InsertBefore(newGroup); }PerActivity is a group containing multiple fields I am trying to copy depending on which row the user presses the "Copy" button on.When I use e.Source.SelectSingleNode and press the Copy button, it simply copies the top node only. It doesn't copy the current field. As far as I was aware, the Button wasn't aware of any XML structure, as it's just a button because that was the first thing I tried but it didn't work.Thanks for the help so far by the way. I've uploaded the last() version for the time being but am hoping I can figure this one out soon. 08-12-2008 10:17 AM In reply to Hilary Stoupa Joined on 06-20-2008 Posts 13,297 Re: Add a field's value to a Repeating Table field programically. Mark as Not AnswerMark as Answer... Reply Contact Hi, zeroecho: The problem is your XPath. You are redirecting back to the root and selecting from there (which gives you the first one....) Let's say that your button is in a table connected to "my:TimeReporting". You would want e.Source.SelectSingleNode("my:PerActivity", NamespaceManager). e.Source will get you the correct "my:TimeReporting" row that the button is in. Hilary Stoupa 08-12-2008 10:19 AM In reply to Hilary Stoupa Joined on 06-20-2008 Posts 13,297 Re: Add a field's value to a Repeating Table field programically. Mark as Not AnswerMark as Answer... Reply Contact Hi, Catharine: I suspect your xpath in that line does not point to a valid node. Given your data structure, I would expect "my:Name1" for the first line and "my:Comment1" for the second. Hilary Stoupa 08-12-2008 12:24 PM In reply to zeroecho Joined on 10-23-2007 Yorkshire, UK Posts 39 Re: Add a field's value to a Repeating Table field programically. Mark as Not AnswerMark as Answer... Reply Contact Hi Hilary, Thanks again for your reply.I tried what you said, basically the button is the last row in a repeating table called PerActivity of which there contains a whole bunch of information. So then I press Copy I want the whole PerActivity repeating group to be copied.When I try without the entire XPath and just put the group name "my:PerActivity" it fails saying "XpathNavigator newGroup = oldGroup.Clone()' Object reference not set to an instance of an object"When I select any field from within PerActivity such as public void CTRL244_5_Clicked(object sender, ClickedEventArgs e) { string xpath = "/myLocation"; XPathNavigator oldGroup = e.Source.SelectSingleNode(xpath,NamespaceManager); XPathNavigator newGroup = oldGroup.Clone(); oldGroup.InsertBefore(newGroup); } I get Object reference not set to an instance of an objectWhen I try a field from within PerActivity and have the full xpath I get "Schema validation found non-date type errors"When I try a group within PerActivity "/my:TimesheetDetails/my:EmployeeInformation/my:TimeReporting/my:PerActivity/my:HoursPerDay" I get Object reference not set to an instance of an object (for both just /my:HoursPerDay and for the whole path)When adding a button in a repeating row theres nothing particularly special you have to do do you?/my:TimesheetDetails/my:EmployeeInformation/my:TimeReporting/my:PerActivity/my:HoursPerDay/my:Mon is the full xpath of the lowest field in my schema where PerActivity and EmployeeInformation are the only repeating groups.Frokm what you've said about redirecting back to the root and selecting from there it would seem that by doing e.Source("/my:RepeatingTable", NameSpaceManager) would do the trick, so either my button is being added/linked incorrectly or I'm getting the wrong end of the stick with the XPath query!Thanks again for your help, feel like I'm almost there and just a syntax error holding me back I hope :D Page 1 of 2 (20 items) 1 2 Next > Copyright © 2003-2019 Qdabra Software. All rights reserved.View our Terms of Use.
Hello,
I have an InfoPath 2007 form template with a repeating table and a button. On-click the button adds a line to the repeating table using the following C# code:
{
writer.WriteElementString(
writer.WriteEndElement();
writer.Close();
}
What I need is for the values of 3 drop-downs to be displayed in the repeating table fields 1,2, and 3 instead the words "Cell 1" "Cell 2" "cell 3". I have tried to do this using rules to set a fields value, but that changes all the fields using that name in the repeating table. I know this is should be simple, I was using a rich text box before and used the following code to display the Fields when the user clicks a button:
But now I decided to use the Repeating Table instead of Rich Text box and ran into the same problem I had before. Any tips, anwsers, workarounds are greatly appreciated.
Thanks,
Hey there --
If you want to use the code you have, it seems that you need to replace "Cell 1", "Cell 2" etc with the reference to the field in your form that has the value. So, if the code in your second sample is pointed to the nodes you want, you might be able to get away with something like this:
string myNamespace = NamespaceManager.LookupNamespace("my");XPathNavigator nav = MainDataSource.CreateNavigator();using (XmlWriter writer = MainDataSource.CreateNavigator().SelectSingleNode("/my:myFields/my:group1", NamespaceManager).AppendChild()) { writer.WriteStartElement("group2", myNamespace); writer.WriteElementString("field1", myNamespace, nav.SelectSingleNode("//my:Actions", NamespaceManager).Value); writer.WriteElementString("field2", myNamespace, nav.SelectSingleNode("//my:ActionEmployee", NamespaceManager).Value); writer.WriteElementString("field3", myNamespace, nav.SelectSingleNode("//my:ActionDate", NamespaceManager).Value); writer.WriteEndElement(); writer.Close(); }
Just as an aside, I haven't tested this. But if you are currently getting Cell 1, 2, and 3 from your initial sample, this would replace those values with values from form nodes.
Hi
The problem is the code changes all of the field's values in the column instead of just the value of the current row.
I usually just clone the last node in the table or clone it from the sampledata.xml. Here is some sample code that clones the last node of a repeating group and fills values:
//get values from a couple of fieldsstring xpath = "/my:myFields/my:field1";XPathNavigator field1 = MainDataSource.CreateNavigator().SelectSingleNode(xpath, NamespaceManager); xpath = "/my:myFields/my:field2";XPathNavigator field2 = MainDataSource.CreateNavigator().SelectSingleNode(xpath, NamespaceManager);//clone last repeating table rowxpath = "/my:myFields/my:group1/my:group2[last()]";XPathNavigator oldGroup = MainDataSource.CreateNavigator().SelectSingleNode(xpath, NamespaceManager);XPathNavigator newGroup = oldGroup.Clone(); //insert the new groupoldGroup.InsertBefore(newGroup); //set the values of the fieldsnewGroup.SelectSingleNode("my:field3", NamespaceManager).SetValue(field1.Value);newGroup.SelectSingleNode("my:field4", NamespaceManager).SetValue(field2.Value);
xpath =
Of course, with this code, the repeating table has to have at least one row present when you click the button that runs it (or change a field, or whatever event you are using). You can always use conditional formatting to hide that blank row.
Is there any way other than "[last()]" to find out which row you are submitting a click from? I found out about clone this morning whilst trying to implement a "Copy row" button like the one OOTB Infopath 2007 comes with on the context menu to add it to a browser based form. I tested it and it copied the row just fine, told people it would be in the next version of the form due out in about 1 hour(!!) and then found out testing something else that it only copied the first row. last() works OK for now but ideally current() would be the best scenario. Any ideas?
Thanks in advance.
string xpath = "my:TimeReporting/my:PerActivity/my:Location"; XPathNavigator field1 = MainDataSource.CreateNavigator().SelectSingleNode(xpath, NamespaceManager);
xpath = "my:TimeReporting/my:PerActivity[last()]"; XPathNavigator oldGroup = MainDataSource.CreateNavigator().SelectSingleNode(xpath,NamespaceManager); XPathNavigator newGroup = oldGroup.Clone();
oldGroup.InsertBefore(newGroup);
Hello Hilary,
I used your code to clone the repeating table row:
newGroup.SelectSingleNode(
But the code is still changing all of the values for column 1...
All the values for one column change, but not the other? Do you have a rule set somewhere that may be running and setting all the values for that column?
Hey, zeroecho:
If you have a button in a repeating table, it knows where it is -- look at this on ClickedEventArgs memebers at MSDN. So, instead of using MainDataSource.CreateNavigator(), you'd use:
XPathNavigator field4 = e.Source.SelectSingleNode("my:field4", NamespaceManager);MessageBox.Show(field4.Value);
XPathNavigator
to pop up the row's field4 value in a message box, for demonstration purposes.
There's no rules set, All the values for once column change. I have a drop down list field, a date box, and a button. The date field works just fine, but the drop down list is changing all the values when the button clicks. No idea why this is happening as the date column is working properly.
Hi I am following this code as well - but I only know VB (and that not very well)
My Xml looks like this
<my:History1> <my:Name1></my:Name1> <my:Comment1></my:Comment1> </my:History1> <my:text1></my:text1> <my:text2></my:text2>
I have converted the code to VB
oldGroup.InsertBefore(newGroup)
I am trying to debug and I get
System.NullReferenceException was unhandled by user code Message="Object reference not set to an instance of an object." Source="TestInsertRow" StackTrace: at TestInsertRow.FormCode.Insert_Clicked(Object sender, ClickedEventArgs e) at Microsoft.Office.InfoPath.Internal.ButtonEventHost.OnButtonClick(DocActionEvent pEvent) at Microsoft.Office.Interop.InfoPath.SemiTrust._ButtonEventSink_SinkHelper.OnClick(DocActionEvent pEvent)
When I try the newGroup.SelectSingleNode("name1", NamespaceManager).SetValue(field1.Value) line. What have I done wrong in my conversion ?
Thanks, I actually would prefer to use VB as well.
I just tested the C# code in a new form and it DOES NOT change all the values in the field. I'm clueless as to why my other form went whacko on me. Anyways, thanks for all the input everyone!
PerActivity is a group containing multiple fields I am trying to copy depending on which row the user presses the "Copy" button on.
When I use e.Source.SelectSingleNode and press the Copy button, it simply copies the top node only. It doesn't copy the current field. As far as I was aware, the Button wasn't aware of any XML structure, as it's just a button because that was the first thing I tried but it didn't work.
Thanks for the help so far by the way. I've uploaded the last() version for the time being but am hoping I can figure this one out soon.
Hi, zeroecho:
The problem is your XPath. You are redirecting back to the root and selecting from there (which gives you the first one....) Let's say that your button is in a table connected to "my:TimeReporting". You would want e.Source.SelectSingleNode("my:PerActivity", NamespaceManager). e.Source will get you the correct "my:TimeReporting" row that the button is in.
Hi, Catharine:
I suspect your xpath in that line does not point to a valid node. Given your data structure, I would expect "my:Name1" for the first line and "my:Comment1" for the second.
Hi Hilary,
Thanks again for your reply.
I tried what you said, basically the button is the last row in a repeating table called PerActivity of which there contains a whole bunch of information. So then I press Copy I want the whole PerActivity repeating group to be copied.
When I try without the entire XPath and just put the group name "my:PerActivity" it fails saying "XpathNavigator newGroup = oldGroup.Clone()' Object reference not set to an instance of an object"
When I select any field from within PerActivity such as
public void CTRL244_5_Clicked(object sender, ClickedEventArgs e) { string xpath = "/myLocation"; XPathNavigator oldGroup = e.Source.SelectSingleNode(xpath,NamespaceManager); XPathNavigator newGroup = oldGroup.Clone(); oldGroup.InsertBefore(newGroup); }
I get Object reference not set to an instance of an object
When I try a field from within PerActivity and have the full xpath I get "Schema validation found non-date type errors"
When I try a group within PerActivity "/my:TimesheetDetails/my:EmployeeInformation/my:TimeReporting/my:PerActivity/my:HoursPerDay" I get Object reference not set to an instance of an object (for both just /my:HoursPerDay and for the whole path)
When adding a button in a repeating row theres nothing particularly special you have to do do you?
/my:TimesheetDetails/my:EmployeeInformation/my:TimeReporting/my:PerActivity/my:HoursPerDay/my:Mon is the full xpath of the lowest field in my schema where PerActivity and EmployeeInformation are the only repeating groups.
Frokm what you've said about redirecting back to the root and selecting from there it would seem that by doing e.Source("/my:RepeatingTable", NameSpaceManager) would do the trick, so either my button is being added/linked incorrectly or I'm getting the wrong end of the stick with the XPath query!
Thanks again for your help, feel like I'm almost there and just a syntax error holding me back I hope :D