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.

SharePoint - here is a REST service Project Item template

UPDATE:

There seems to be an issue when loading this template in VS.NET - sometimes there's an error that prevents the rest of CKSDEV from working correctly.  If you are unable to retract or deploy via CKSDEV after this template was included, please remove this template and restart VS.NET

 

CKSDEV provides a wonderful WCF template.  The main magic of this template is that it uses SharePoint 2010's MultipleBaseAddressBasicHttpBindingServiceHostFactory to create a service host and hook up all the configuration settings.  This is done by the hardwork Charlie Holland and described here http://www.chaholl.com/archive/2010/03/10/how-deploy-a-wcf-service-to-sharepoint-2010.aspx

I've been presenting a talk where you can start with the WCF template, then change the factory to MultipleBaseAddressWebServiceHostFactory and switch the service to a REST service.

 

Finally, I sat down and created a Project Item template for SharePoint.  With examples on how to create both a GET and a POST method in REST service.

 

Download:

 

Install:

  • You may need to unblock this file if you download it from IE
  • Copy the file to \Documents\Visual Studio 2010\Templates\ItemTemplates\Rest.zip
  • Close / Restart VS.NET

 

Use:

  1. Create a blank SharePoint Farm solution.  Services can't be deployed as Sandbox.
    image
    Figure: Create a SharePoint Farm solution. 
  2. Add new Project Item, the template does NOT appear under the SharePoint group currently.  So you'll need to search for it.  Will be fixed... "Soon".  Give it a nice name.
    image
    Figure: Search for the template and use it to create a REST service
  3. These files are created:
    image
    Figure: My RestService1

  4. The IRestService1.cs interface gives you the definition of your REST service methods.  I've provided a GET and a POST operation.
    image
    Figure: GET, and POST
  5. You should also add a CKS WCF Service
    image
  6. The solution should look like this:
    image
    Figure: OK, we have a REST service and a WCF SOAP service.

    Important.  CKSDEV's WCF Template hooks up token replacement for the *.svc file.  You need to add this, even if you don't use it, otherwise you'll need to modify your VS.NET project file manually.  You can remove this service after you've added it once. 

    I recommend you compare the difference between the CKSDEV WCF SOAP service and the REST Service.
  7. Deploy! 
    image
    Figure: I LOVE Deploy from VS.NET 2010
  8. Open a browser, go to:
    http://server/_vti_bin/SharePointProject1/RestService1.svc/GetItem/1

    You should get:
    image

  9. The returned content type is unrecognized by Internet Explorer, so it's prompting you to save it.
    Save this, and open it in notepad.
    image
    Figure: Haha!  JSON'ed HelloWorld Blob object returned from the server!

  10. In IE Developer Toolbar, you can watch the network traffic
    This particular request took 31ms and sent 463 bytes!
    image
    Figure: Extremely fast and efficient way to talk to SharePoint.

 

 

If you see this error:


Error

The type 'SharePointProject1.RestService1, $SharePoint.Project.AssemblyFullName$', provided as the Service attribute value in the ServiceHost directive could not be found.


This is because VS.NET does not perform Token Replacement for the *.svc file by default.  There are a few ways to fix this.

  1. The simplest way is to add a CKSDEV WCF Service Project Item.  You can remove it afterwards.
  2. Alternatively, you can edit your project file, you need to find this, and add svc;
    image

    Reload your project
    image

 

Minor issues need fix... one day:

Minor Problems:

  1. Project Item doesn't appear under SharePoint Group
    To properly create SharePoint Project Items, I need to define a proper .spdata file - this requires an additional project to declare a new SharePoint Project Item type. 
    This will also allow me to specify an ICON to use in the solution, instead of this silly red image looking icon.
  2. Not properly set up TokenReplacementFileExtension
    The project will also allow me to hook into the project item wizard and link up TokenReplacementFileExtension for svc.
  3. Need custom code...
    Custom code requires signed assemblies. Annoying.
  4. Or, preferably, I clean up the template a bit more and submit it to CKSDEV, which has most of these facilities already built in.