repeating table add rows programaticly - InfoPath Dev
in

InfoPath Dev

Use our Google Custom Search for best site search results.

repeating table add rows programaticly

Last post 07-19-2016 05:32 AM by mloftus. 39 replies.
Page 2 of 3 (40 items) < Previous 1 2 3 Next >
Sort Posts: Previous Next
  • 07-11-2008 04:30 AM In reply to

    Re: repeating table add rows programaticly

    Yes i have solved this problem. And you can check the shortest solution on my blog

    http://sharepointtopics.blogspot.com/

    thanks

    :)

  • 08-12-2008 09:54 AM In reply to

    • Patrick
    • Top 500 Contributor
      Male
    • Joined on 11-04-2007
    • Texas
    • Posts 51

    Re: repeating table add rows programaticly

    Hi  Hilary,

     I am using InfoPath 2007.  I used the code you wrote as a guideline for creating the text box that will designate the # of rows to add to a repeating table.

    I should note that I have this group  set up as a master/detail in one view, and a repeating table in another view (with different controls displaying)

    However, I am getting some errors when I execute in the preview (i can do this in a preview right?).  There are no build errors when I am in VSTA, and I made a button to run the code.  When I execute with the button I am getting these errors within InfoPath:

    Request failed.
       at Microsoft.Office.InfoPath.MsxmlNavigator.IsValidNode(MsxmlNode test)
       at Microsoft.Office.InfoPath.MsxmlNavigator.MoveToFirstChild()
       at MS.Internal.Xml.XPath.XPathChildIterator.MoveNext()
       at MS.Internal.Xml.XPath.ChildrenQuery.Advance()
       at MS.Internal.Xml.XPath.ChildrenQuery.Advance()
       at MS.Internal.Xml.XPath.ChildrenQuery.Advance()
       at MS.Internal.Xml.XPath.ChildrenQuery.Advance()
       at MS.Internal.Xml.XPath.XPathSelectionIterator.MoveNext()
       at System.Xml.XPath.XPathNavigator.SelectSingleNode(XPathExpression expression)
       at System.Xml.XPath.XPathNavigator.SelectSingleNode(String xpath, IXmlNamespaceResolver resolver)
       at OMS_ver1._2._23_Alpha_PH_XML.FormCode.CTRL_createSites_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)

    Here is my code:

    I had changed one thing from what you posted, because it was giving me an error that I had already declared the variable 'xpath", so I changed it to 'xpath2' as you will see below.

    I'm not sure how to post the code correctly, so I apologize (how do you do it on this site?)

     

    Imports Microsoft.Office.InfoPath
    Imports System
    Imports System.Windows.Forms
    Imports System.Xml
    Imports System.Xml.XPath
    Imports mshtml


    Namespace OMS_ver1._2._23_Alpha_PH_XML
        Public Class FormCode
            ' Member variables are not supported in browser-enabled forms.
            ' Instead, write and read these values from the FormState
            ' dictionary using code such as the following:
            '
            ' Private Property _memberVariable() As Object
            '     Get
            '         _memberVariable = FormState("_memberVariable")
            '     End Get
            '     Set
            '         FormState("_memberVariable") = value
            '     End Set
            ' End Property
           
            ' NOTE: The following procedure is required by Microsoft Office InfoPath.
            ' It can be modified using Microsoft Office InfoPath.
            Private Sub InternalStartup(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Startup
                AddHandler DirectCast(EventManager.ControlEvents("CTRL_createSites"), ButtonEvent).Clicked, AddressOf CTRL_createSites_Clicked
            End Sub

            Public Sub CTRL_createSites_Clicked(ByVal sender As Object, ByVal e As ClickedEventArgs)
                'Get the value of the text box that holds the number of rows to add
                Dim xpath As String = "/my:OMS/my:UniversalInformation_sec/my:UI_Addrows_sec/my:UI_AddRows_txt"
                Dim field As XPathNavigator = MainDataSource.CreateNavigator().SelectSingleNode(xpath, NamespaceManager)

                'Get the node that will be repeated/cloned
                xpath = "/my:OMS/my:SiteSpecificInfo_sec"
                Dim group As XPathNavigator = MainDataSource.CreateNavigator().SelectSingleNode(xpath, NamespaceManager)

                'Cast the field's value to an integer to know howmany rows to add
                Dim rows As Integer = field.ValueAsInt

                'Loop, Cloning Group
                Dim i As Integer

                For i = 1 To rows - 1
                    Dim newRow As XPathNavigator = group.Clone()
                    newRow.InsertAfter(group)
                Next i

            End Sub
        End Class
    End Namespace



     

    -Patrick
    Filed under: , ,
  • 08-12-2008 10:05 AM In reply to

    • Patrick
    • Top 500 Contributor
      Male
    • Joined on 11-04-2007
    • Texas
    • Posts 51

    Re: repeating table add rows programaticly

     A quick update:

    I made my form Full Trust and Signed it, but I would rather have it in Domain Trust if possible.  I got no errors when in Full Trust and the code worked correctly...so thank you Hilary!

    Is there a way to make it work with Domain Trust?
     

    -Patrick
  • 08-12-2008 10:25 AM In reply to

    Re: repeating table add rows programaticly

    Hi, Patrick --

     So the code you put in the post before this works for you? And your form has to be in full trust for it to work in preview? Is your machine part of a domain? I ask because of this post by Greg Collins on his blog -- apparently there are issues with that.

    Hilary Stoupa

  • 08-12-2008 12:57 PM In reply to

    • Patrick
    • Top 500 Contributor
      Male
    • Joined on 11-04-2007
    • Texas
    • Posts 51

    Re: repeating table add rows programaticly

    Hilary,

    Yes that's correct.  I have the form in Full Trust, I am part of a Domain, and the code works ONLY when I have it set to Full Trust.  The preview works in Domain, but the code does not.  I browsed through Greg's article and it sounds like he was having issues with the form previewing correctly, right?  I would say mine is more with the code running correctly, but they very well could be related directly.  I'm not sure :(

    Now I'm back to battling with the performance of the form and all its data sources... 

    -Patrick
  • 09-02-2008 02:21 PM In reply to

    • Patrick
    • Top 500 Contributor
      Male
    • Joined on 11-04-2007
    • Texas
    • Posts 51

    Re: repeating table add rows programaticly

    Hi Hilary,

    I was revisiting this issue because I ran into a problem when running the code.  To update, here is the code I adapted to C# from your post earlier:

    public void CTRL_createSites_Clicked(object sender, ClickedEventArgs e)
            {
                //Get the value of the text box that holds the number of rows to add
                string xpath = "/my:OMS/my:UniversalInformation_sec/my:UI_Addrows_sec/my:UI_AddRows_txt";
                XPathNavigator field = MainDataSource.CreateNavigator().SelectSingleNode(xpath, NamespaceManager);
     
                //Get the node that will be repeated/cloned
                xpath = "/my:OMS/my:SiteSpecificInfo_sec";
                XPathNavigator group = MainDataSource.CreateNavigator().SelectSingleNode(xpath, NamespaceManager);
     
                //Cast the field's value to an integer to know how many rows to add
                int rows = field.ValueAsInt;
     
                //Loop, Cloning Group
                int i;
     
                for (i = 1; i <= rows - 1; i++)
                {
                    XPathNavigator newRow = group.Clone();
                    newRow.InsertAfter(group);
                }
            }

     

    What's happening are the following issues:

    1.  If I try to create more than 20 rows, the program usually (90% of the time) locks up and won't respond.

    2. If I select a node with information already in it, then it clones it and creates 'x' number of cloned rows with the same info.  (This isn't a problem, just noting that this is what happens.  I'm pretty sure that's what the code is telling it to do anyway, but for the original issue in this post, the caveat was to start with a blank row, right?

     

    The real issue is the time it takes to create the rows with the code (example: it takes about 9 seconds to clone 5 rows, and another 18 seconds if I clone 5 more right after that).  I don't know why it locks up, but it may have something to do with the number of fields located in that group string = xpath.  When cloning the rows, does it clone the controls that are only inserted in the form, or the whole schema associated with that group?
     

    Is there a faster way? Perhaps without cloning the node?  I am wondering about the AppendChild() method...  I'm not sure if that suggestion even makes sense.... 

    -Patrick
    Filed under: , , ,
  • 09-03-2008 07:53 AM In reply to

    Re: repeating table add rows programaticly

    Hey, Patrick:

     I'd suggest that you clone your node from the sampledata.xml, since you want to make sure that the information isn't copied from the previous row. And you can use AppendChild() to be sure -- as far a performance goes, you'd need to test it, see if it improves the amount of time things seem to be taking.

    A few notes on cloning from sampledata.xml -- here is a post that shows how to get that file from you template using IP 2007 C#. You'll need to beware the xsi:nil attribute on any fields that it applies to (dates, numbers) and this post can help you with that.

    Oh, and yes, the clone method is cloning the entire group, including all the fields below it, regardless of the controls on your form. You are working with the data structure, not with the controls.

    Let me know if you need more help, okay?
    Hilary Stoupa

  • 09-03-2008 08:42 AM In reply to

    • Patrick
    • Top 500 Contributor
      Male
    • Joined on 11-04-2007
    • Texas
    • Posts 51

    Re: repeating table add rows programatically

    Thank Hilary I will look at using the sampledata.xml, but I'm not entirely sure how to go about using the AppendChild() method.  I was playing around with it and I can't seem to get it to do anything, even if it builds correctly. 

    -Patrick
  • 09-03-2008 09:27 AM In reply to

    Re: repeating table add rows programatically

    Here is a link to the MSDN documentation. For example:

    if (e.Operation.ToString().Equals("ValueChange"))           
    {
                   
        
         XPathDocument
    sampleData = new XPathDocument(this.Template.OpenFileFromPackage("sampledata.xml"));
                   
        
    XPathNavigator newGroup = sampleData.CreateNavigator().SelectSingleNode("/my:myFields/my:topGroup/my:repeatingGroup", NamespaceManager).Clone();
                   
        
    XPathNavigator rootNode = MainDataSource.CreateNavigator().SelectSingleNode("/my:myFields/my:topGroup", NamespaceManager);
                   
        
    rootNode.AppendChild(newGroup);

               
    }

    in the Changed event of a field in the repeating group clones the node from the sampledata and appends it back to the group containing the repeating group.

    Hilary Stoupa

  • 09-03-2008 10:37 AM In reply to

    • Patrick
    • Top 500 Contributor
      Male
    • Joined on 11-04-2007
    • Texas
    • Posts 51

    Re: repeating table add rows programatically

    Most of that makes sense to me (what you wrote above), but what about the if statement?  If I want to have this run when a button is clicked, then I can just use the rest right? 

    -Patrick
  • 09-03-2008 10:48 AM In reply to

    Re: repeating table add rows programatically

    Yah, I used the if statement so that if this was on the changed event of a field I wouldn't end up in an infinite loop.

    Hilary Stoupa

  • 09-03-2008 10:58 AM In reply to

    • Patrick
    • Top 500 Contributor
      Male
    • Joined on 11-04-2007
    • Texas
    • Posts 51

    Re: repeating table add rows programatically

    Ok that's what I figured.  I tried the AppendChild() method and it worked, but the performance was worse :(  It was worth a try though.  Adding 5 rows took 2.5 times longer than the cloning method.   

    -Patrick
  • 11-10-2008 03:39 PM In reply to

    Re: repeating table add rows programaticly

    Hi Hilary,

     I am using the clone method to copymy repeating table row and then insert it into the table.   I was wondering what the proper way to set a value of the fields prior to the insert after call.

    XPathNavigator group = MainDataSource.CreateNavigator().SelectSingleNode("/my:ProjectTicket/my:BudgetMaster/my:BudgetLine", NamespaceManager);

    XPathNavigator NewRow = group.Clone();

    //Set each field value prior to inserting, ie i Have a field called LineStatus the is in BudgetLine that I would like to set a value for.

    NewRow.InsertAfter(group);

    Thanks,

    Jeff

  • 11-10-2008 04:21 PM In reply to

    Re: repeating table add rows programaticly

    Have you tried:

    CurrentView.ExecuteAction(ActionType.XCollectionInsert, "XmlToEdit");

    where XmlToEdit is a unique identifier for the repeating table that you can find in the InfoPath designer?  This mimics the behavior that InfoPath carries out when a user adds a row to a repeating table/section and takes all the guesswork out of adding rows to repeating tables/sections.

    Jimmy Rishe / Software Developer / Microsoft MVP
    Qdabra Software
  • 11-10-2008 05:31 PM In reply to

    Re: repeating table add rows programaticly

    Hi, Jeff:

    If you follow Jimmy's suggestion, the node you will want to set the values on will be the last node in your repeating group. So you could create an XPathNavigator variable to the last node, like this:

    XPathNavigator group = MainDataSource.CreateNavigator().SelectSingleNode("/my:ProjectTicket/my:BudgetMaster/my:BudgetLine[last()]", NamespaceManager);

    Then you could set the values by selecting single nodes from the group:

    group.SelectSingleNode("my:fieldInBudgetLineGroup").SetValue("A Value");

    If you want to use the code you are currently using, where you clone nodes, you can set the values on the nodes in the variable NewRow before inserting;

    NewRow.SelectSingleNode("my:fieldInBudgetLineGroup").SetValue("A Value");

    Does that make sense?

    Hilary Stoupa

Page 2 of 3 (40 items) < Previous 1 2 3 Next >
Copyright © 2003-2019 Qdabra Software. All rights reserved.
View our Terms of Use.