1
votes

I have an Infopath 2010 template with 2 buttons: submit and cancel. When the submit button is clicked I the form is saved to a document library in SharePoint 2010 and the corresponding workflow is clicked off. The user can then open the form and cancel the request by clicking on cancel. I would like to start a different workflow when cancel is clicked. Any ideas as to how that could be done?

Thanks

2

2 Answers

1
votes

I have not found a method to kick off a workflow specifically from an Infopath form. I did however find a workaround; here's how I set it up:

  1. Added a column to my list/library that will be set to true when the cancel button is selected.
  2. In my infopath form, add my "cancel" button.
  3. Open the control properties for the button, and select the "Rules" action. Close out of the properties dialog.
  4. I added a fomatting rule for the cancel button so it will only display if the first workflow has started. I also disabled all other editing controls as I only wanted the cancel option to be available.
  5. On the Control Tools contextual tab, in the Button group, click Manage Rules.
  6. Add a new Action rule, it should run two actions: first set the value of the column we created in the first step to true; second submit data using the main data connection.
  7. The workflow you want to run when it is cancelled should be set to run on change. As a first step, evaluate the column created above, and if true, continue the worflow. Make sure you set the value back to false so the workflow doesn't run unintentionally.

Hope that helps.

0
votes

That is not a bad workaround Nostromo but we actually ended up using the out of the box SharePoint web services to start the workflow from InfoPath code behind. Here is the method we developed to do that.

  public static void StartWorkflow(string siteUrl, string docUrl,string workflowName, List<string> approvers,string description)
        {
            var workflow = new Workflow();
            workflow.Url = siteUrl+ "/_vti_bin/workflow.asmx";
            workflow.Credentials = System.Net.CredentialCache.DefaultCredentials;
            XmlNode assocNode = workflow.GetTemplatesForItem(docUrl);
            XmlNamespaceManager nsmgr = new XmlNamespaceManager(assocNode.OwnerDocument.NameTable);
            nsmgr.AddNamespace("wf", "http://schemas.microsoft.com/sharepoint/soap/workflow/");

            XmlDocument doc = new XmlDocument();
            Guid templateID = new Guid();
            bool workflowFound = false;
            XPathNodeIterator rows = assocNode.CreateNavigator().Select("//wf:WorkflowTemplate", nsmgr);
            while (rows.MoveNext())
            {
                if (rows.Current.GetAttribute("Name", "").ToLower() == workflowName.ToLower())
                {
                    doc.LoadXml(rows.Current.SelectSingleNode("wf:AssociationData/wf:string", nsmgr).Value);
                    XPathNavigator idNode = rows.Current.SelectSingleNode("wf:WorkflowTemplateIdSet", nsmgr);
                    templateID = new Guid(idNode.GetAttribute("TemplateId", ""));
                    workflowFound = true;
                    break;
                }
            }

            if(!workflowFound)
                throw new Exception("System couldn't location the workflow with name: " +workflowName);

            XmlElement xmlRoot = doc.DocumentElement;
            nsmgr = new XmlNamespaceManager(assocNode.OwnerDocument.NameTable);
            nsmgr.AddNamespace("my", "http://schemas.microsoft.com/office/infopath/2003/myXSD");
            xmlRoot.SelectSingleNode("/my:myFields/my:Description", nsmgr).InnerText = description;
            XmlNode reviewersNode = xmlRoot.SelectSingleNode("/my:myFields/my:Reviewers", nsmgr);

            reviewersNode.InnerXml = "";

            foreach (var user in approvers)
            {
                XmlNode personNode = reviewersNode.AppendChild(doc.CreateElement("my:Person"));
                XmlNode accountIdNode = personNode.AppendChild(doc.CreateElement("my:AccountId"));
                accountIdNode.InnerText = user;
                XmlNode accountTypeNode = accountIdNode.AppendChild(doc.CreateElement("my:AccountType"));
                accountTypeNode.InnerText = "User";
            }

            XmlNode workflowNode = workflow.StartWorkflow(docUrl, templateID, doc.DocumentElement);


        }