June 2012 - Posts - Hilary Stoupa
in

InfoPath Dev

Hilary Stoupa

June 2012 - Posts

  • qRules SubmitToSharePointList - Walkthrough for v4.2 - Working With Existing Data & Submitting a Single Mapping

    With qRules 4.2, we've introduced a major improvement to the SubmitToSharePointList command - especially if you have been submitting to multiple lists. The first walkthrough can be found here, and then in this post, we talked about how to save attachments with our list items. Picking up where the second post left off, we are now going to modify our form to submit to one of the individual lists we've mapped. Thus far, we've only submitted to all the lists. Also, because I am frightfully lazy, we are going to start pulling some existing data into our form so we can edit it and update our existing customers.

    We'll start with the same template we have been using for the previous two walkthroughs - mine is available here, if you'd like it. Keep in mind that my form & mapping is pointed to sites in my environment, so you'll need to modify that, and it is using the current 4.2 trial version of qRules - which expires 9/15/2012. So, you'll want to re-inject with a new trial if you are following this at a later date.

    Data Connections

    First, we need to add 2 data connections to our form - one that we'll use for a customer drop down, and the other that we'll use to return all the data for a given customer. The first one, which I'll call the CustomerNumber data connection, is to the Customer list, and returns these columns:

    I sorted by Company Name to make the drop down I'll use this data for less annoying.

    Return data on load for this connection only:

    Now, create another data connection to the Customers list:

    Select at least all of the columns that the form is mapped to submit data to. This time, deselect the checkbox to query data on load:

    Form Changes

    In my form, I've decided to let the user choose an existing customer or just fill in the fields if they want to create a new customer. I've added a drop down that is bound to the /my:myFields/my:Customer/my:ShpId field - you may recall from the earlier walkthough that when mapping, we can indicate a form field that will hold the SharePoint List item ID after a successful submit- we are going to leverage this field to allow our users to open a new form and edit existing customers.

    Set the drop down to use the CustomerNumbers data source, with the ID for the value and the Company Name for the display:

    Here's my form up to this point, in case I've lost anyone.

    After the user selects the Customer, we'll need to query the Customers data source for that customer's data and then populate the main data source nodes with those values - this can be done with ordinary InfoPath rules. While this could be done with rules set on the ShPId field the drop down is bound to, that would make things slightly more complex for us - we'd need to make sure these rules don't run when qRules is populating that field. So, for the purposes of this walkthrough, I'm going to add a button and put these rules on the button. However, you have other options - like:

    • Bind the drop down to another field, and execute the rules from that field - be sure you also set the form field for the ID if you take this approach
    • Have a helper field in a 2ds that set when the form is about to execute the SubmitToSharePointList command, and base conditions off the value of that field to prevent execution of rules when qRules sets the ID field for a new item

    For my form - I'm going with a button.

    My first rule action sets the Customers query ID field:

    To the value of the /my:myFields/my:Customer/my:ShpId field:

    Then, I execute the Customers query:

    Now, since the user selected the ID of the customer she wants, I could have returned all the customer data and used filtered XPath to get the values I want - and if you are using SharePoint & InfoPath 2007, this would be the approach you would probably take (or use the qRules FilterOwssvr command to get back just the single record you need). Since I only will have one record in my Customers data source, I don't have to use filtered XPath to populate my other form values. That makes me happy.

    In the rules above, I am setting main data source Customer group nodes to values from my Customers list.

    Preview

    Time to check our work - preview the form, and select a customer from the drop down - does all the customer's information get populated correctly?

    If not, check and make sure you are returning data to your Customers data source - and here's my form in progress, in case you need to take a look at it.

    Submit a Single Mapping

    Now that we have added the logic to pull an existing customer into the form, we can add a button to save just the user's Customer changes. The big trick here is making sure that in the mapping we have identified a field to use for the ID:

    And making sure we have in our form set that field to the SharePoint List item ID that we wish to update - in my form, I've done this by binding a drop down to the field ( /my:myFields/my:Customer/my:ShpId) and then using a data connection to my target list for the values - so that the user will be picking a valid item ID from the drop down.

    Our original submit command was:
    SubmitToSharePointList /submit=ShPList

    We then added to it for adding attachments in the last walkthrough. I'm not going to be adding attachments here, just editing my existing customer - so I only need to add the mappingName parameter to indicate which mapping I want to submit:
    SubmitToSharePointList /submit=ShPList /mappingName=Customers

    I'm going to add a region to this customer, since it was missing when I pulled his information into my form:

    After clicking my button with the qRules command on it, I can see the region has been added to the customer:

    If you would like to verify that only the Customer is submitted, add an Order and use the command that submits only the Customer data - you'll find the Customer is added / updated and the order is not. If you need my final form, here it is.

    ***********************

    There you have it - you can make this more interesting by allowing the user to copy in Orders or Order Details - using CopyTable or Insert - so those could be updated. Of course, you'd probably be submitting the XML to a form library in a real form - so you would open the form to update the order.

    But what if someone changed the list item? What if you want your users to be able to edit from the form or the list, and you want to keep them in sync? Stay tuned - next up is a walkthrough on the RefreshSharePointListItems command!

    ***********************

    SubmitToSharePointList Walkthrough
    Working with Attachments
    RefreshSharePointListItems

  • qRules SubmitToSharePointList - Walkthrough for v4.2 - Working With Attachments

    In the previous walkthrough for the SubmitToSharePointList changes, we submitted data to three lists, all with a single mapping, a single submit connection, and the new, much simplified command syntax. If you didn't hang onto your form template from last time - here's one that you can start with - mind you, the form is pointed to my development SharePoint sites, so just about everything will need to be repointed to your environment, but at least you won't have to start all over. Also, this form is injected with a qRules trial - so if you download it after 9/15/2012, you'll want to re-inject it to enable qRules again.

    Form Changes

    First, we will need to add a field to our form data source for attachments. I think I'm going to add that to my Customer - it seems like I may want to attach a filled out credit application, or some other file related to the customer:

    I've set the field to be repeating, since I want the user to be able to add multiple files.

    Now, I have a decision to make. There are two options when adding attachments to my list item - I can keep the file in my form XML and add it to the list item in SharePoint or I can simply upload the file to my list item and remove it from the XML. Since I don't want to keep the file in two places, I'm going to take the second option - I want qRules to remove the file from my form after saving it to my list item.

    To do that, all I have to do is add two attributes to my attachment node - qRulesLink and qRulesFilename:

    The presence of these attributes on the attachment node indicates to qRules that you want to have the file removed after it has been uploaded (like the functionality of the SaveToSharePoint command, only for a list instead of a library).

    Mapping Changes

    Next, we need to modify our list mapping file to indicate that we have an attachment field. Now, if you have worked with the SubmitToSharePointList command before, you may have had to re-do your mapping each time you wanted to make a change. We've improved that experience in qRules 4.2 - we can now import our mapping into the mapping form.

    So, first save your changes to your form template. Then, from the Data tab of the Ribbon, select Resource Files:

    From the Resource Files dialog, click on your mapping.xml file:

    And click the Export button to save the file.

    Open the mapping tool from the Start menu:

    Select the Define Mapping tab. There is a button toward the bottom - Import Existing qRules Mapping - click that:

    You'll get a warning about the form deleting existing mappings, which you can click OK on, and then select the mapping file you just exported from your form. Your existing mapping will be imported - all that remains is to attach your template to the Source XSN field - much better than remapping every time, don't you think?

    In the mapping to the Customers list, select Add mapping:


    Select the new Files node that was added earlier for the Form Field and click the Show button in the Options column:

    Select the Attachment checkbox for the Files node mapping:

    And click the Save as qRules Mapping button at the bottom of the form to save the mapping.xml. If you maintain the same name as the original file you exported, you can simply re-add the file as a resource file - no need to walk through the data connection wizard again. From the Data tab of the Ribbon, select Resource Files again to open the Resource Files dialog. Click Add and navigate to the mapping file you just saved. InfoPath will prompt you:

    You want to replace the existing file, so leave the default selection and click OK. You shouldn't have to modify your mapping data connection - the schema of the XML file will not have changed at all, simply the data. As an aside, you can always verify what file is used by your data connection in the Data Connection dialog:

    Add a Data Connection 

    We need to add a Receive data connection to the AddAttachment method of the SharePoint Lists web service. On the Data tab of the Ribbon, select From Web Service --> From SOAP Web Service:

    The URL for the Lists web service is: http://YourServer/_vti_bin/lists.asmx - replace "YourServer" with your actual server name. If in doubt, test your URL in a browser, making sure you get a page that looks like this:

    After entering the URL in the Data Connection Wizard, click Next and select the AddAttachment method:

    Click Next - no need to set any of the query parameters, so click Next again, then one more time - in the final screen of the dialog, deselect the "Automatically retrieve data when form is opened" checkbox and leave the default name for the data connection - you can name it something else if you like, but keep track of the name, because we will need it when we modify our command.

    Add Controls to the Form 

    Add controls to your form to allow the selection of files. I like to add a file picker and a hyperlink, with the file picker inside a section, and set to hide if the qRulesLink attribute is not blank. Here's a copy of my work in progress, if you'd like to check it out. For the hyperlink, I am using the qRulesLink attribute for the link, and the qRulesFilename attribute for the display:

    Modify the Command

    In the first walkthrough, we added a submit button to our form with the qRules command:
    SubmitToSharePointList /submit=ShPList

    Now, we need to modify this command to include our attachment files when we submit to the Customer list:
    SubmitToSharePointList /submit=ShPList /dsname=AddAttachment

    If you named your AddAttachment data connection something different, you need to modify the command above to use the name of your data connection:
    SubmitToSharePointList /submit=ShPList /dsname=MySuperSpecialAttachmentDataConnection

    Remember, case cOunTs - you need to use the exact same spelling and casing.

    Test the Form

    As always, be sure you have the QdabraRules Error node somewhere you can see it prior to testing. Preview your form, add a new customer, and add some files for the customer. Click the Submit button:

    If everything is set up correctly, you'll now have links in your form instead of files - and in your list item:

    You will have attachments.

    Extra - Add Delete Logic!

    So - this is all well and good. Provided your users never ever make mistakes.

    But every now and again, someone may attach and save the wrong file. It would certainly be nice to allow the user to delete the file from the form, wouldn't it?

    No qRules required for this - just add another data connection to the DeleteAttachment method of the SharePoint Lists web service - exactly the same way as you added the AddAttachment method above:

    Don't bother filling out any of the query parameters, and deselect the option to automatically execute the data connection on load (just like we did for the AddAttachment data connection).

    Add a button to your form next to your hyperlink control:

    Add a conditional formatting rule to the button to hide it if the qRulesLink attribute is blank:

    Add an action rule to the button. There are three fields we need to set in the DeleteAttachment data source queryFields:

    I like to get the listName from the mapping file. MSDN states that the listName parameter can be the list GUID or name. We have the GUID in our mapping file - it is in the Customers mapping:

    So, I'll set that field to the ListCollection node in my mapping file where the mappingName is equal to Customers:

    Next, I set the listItemID parameter to the field I am storing my SharePoint item ID in - in this case, that would be /my:myFields/my:Customer/my:ShpId:

    Then I set the url parameter to the qRulesLink attribute:

    Don't forget, we need to actually execute the query (I always forget that rule action, leaving myself perplexed when my what-ever-it-is doesn't work):

    In a perfect world, our web service method would return some useful information to us - sadly, it doesn't (or at least not anything that InfoPath is going to tell us about). If the query fails, any rule actions after it won't run, so I generally work on the assumption that if my query succeeds, my attachment will have been deleted, and add two more rule actions to clear out the qRulesLink and qRulesFilename attributes.

    However, you do have some options for error handling.

    1. Use the qRules QueryData command to execute the DeleteAttachment query - it will handle any errors and return them to the QdabraRules QueryDataError node - you could then add some conditions around clearing the qRulesLink and qRulesFilename attributes
    2. Or, after executing the data connection, you could query the GetAttachmentCollection method of the Lists web service - check the value of the /dfs:myFields/dfs:dataFields/tns:GetAttachmentCollectionResponse/tns:GetAttachmentCollectionResult and see if it contains the value of the qRulesLink attribute 

    My final ruleset looks like this:

    I've simply chosen to let InfoPath return a query error in this case - and I added a condition to only run if the SharePoint ID field is populated.

    ***********************

    So, now our form submits to three related SharePoint lists. It can include attachments. The user can delete attachments. Here's the final form, in case you want to take a look at any of the logic. Next up - submitting just specific mappings. Hang onto your form and your test site!

    ***********************

    SubmitToSharePointList Walkthrough
    Submitting a Single Mapping / Updating Existing Data
    RefreshSharePointListItems

  • qRules 4.2 and useBrowserApi node

    We are getting ever closer to releasing qRules 4.2 and I wanted to post briefly on a new node we've added to the QdabraRules data source - it is called useBrowserApi and has a default value of "false".

    Here's what it does and why it is there:

    With qRules 4.1, we modified a lot of the SharePoint related commands to use the SharePoint object model instead of web services if the form was opened in the browser. We added a node called useWebServices, just in case this change affected any forms upgraded from earlier versions of qRules. But the other day, we suddenly saw an issue where sometimes qRules was not correctly switching between the SharePoint object model code and the web service code, and this caused some issues in our Office 365 forms (which can't fall back on using web services).

    That code has been addressed in 4.2 and we are now unable to reproduce the issue in our environments, however, it made sense to give form designers a way to switch this off and indicate that they would like to always use the SharePoint DLLs

    Now, if you ever have issues with a form failing in the browser because it is not using the SharePoint object model, you can set useBrowserApi to true in order to make the form always use the SharePoint object model based code.

    The logic, then, as of qRules 4.2, is as follows:

    1. If the useBrowserApi node in qRules data source = true, we use the SharePoint DLLs.
    2. If not 1, and if Application.Environment.IsBrowser = true or Application.Environment.IsMobile = true, we check to see if the useWebServices node in the qRules data source is true:
      • If useWebServices = true, we do NOT use SharePoint DLLs
      • If useWebServices = false, we DO use SharePoint DLLs
    3. If not 1, and if not 2, we do NOT use SharePoint DLLs

    If useBrowserApi is set to true, the SharePoint commands like SubmitToSharePoint will fail in Filler and in Preview - unless the form is opened on a machine with SharePoint installed, of course.

Copyright © 2003-2019 Qdabra Software. All rights reserved.
View our Terms of Use.