Tuesday, April 17, 2012

How to dynamically add and remove values to a Drop-Down List control in InfoPath.

In InfoPath form you can bind repeating nodes to Drop-Down List control. This is an easy solution which dynamically adds and removes values to a Drop-Down List control.
1.       Create a blank InfoPath form and add a Drop-Down list control. Name it as ‘ContactsField’.


2.       Add a Group called ‘ContactsGroup’ under myFields.
Add a Group under ‘ContactsGroup’ called ‘ContactNode’, tick the Repeating checkbox.
Add two Text Fields under ‘ContactNode’ called ‘Name’ and ‘Phone’.




3.       Add two Text Box controls to the form called ‘NameField’ and ‘PhoneField’.



Go to Drop-Down List Box properties  and select “Get choices from fields in this form”. For Entities select the repeating node, Select “Name” under repeating node for both Display Name and Value.




Go to field properties of the “ContactsField” and type “Select…” as the default value in order to remove empty node displayed in Drop-Down control. (You can just remove default value and   check there’s empty node available)

4.       Go to Code Editor of the form. You can find it in the developer section in the ribbon. Add form loading event, from developer section in the ribbon. Use the following code.

/// <summary>
        /// Holds the main XPath navigator of the form
        /// </summary>
        private XPathNavigator mainNavigator;

        /// <summary>
        /// Holds the XPath navigator of a contact node in Contacts group
        /// </summary>
        private XPathNavigator contactNode;

        public void InternalStartup()
        {
            EventManager.FormEvents.Loading += new LoadingEventHandler(FormEvents_Loading);
        }

        /// <summary>
        /// Event of form loading.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">This instance containing the event data.</param>
        public void FormEvents_Loading(object sender, LoadingEventArgs e)
        {
            mainNavigator = this.MainDataSource.CreateNavigator();
            //When opening a saved form remove the existing contacts.
            RemoveContacts();

            //Add repeating nodes to the contactsGroup.
            PopulateContacts();           
        }

        /// <summary>
        /// Reset Contact Details
        /// </summary>
        public void RemoveContacts()
        {
            //Create XPathNavigator
            XPathNavigator contactsGroup = mainNavigator.SelectSingleNode("//my:ContactsGroup", this.NamespaceManager);
            contactNode = contactsGroup.SelectSingleNode("//my:ContactsGroup/my:ContactNode", this.NamespaceManager);
                       
            if (contactNode != null && contactsGroup != null)
            {
                //Removes previous contacts bindings
                XPathNavigator firstNode = contactsGroup.SelectSingleNode("//my:ContactNode[1]", this.NamespaceManager);
                XPathNavigator lastNode = contactsGroup.SelectSingleNode("//my:ContactNode[last()]", this.NamespaceManager);
                contactsGroup.MoveTo(firstNode);
                contactsGroup.DeleteRange(lastNode);
            }          
        }

        /// <summary>
        /// Add Contact Details
        /// </summary>
        public void PopulateContacts()
        {
            //Sample contacts are taken from a SortedList.
            //You can get contacts from database, external data source or web service instead.
            SortedList contactsList = new SortedList();
            contactsList.Add("SACHINdre Senasinghe", "0771112223");
            contactsList.Add("Malaka Chandrasekera", "0772223334");
            contactsList.Add("Chinthaka Siriwardena", "0771112225");
            contactsList.Add("Upul Chaminda", "0771112226");
            contactsList.Add("Suranga Kumarage", "0771112227");
            contactsList.Add("Udara Samaratunge", "0771112228");
            contactsList.Add("Dumidu Uragodage", "0771112229");

            //Create XPathNavigator
            XPathNavigator contactsGroup = mainNavigator.SelectSingleNode("//my:ContactsGroup", this.NamespaceManager);
           
            //Object is assigned to contactNode before deleting all the nodes from the group.
            //So this should not equals to null.
            if (contactNode != null)
            {
                //Node is added for empty contact selection.
                XPathNavigator emptyNode = contactNode.Clone();
                emptyNode.SelectSingleNode("my:Name", this.NamespaceManager).SetValue("Select...");
                contactsGroup.AppendChild(emptyNode);

                if (contactsList != null && contactsList.Count > 0)
                {
                    //Every contact is appended to the contactsGroup.
                    for (int i = 0; i < contactsList.Count; i++)
                    {
                        emptyNode = contactNode.Clone();
                        emptyNode.SelectSingleNode("my:Name", this.NamespaceManager).SetValue(contactsList.GetKey(i).ToString());
                        emptyNode.SelectSingleNode("my:Phone", this.NamespaceManager).SetValue(contactsList.GetByIndex(i).ToString());
                        contactsGroup.AppendChild(emptyNode);
                    }                  
                }
            }
        }

5.       Add new rule to ContactsField. Use ContactsField is not equal to “Select…” as the condition, Add Action and set ContactsField’s value for NameField.



Add another Action and get value of ‘Phone’ field which value of ‘Name’ field equals to selected value of ‘ContactsField’ field, set it as value of ‘PhoneField’ field.


6.       Now you can publish the form to a SharePoint server or just debug the solution. J

2 comments: