InfoPath how to copy a repeating section using rules

For years, we all thought this was impossible.  You had to use code.  I somehow woke up with an idea on how to do this, and set about testing and to my surprise, found a solution.  Here it is!

 

The form set up

image

  • Two repeating sections, Foo's and Bar's
  • One additional integer field i to control which row to copy

Put the elements on the form:

image

 

 

The copy rule

Create a rule on the integer field i

  1. We will use the normal action, then tweak it. 
    Give this rule the name "Copy"
    Start by defining a set field value rule.
    image
  2. Set /my:myFields/my:Foos/my:Foo/my:F1 to /my:myFields/my:Bars/my:Bar/my:B1
    image

    There are a few issues so far with the default Set Field Value action related to a repeating section.
    • For the Field (target), it will set ALL the matching nodes.
    • For the Value, it will get the First matching node.
  3. Let's fix the second value - we can do this in InfoPath designer.
    image

    The expression is:
    ../my:Bars/my:Bar[number(../../my:i)]/my:B1

    This expression lets us copy a different row.

    image

    So we can now copy value from any row - depending on what the number i is.
  4. To fix the Field Target is a bit more difficult.  InfoPath designer doesn't give us a way to modify the XPath of the field.

  5. Save the form.  We're about to do unsupported stuff. 
  6. Publish the form to Source Files. 
    image

    I publish to C:\Temp\CopyForm\
  7. Close InfoPath designer.  Open the file C:\Temp\CopyForm\manifest.xsf file using NotePad or your favourite XML editor.
  8. The "Copy" rule is hiding in this XML file, it looks like this:
  9. <xsf:rule caption="Copy">
        <xsf:assignmentAction targetField="../my:Foos/my:Foo/my:F1" expression="../my:Bars/my:Bar[number(../../my:i)]/my:B1"></xsf:assignmentAction>
    </xsf:rule>

  10. Change it to:
  11. <xsf:rule caption="Copy">
    <xsf:assignmentAction targetField="../my:Foos/my:Foo[number(../../my:i)]/my:F1" expression="../my:Bars/my:Bar[number(../../my:i)]/my:B1"></xsf:assignmentAction>
    </xsf:rule>
  12. Save, and close Notepad.  Re-open manifest.xsf file using InfoPath Designer
  13. Let's check our rule.
    image
  14. Are you thinking what I'm thinking?  We're nearly there.

The loop

  1. This rule is set on the number i, and runs once whenever the number i changes.
  2. Lets set it up to increment.
    image
  3. Add a condition to stop incrementing when we've run out of rows
    image

    image
  4. And to start the whole thing, remember we have a button.

    image

    To start the process, set i to 1.  XML index starts from 1 to n.  Does not start at 0.

 

Result - InfoPath Filler


image
Starting...

image

Press "Copy"

Result - Form Server:

image

Starting Browser Form

image

Copy.

 

Note - InfoPath "Infinite Loop" limitation:

InfoPath is hard coded to only execute 16 rules before throwing the "Infinite Loop" error.

image

An error occurred in the form's rules or code. The number of rule actions or the number of calls to the OnAfterChange event for a single update in the data exceeded the maximum limit.

The rules or code may be causing an infinite loop. To prevent this, ensure that the rule action or event handler does not update the data which causes the same rule action or event handler to execute.

 

There is no solution for hard coded 16 rules.  So your i can not go over 16.

Download

Pretty up SharePoint 2010 mysite with showModalDialog (updated)

[This is an updated article from /blog/2011/8/3/sp2010-pretty-up-mysite-with-showmodaldialog.html.]

 

SharePoint 2010 My Site

SharePoint 2010 ships with this pretty mysite.  Packed with numerous features.

image

 

The problem with My Site, even back in the days of SharePoint 2007, is that your users get lost.  It doesn’t look anything like your nice branded site.  It doesn’t share the same global navigation.  In fact, users are so lost that they think they are in a place that they shouldn’t be in.

Result?  They close the browser.  Sometimes, if they are nasty, they tell their colleagues that the Intranet sucks - they can never find anything. 

 

If only we can render our mysite in a SharePoint 2010 showModalDialog, then it would look like this:

My Site in a modal dialog

image

 

Some of the immediate benefits:

  • My Site remains totally un-branded, but now it is just demoted to an utility page.  That is, you keep the functionality without having to invest in how to make My Site look nice.
  • Users are familiar with the SharePoint modal dialog, and can easily close My Site via the top right close buttons.
  • Users don’t feel like they’ve left the site, because they can clearly see the previous page right beneath them.

 

Using modal dialog for user information

Even if you aren't using My Site, you can still use this for links on the page that would lead you to a user's information page.  Here's an example:

image

 

You click the user name, you are sent to the User Information page - completely losing your previous page.

image

Figure: EEk!  Where the heck am I?

We add this bit of jQuery

$(function(){
    $("a[href*='userdisp']").click(function(e){
        SP.UI.ModalDialog.showModalDialog({
             url: $(this).attr("href"),
             autoSize: true
        });     
        e.preventDefault();
    }).attr("onclick","");
});

This hooks into any <a> anchors on the page, whose href contains the word "userdisp".  And then override the onclick attribute to empty.  It also attaches a new click event handler, sending the click to a show modal dialog.  Lastly, it prevents default - so the default action from the click is swallowed.

