A solution for inserting a row using code - InfoPath Dev
in

InfoPath Dev

A solution for inserting a row using code

Last post 05-28-2008 11:31 AM by Albert. 2 replies.
Page 1 of 1 (3 items)
Sort Posts: Previous Next
  • 05-28-2008 07:58 AM

    • Albert
    • Top 500 Contributor
    • Joined on 04-03-2008
    • The Netherlands
    • Posts 32

    A solution for inserting a row using code

    Hi, i've tried to look for some code that inserts rows. I couldn't find any answer that satisfied me, for example missing node-order. So i've created my own method and just wanted to share it (jscript) with everyone here.

    It can:

    • Insert a row to a repeatinggroup
    • Insert a group which is not in default values
    • Respect the node order InfoPath expects
    • Use predicates, like my:repeating_group[3]/my:repeating_subgroup
    It can't:
    • Insert multiple rows, always the first node (selectSingleNode) will be used.
    • Insert a row at a specific location in a repeating group, the new node is always inserted at the end of a repeating group.

    //Inserts a node at the specified location
    function InsertNode(xpath)
    {
     //Get reference to the sampledocument (sampledata.xml)
     var domSample = XDocument.CreateDOM();
     domSample.async = false;
     domSample.validateOnParse = false;
     domSample.load("sampledata.xml");
     domSample.setProperty("SelectionNamespaces", XDocument.DOM.getProperty("SelectionNamespaces"));
     
     //Get reference to sample node, this will be inserted into the maindom
     var xpathSample = xpath;
     while(xpathSample.indexOf('[') != -1 && xpathSample.indexOf(']') != -1)
     {
      xpathSample = xpathSample.replace(xpathSample.substring(xpathSample.indexOf('['),  xpathSample.indexOf(']') + 1), "");
     }
     var nodeSample = domSample.selectSingleNode(xpathSample);
     if(nodeSample == null) throw new Error("Unable to insert node: '" + xpathSample + "' doesn't exist in sampledata.");

     //Get reference to parentnode 
     var xpathParent = xpath.slice(0, xpath.lastIndexOf('/'));
     var nodeParent = XDocument.DOM.selectSingleNode(xpathParent);
     if(nodeParent == null) throw new Error("Unable to insert node: Parent '" + xpathParent + "' doesn't exist.");
     
     //Determine if the parentnode has a sibling that can be used as a reference
     var nodeRef = null;
     var nodeSampleRef = nodeSample.nextSibling;
     while(nodeSampleRef != null && nodeSample.prefix == nodeSampleRef.prefix)
     {
      nodeRef = XDocument.DOM.selectSingleNode(xpathParent + "/" +  nodeSampleRef.nodeName);
      if(nodeRef != null) break;  
      nodeSampleRef = nodeSampleRef.nextSibling;
     }
     
     //Insert the node
     try
     {
      nodeParent.insertBefore(nodeSample, nodeRef);
     }
     catch(e)
     {
      throw new Error("Error inserting node. Are you trying to insert an already existing node while it is non-repeating?");
     }
    }

    //Example
    function btnExample::OnClick(eventObj)
    {
     try
     {
      InsertNode("/my:root/my:repeating_group");
      InsertNode("/my:root/my:repeating_group[3]/my:other_repeating_group");
      InsertNode("/my:root/my:repeating_group[my:field1 = "InfoPath"]/my:group_that_is_not_in_default_values");
      InsertNode("/my:root/my:group/my:group_that_is_not_in_default_values");
     }
     catch(e)
     {
      XDocument.UI.Alert(e.message);
     }
    }

    I've tested a bit in InfoPath 2007, but might be possible still some errors occur in specific situations. Let me know.

    Albert

    edit: forgot to metion you can't use [ and ] inside the predicates right now. And it might be a good idea to return the newly inserted node. If i can find some time i might take care of both.

  • 05-28-2008 11:17 AM In reply to

    Re: A solution for inserting a row using code

    Thanks Albert!

    A common desire is to insert a row templated from an existing row. So copy a row and then insert a clone to reduce the data entry. Would it be the last record or could you specify the sample row?

    Could your code be used for this?  Maybe you could explain as this would help others.

  • 05-28-2008 11:31 AM In reply to

    • Albert
    • Top 500 Contributor
    • Joined on 04-03-2008
    • The Netherlands
    • Posts 32

    Re: A solution for inserting a row using code

    The code reads the node from sampledata.xml, which contain all default values (= templated?). But its possible to change the code, so instead of reading a node from sampledata it can read a node from the maindom and clone it. It doesnt matter what if its the last or not. Its just a matter of selecting the right node with selectSingleNode and inserting it into the maindom. Maybe I could post an example later, something like 'function CopyNode(xpath)' or 'function CopyNode(nTemplate)'?

    Albert

Page 1 of 1 (3 items)
Copyright © 2003-2019 Qdabra Software. All rights reserved.
View our Terms of Use.