Compartilhar via


Conditional Presence versus Conditional Visibility

InfoPath supports a feature called Conditional Formatting which allows among other things to show or hide sections of the form based on some condition.

 

However, the underlying XML data still stays there even though it is not visible in the view. What if one wants to remove the XML data altogether? It is easy to achieve this by writing a little bit of code.

 

First of all, a trick: an optional leaf field can be wrapped in an Optional Section without adding any additional nodes in the Data Source. Suppose that your data source looks like that:

 

      myFields

              field1

 

Instead of dragging field1 into the view (which will produce a Text Box, assuming its datatype is a string), right-click on it, select More… and pick Optional Section with Controls.

 

Now the Text Box is wrapped in an Optional Section and you can remove or insert it as desired.

 

At this time, suppose that you want field1 appear conditionally based on a state of a Check Box bound to some node (let’s call it field2). Attach an “OnAfterChange” event to it with the following code:

 

function msoxd_my_field2::OnAfterChange(eventObj)

{

      if (eventObj.IsUndoRedo || eventObj.Operation != "Insert")

      {

            return;

      }

      if (eventObj.NewValue == "true")

      {

            XDocument.View.ExecuteAction("xOptional::insert", "field1_1");

      }

      else

      {

      XDocument.View.SelectNodes(XDocument.DOM.selectSingleNode("/my:myFields/my:field1"));

            XDocument.View.ExecuteAction("xOptional::remove", "field1_1");

      }

}

 

Here, we use the xOptional::insert command to insert field1 (and hence the Optional Section) when the Check Box is checked, and xOptional::remove to remove it when the Check Box is unchecked.

 

A few comments on the code above:

  • The “field1_1” string is the xmlToEdit name associated with the section. To find out what this name is for your section, look at the “Advanced” tab of the Optional Section properties.
  •  When executing actions, InfoPath is using the current XML context to determine how to perform the action. Clicking on the checkbox moves the XML context to field2 in our example. While InfoPath can still handle the insertion properly, it cannot figure out what section to delete. In order for xOptional::remove to succeed, we use SelectNodes() method on the view to set the xml context to the section we are trying to remove.
  • Finally, to prevent the user from inserting or deleting the Optional Section by other means than using the Check Box, bring up the properties of the Optional Section, click “Customize Commands” and uncheck everything under “Insert” and “Remove” actions. Also uncheck the “Show insert button and hint text”.

P.S. The conditional presence technique is especially useful in scenarios where the schema contains optional elements that are not allowed to be blank (which could be a desirable design in some scenarios where the XML-consuming backend cannot handle xsi:nils).

P.P.S. The technique of calling View.SelectNodes() can solve the ExecuteAction() focus/context problem. The ExecuteAction() documentation states that sometimes calling ExecuteAction() from button’s onClick can fail. Calling View.SelectNodes() from onClick shold remedy to this problem.

Comments

  • Anonymous
    July 28, 2006
    Is there any plans in the future to allow for insretion and deletion of optional sections from the designer?
  • Anonymous
    July 09, 2007
    Hi, I need to hide a complete view, which contains several textboxes supposed to be hidden from user. How to do this. The values are set/get in the rules and VS 2005 code in/from these texboxes. Now once I make this view invisible, will my code and rules still work properly? Any idea or help!! Thanks. zullu