Creating Knockout User Experiences in SharePoint with JavaScript and REST services

 

Sydney SharePoint user group is 21st of February.  Where I'll be presenting Knockout, AJAX and REST services.

 

To many of us web/SharePoint developers, discovering jQuery made us love JavaScript again. Finally, here was a JavaScript library that made sense. It made everything a thousand times easier. Within years, jQuery had become the ubiquitous hammer in everyone's tool belt.

On the server side, SharePoint shipped with a complex Client Object model, REST services, and it is incredibly easy and flexible to build your own web services and use them in your solutions.  Even for SharePoint 2007, SPServices has made huge improvements in bridging how you can talk to the server.

There is one final piece of the puzzle: how do we easily fit data that we've obtained from the server back into the web UI seamlessly? What if there's a way to do data binding, MVC/MVVM style, and leave both the object and the UI robust and free of spaghetti code?

Knockout solves one of the most difficult remaining problem in creating complex business solutions entirely using JavaScript.  If you thought jQuery alone is awesome.  Discovering Knockout is like finding another beautiful library like jQuery all over again!

In this session, John will demonstrate how to build a fairly complex system using Knockout and jQuery.  As well as show examples of some of the systems that he's been building and the flexibility you can easily achieve with Knockout.

So bring your developer hats and be prepared to enjoy an evening of new exciting techniques!  Don't be afraid to ask questions too!

Teaser Picture

image

Figure: this is your SharePoint task list, but supporting drag and drop!

 

See you at the Sydney SharePoint user group.

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.