Mobile LOB webpart pages in Sharepoint

One of the things Microsoft never quit has got its grip about is the support for mobile devices in Sharepoint, I know that it’s possible to get mobile views of lists and navigation by appending an m to the url like this http://servername/m what this does is simply redirecting you to /_layouts/mobile/mbllists.aspx page, one thing comes to mind here is that you are redirected to the _layouts folder which indicates this is an application, the pages are of the SPMobilePage type which inherits System.Web.UI.MobileControls.MobilePage that inherits the normal Page class like a normal LayoutsPageBase does via UnsecuredLayoutsPageBase.

But what’s the problem?

The problem as I see it are that you do not have a way of extending the pages with webparts if you need it, and on the other hand if you create a normal web part page and saves it to a page library the total page size will be very large and prevent the mobile device performing at a acceptable pace.

This is caused by Sharepoint, because it injects links to external js and css files that the device must load. I was recently hired as a consultant where the customer used Sharepoint and integrated with DynamicsAX.

Dynamics comes with a lot of webparts that was required to run on a Motorola hand terminal, which was used to scan barcodes. The problem was that the total page size was so large that the terminal was slowed down; the users didn’t need any special rights on the portal so Site Actions was not shown, and the need for the webpart menu wasn’t needed either.

But whenever Sharepoint sees a webpart it automatically loads core.css, init.js, ie55up.js (depending on browser) and core.js.

The challenge

We need to be able to select what the page returns depending on what you want to do. E.g. editing a page or using it from a hand terminal. So we need a way to control the output from Sharepoint without scarifying the functionality of the page. The goal was that an entire page must not exceed 10kb.

The measurements

I created a new master page based on the default.master called mobile.master, and a new page for testing purposes called mobilepage.aspx.

I used Fiddler2 to measure the payload of the page the result was as follows:

Even with everything removed from the Mobilepage.aspx and the masterpage we still have a payload of approx. 150KB that’s about 15 times more than acceptable also the chart says it all, about 80% is javascript, which is totally unnecessary in this scenario, in this demo the only thing want to show is this:

 

Naturally a more rich webpart will be used in a real world scenario.

Request filters and httpmodule to the rescue

After trying a few different approaches, one of them was to insert <Sharepoint:ScriptLink runat=”server”/> web control into the masterpage. That solved some of the issues concerning the core.js, but that’s only 70KB of the 140KB needed. I was still stuck with a lot of javascript.

Step 1 Create a httpmodule in C#

To do that two things have to be done first create a class that implements the IHttpModule interface and update web.config in the <httpModules> section      

<add name="MobileModule" type="Minimum_Payload.HttpFilter, Minimum Payload, Version=1.0.0.0, Culture=neutral, PublicKeyToken=c23d6c989c59848d" />               

namespace Minimum_Payload
{
 
public class HttpFilter :IHttpModule   
 
{

    #region IHttpModule Members        
     
public void Dispose()       
     
{}
      HttpApplication _context = null;       
     
public void Init(HttpApplication context)       
     
{
           
       
_context = context;
           
       
context.ReleaseRequestState += new EventHandler(context_ReleaseRequestState);       
     
}
      void context_ReleaseRequestState(object sender, EventArgs e)        
      
{
        if (string.IsNullOrEmpty(_context.Request.QueryString["mobile"])) return;            
       
_context.Context.Response.Filter = new MobileFilter(_context.Context.Response.Filter);
       
     
}
                     
   
#endregion
   
  
}
} 

One of the requirements was the ability to control whether it was a normal browser or a mobile device, for this demo I choose the querystring.

Step 2 Create the Filter

I used this post as inspiration from 4guysfromrolla

public class MobileFilter : MemoryStream   
{
        Stream _output = null;
        public MobileFilter(Stream output)
        {
            _output = output;
        }

        public override void Write(byte[] buffer, int offset, int count)
        {
            string page = UTF8Encoding.UTF8.GetString(buffer);
            if(page.ToLower().Contains("<script>"))
            {
                int indexOfScript = page.IndexOf("<script>") + 8;
                int indexOfLastScript = page.IndexOf("</script><SCRIPT LANGUAGE='JavaScript' >");
                page = page.Remove(indexOfScript, indexOfLastScript - indexOfScript);
            }
            if (page.ToLower().Contains("</title>"))
            {
                int indexOfTitle = page.IndexOf("</title>");
                int indexOfLastTitle = page.IndexOf("<title>",indexOfTitle);
                page = page.Remove(indexOfTitle, indexOfLastTitle - indexOfTitle);
            }
            _output.Write(UTF8Encoding.UTF8.GetBytes(page), offset, UTF8Encoding.UTF8.GetByteCount(page));
         }
    }

This filter is very simple and I won't recommend that you use it in a production environment, but as an example it works well. The result of the payload of the page are shown here

smallpayload

Conclusion

It is possible to reduce the payload of the page and truly enable mobile devices using webparts. However I do not think that this scenario are supported by Microsoft and I also think that you should take great care in when using custom httphandlers in Sharepoint. Mainly because all request will pass through it, and this could degrade performance.

Source code

Minimum Payload.rar (8,62 kb)

Modifying Quick launch bar with JQuery

The Quick launch bar 

Many people are annoyed with the Quick Launchbar, because it quickly gets very large; I'm going to show how this can be solved with JQuery. I was inspired by a post made by Jan Tielens, you can read more about it here. I'm not going to claim to be any kind of expert with regards to JQuery so it's a learning experience for me too.

But what is wrong?

   

Well, there's nothing wrong with it by default, but it really takes up a lot of space and you need to scroll down the page just to see all the links, like this screenshot, not that many lists but a lot of space taken up. I know it's possible to remove the lists from the quick launch bar but then you need mere clicks to get the information.

It's obvious that this needs to be fixed.

JQuery

Unfortunately all the items in the quick launch are all using the same CSS classes so I haven't been able to find a way (yet) to select the individual sections. So this will only work on all the sub items. Insert this code into a Content Editor Webpart:

<style type="text/css">
   .myRowHighlight {color:red; background-color:#FFCC66}
</style>

<script>
$(document).ready(function()
 {
       $("table[class='ms-navSubMenu2 zz2_QuickLaunchMenu_8']").hide("slow");
       $("table[class='ms-navheader zz2_QuickLaunchMenu_4']").hover
        (
            function() {
                $("table[class='ms-navSubMenu2 zz2_QuickLaunchMenu_8']").show("slow");
            }
        );

       $("#OuterLeftCell").hover
        (
             function() {
                 $("table[class='ms-navSubMenu2 zz2_QuickLaunchMenu_8']").hide("slow"); 
             }
        );
 }
);

</script>

I have tested this in IE8 in normal and compatibility mode, Firefox, Opera and Safari and it looks fine in every one of them.

Update Update I managed to find someone that made a better implementation where the individual sections are expaneded check out this great post http://www.endusersharepoint.com/?p=985

About the author

Jesper is a serlfemployed IT-consultant and owner of Nsight ApS.

His primary focus is on SharePoint and Microsoft online services like Azure and Office 365

Month List

Page List