Result - User Information in a pop up:

image

Figure: Now isn't this far more useful?!

 

Changing My Site

We have these two links that sends our users into Alice's Wonderland.

image

 

They both use a SharePoint JavaScript function STSNavigate2

We can override the JavaScript this way:

I did a simple prototype by overriding a SharePoint javascript function:

 

$(function(){
    // store a reference to the STSNavigate2 function
    window.oldSTSNavigate2 = window.STSNavigate2;
    window.STSNavigate2 = function (evt, Url){
        if (Url.indexOf("mysite") != -1) {
            // if the url contains mysite - open it in showModalDialog
            SP.UI.ModalDialog.showModalDialog({
                url: Url + "#",
                title: "My Site",
                autoSize: true
            });
            return;
        }
        // otherwise call the old version of STSNavigate2
        window.oldSTSNavigate2(evt, Url);
    };
});

 

Result - My Site in a pop up:

image

 

Notes - some odd CSS issues:

When a page is rendered in the modal dialog, SharePoint will automatically insert &IsDlg=1 to the argument.

My Site doesn't appear to have been exhaustively tested with IsDlg - and there are odd CSS issues that does appear.  Depending on the features that you plan to activate on your My Site, you may still need to invest in a small bit of CSS work to make sure nothing strange appears when My Site is shown in a Pop Up.

Still, I argue that the small CSS fixes are a lot less work than completely rebranding your My Site.

In general though, majority of the functionality are available without further modification and this is a good way to quickly test if this could work for you and your organisation.  Do let me know how this works for you!

SharePoint - JavaScript current page context info

Quick blog. On every SharePoint page there's a javascript context variable:

 _spPageContextInfo 
{
webServerRelativeUrl : "/ProjectWeb",
webLanguage : 1033,
currentLanguage : 1033,
webUIVersion : 4,
pageListId : "{c1d7b89f-f07b-4e2e-b89c-76c315831d59}",
pageItemId : 5,
userId : 68,
alertsEnabled : true,
siteServerRelativeUrl : "/",
allowSilverlightPrompt : "True"
}
So if you are on /ProjectWeb/Pages/default.aspx
_spPageContextInfo.pageListId;   // list guid for Pages
_spPageContextInfo.pageItemId; // ID for listitem

 

Special Note

siteServerRelativeUrl will tell you if your site collection is sitting at the root level, or mapped further down.  Fairly useful information for all sorts of mischief.

No idea why alertsEnabled is a useful information.

 

An Example

Say if you want to show the versions page:

var options = {
tite: "Version History",
url: _spPageContextInfo.webServerRelativeUrl + "/_layouts/Versions.aspx?list="+ _spPageContextInfo.pageListId +"&ID="+ _spPageContextInfo.pageItemId,
width: 800,
height: 500,
};
SP.UI.ModalDialog.showModalDialog(options);

 

This will get you the Version History page in a modal popup, without running any additional client context async query.

image

Figure: Version History showing in a modal popup.

Australian SharePoint Conference 2012, March 20-21, Melbourne

2012 will be the third Australian SharePoint Conference [agenda], and my third time speaking at this fantastic event. In my opinion, the AUSPC conference has some of the world's best speakers (and I gladly exclude myself from that list), exceeding even the Australian Tech-Ed event in terms of breadth and depths of SharePoint content. There are simply no other event this dedicated to SharePoint within Australia.

In the year 2011 we saw tremendous growth in SharePoint, and new techniques with jQuery becoming very popular.

Silverlight is now moving towards a backseat, to my dismay - I argue that it remains a very useful arsenal in providing the tools to extend SharePoint's capabilities, but with the advances in HTML5 and the myriad of devices that our users are now plugging to SharePoint, a different future is fast approaching, and it doesn't look that great for Silverlight.

In the new year 2012, I think there will be stronger focus in using HTML5 and JavaScript going forward, with may be a good sprinkle of Metro, pending Windows 8's release.

I will be presenting an updated version of my talk "Building your own Custom REST services and consuming them with jQuery AJAX". Time permitting, I want to add a tiny section on KnockoutJS. Aside from future SharePoint Saturday events, I'll be posting the entire REST services talk in a series of blog posts in the upcoming months.

Also, consider the sad cancellation of January's Sydney SharePoint User Group, I hope to be able to present a talk on KnockoutJS in a Developer session as early as February, fingers crossed. A previous version of my talk on REST services is still here.

If you thought you've seen everything there is to know about SharePoint, hold on to your seatbelts, because you are about to be blown away! See you soon around Australia, our first stop, in the Australian SharePoint Conference, March 20-21.

InfoPath - LoadDocumentAndPlayEventLog NullReferenceException

Error:

LoadDocumentAndPlayEventLog failed with unhandled exception System.NullReferenceException: Object reference not set to an instance of an object.     at Microsoft.Office.InfoPath.Server.Converter.DetectUnsupportedNamespaces.VerifyNamespace

This is a very uncommon bug.  Essentially, you are using custom code in InfoPath, and you are using code that doesn't have a namespace.  Say a helper function that you've included in your code.

When InfoPath Forms Services attempt to validate your form, it finds that your form template contains reference to code that doesn't have a namespace!

The fix is simple, create a namespace for the helper class, or move the helper class under the namespace of the form's namespace.