3-step fix Nintex WorkflowDesigner.aspx with your custom system masterpage

Scenario

  • You have created a wonderful, responsive-design, HTML5 MasterPage for your SharePoint 2010.  It works really well. 
  • You even did a variation for the system pages.  Those also work very well.
  • Until you try to use Nintex's Workflow Designer.  That page bombs out.   Most of the panels don't work, the scrollbars don't work.  The hovers go off screen. 
  • Your heart sank.

 

Your choices

  1. Easiest choice, if you don't have time, is to use v4.master for your system pages.  The biggest problem with this choice is the jarring experience your advanced users will get when they inevitably ends up on a system page and suddenly they are dropped into Vanilla SharePoint zone.
  2. Hardest choice, if you do have the time, is to butt your head against Nintex's WorkflowDesigner page until you win.  I have done this twice in the last two years.  In general, if you start with http://startermasterpages.codeplex.com/ you aren't too bad.  You'll need to pull a few ContentPlaceHolder panels out of hiding, and add a few elements with very specific ID's into your current navigation menu. 
    This will take you...  about 2 days. I won't go into the details of what you will face.
  3. Oh, and God have mercy on your soul.
  4. This blog entry is about an Interesting third choice.  You can hack Nintex's WorkflowDesigner.aspx file to use v4.master, while all your existing system pages will continue to use your new custom masterpage.

 

Consequences

  • Nintex's WorkflowDesigner.aspx is an application page that resides in _layouts folder on each Web Front End.  You will need to apply this change across all your WFE manually.
  • When Nintex updates Nintex Workflow, you may need to re-apply this hack.
  • This hack applies to ALL nintext solutions across the entire WFE.  For all  web applications, site collections.

 

How to fix (hack)


Understand the consequences, the hack is actually REALLY simple

  1. Browse to C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\LAYOUTS\NINTEXWORKFLOW\
    Copy this file and make a backup:  WorkflowDesigner.aspx
  2. Open it and find the masterpage reference: 
    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WorkflowDesigner.aspx.cs" Inherits="Nintex.Workflow.ApplicationPages.WorkflowDesigner,Nintex.Workflow.ApplicationPages, Version=1.0.0.0, Culture=neutral, PublicKeyToken=913f6bae0ca5ae12" DynamicMasterPageFile="~masterurl/default.master"  %>
  3. Change DynamicMasterPageFile to MasterPageFile="../v4.master"
    The v4.master sits in \LAYOUTS\v4.master by default making this hack really easy.

 

Result

  • Your custom system masterpage
    image
  • Nintex WorkflowDesigner running on v4
    image

Building SharePoint solutions with Microsoft's TypeScript: why and how

 

I wanted to write up a summary of this presentation that I've had the chance to present at two recent events:  SharePoint Saturday Perth (09/03/2013) and Sydney SharePoint User Group (13/03/2013).

This is a blog post aiming to cover both the feedback I've received, as well as additional notes to the presentation that I may not have covered due to time constraints.

A new and improved version of this entire presentation will be shown at the Australian SharePoint Conference in Sydney, come to my session then!

Introduction

  • To cover why, oh why we need another scripting language.  (~15mins).
  • What is TypeScript
    • TypeScript is free, open source and supported by Microsoft
    • It is based on ECMA4 standards with ECMA6 proposals.
    • Created by the father of C# - Anders Hejlsberg
    • It is a superset of JavaScript
  • Why do we JavaScript+
    • JavaScript: The Good Parts vs. JavaScript: The Definitive Guide
    • History of JavaScript, but now we use it as a programming language for all sort of things.
    • JavaScript is not suited for large applications. 
    • As your JavaScript codebase gets large, it is unwieldy. 
  • JavaScript Problems
    • Untyped variables
      • key: JavaScript is interpreted.  There are no design-time or compile-time assistance to help you point out errors
    • Object-extension based, not class-based inheritance. 
      • Key: although object inheritance is possible, it is too messy, so we learn to live without it. 
      • This means we are back in an age where we don't define contracts for our code, we don't describe the shape or capabilities of our object upfront, we expect it to all just work at runtime.
    • Parameters - not taken seriously
      • Key: they are sort of like guidelines. 
      • Caller can still do whatever they want.  Callee has to be defensive and check everything.
    • Scope - while JavaScript shares a similar syntax to C-based languages, it only doe scope at new function levels.
    • Hoisting
      • Key: an example where JavaScript is so easy to get wrong, with strange weird results.
    • Multiple Files
      • Last problem for today.
      • JavaScript doesn't understand multiple files.  Visual Studio helps with <reference>, but VS.NET doesn't help you check the correctness of your reference code.

 

Let's look at TypeScript

  • To ease audience into TypeScript (switch from thinking mode to demo mode ~1min break/reset)
  • How do you install it?
    • Grab it from http://typescriptlang.org this includes extensions for VS.NET 2012. 
    • You can do it with VS.NET 2010, but there are manual bits involved.  Installer doesn't help you.
  • First glance
    • Key: a TypeScript function is a JavaScript function with more, optional, bits.

 

TypeScript Demo

  • To show simple TypeScript language features (~15min)
  • Function type checking
    • Intellisense
    • Generated code
    • Best way to describe this.  TypeScript is option strict for your JavaScript.
  • Function optional parameters
  • Module
    • Generated code.  Talk about how JavaScript namespace / scope is possible, but very easy to screw up.
  • Interfaces
    • Defines the shape of an object.  TypeScript works with Shapes.
  • Definition files
  • jQuery - jQuery methods are smarter with TypeScript. 
  • SP.UI.ModalDialog.showModalDialog
    • Wrong Url parameter
  • Interfaces are open - so you can extend it
  • Class-based inheritance
    • Generated code.
  • Export keyword

 

New Project - Pinteresp webpart Demo

  • To show a Complex example of TypeScript and debugging.  (~10min)
  • Module with:
    • 2 interfaces, 3 helper functions, 2 classes and a jQuery ready event handler.
    • Create a PictureLibrary object.  Call Load()
    • This populates an Items() array with PictureItem objects.
    • Call Render() to display to screen.
  • Show how to write the Load method.
  • Show SourceMap debugging.

 

Using TypeScript on your existing projects

 

  • Discuss strategies to get TypeScript onto an existing project (~10 min)
  • Get it to work first
    • You don't have to tackle everything at once.  Start with the simple JavaScript file.
    • Copy everything from JS to TS
      The errors that you will see are all related to the fact that TypeScript doesn't know what the objects you are referring to are.
  • Fixing the initial errors
    1. Add References
    2. Improve your Definition files
    3. Specify optional parameters
    4. Some specific issues - the main support forum is http://stackoverflow.com/questions/tagged/typescript, and they are very responsive.  I blog issues I come across along the way.
  • Refactor - now you can finally clean up that old JavaScript code
    • Here are some things you've ALWAYS wanted to do to that nasty script file but were too afraid to break things.
    • Move common functions into a shared Utilities module
      • Write detailed jsdoc comments for the functions you use, and you expect your team to use
    • Use rename to fix up the variable names - John's i, j, k, i1, i2 nastiness.
    • Add more type information to your variable declarations to increase the strictness of your code

 

History of TypeScript

  • Release 0.8 to public in 11/2012
  • 0.8.1 added Source Map debugging
  • 0.8.2 added jsdoc
  • 0.8.3 added more debugging options
  • 0.9 scheduled to deliver generics in JavaScript.  So in my example above, I can use an Array of PictureItem objects, and not just an Array of objects with PictureItem in them.

 

Summary

  • The ideal conclusion I want to get to at this point, is that it should be pretty obvious TypeScript is good for your team and your code.
  • If you plan to read your own significant JavaScript after a 3 month break, you need TypeScript.
  • If you plan to work on JavaScript with a team, you need TypeScript.
  • VS.NET development and debugging experience for JavaScript is not bad, but with TypeScript it is awesome.  You need TypeScript.

 

The Short Summary

 

Questions and Comments

  • CoffeeScript / Dart comparison
    • CoffeeScript is more mature, has more features.
    • CoffeeScript thinks JavaScript is too broken and needs a new simpler, different syntax to fix it.  TypeScript thinks JavaScript is not broken enough to be replaced.  It just needs to be strengthened.
    • TypeScript has strong VS.NET integration.

 

Download Files

SharePoint Saturday Perth - Building SharePoint solutions with TypeScript: how and why.

 

I'll be presenting a new topic for SharePoint Saturday Perth this year, on SharePoint and TypeScript.

While I had begin planning to work with TypeScript since the beginning of the year, I really owe it to Charlie Holland's blog post that really got me started.

Anyway, if you see the good parts in my demo, that'd be to his credit.  And if you see the lousy parts?  I'll claim those.

 

Building SharePoint Solutions with TypeScript

TypeScript is a new language designed as a superset of JavaScript. Released by Microsoft and designed by the father of C# Anders Hejlsberg. It is designed to ease building large scale applications using JavaScript, and addresses JavaScript shortfalls such as lacking a module system as well as type and compile-time type checking for better error detection and tooling.

SharePoint itself has become increasingly open over the recent versions with numerous new APIs available to client-side scripting, thus allowing more and more complex JavaScript applications. The time seems right that TypeScript will be a great addition to help us envision and attempt even more complex SharePoint solutions.

In this session, we want to tackle the two problems at hand: how do we set up our environment and get started with writing TypeScript with our solutions. And perhaps more importantly, what benefits do we get for choosing to go down this route with TypeScript.

 

A sneak preview

image

 

We'll build this Sandbox Webpart with TypeScript.  I'll see (some) of you this Saturday at Perth.

Ticket for SPSPER are very low, you'll need to register right away.

:-)

TypeScript and SharePoint - definition files

 

One of TypeScript's strengths is that you can use the ability to define Interfaces to produce Type Definition files for JavaScript.  These interface definitions provides an IDE (like Visual Studio) with a lot more type information at compile time regarding how to use a certain JavaScript object.

A large repository of definition files are at: https://github.com/borisyankov/DefinitelyTyped

Why is this related to SharePoint?  Well, javascript files provided in SharePoint are actually quite rich in meta data and could potentially be used to reverse engineer the TypeScript Definition Files. 

Without further delay...

  • Here's my TypeScript program
  • which will generate a JavaScript program
  • which will parse and read SP's JavaScript objects
  • which will produce TypeScript definition results

 

TypeScript code

 

module tools {

    export function findReturnType(o: any): string {

        // return;
        if (/return\s*;/gi.test(o)) return ": void";

        // no return
        if (!/return/gi.test(o)) return ": void";

        // return 1.1; return 1;
        if (/return\s*\d+(\.\d+)?;/gi.test(o)) return ": number";

        // return "xx";
        if (/return\s*"[^"]*?"\s*;/gi.test(o)) return ": string";

        // return 'xx';
        if (/return\s*'[^']*?'\s*;/gi.test(o)) return ": string";

        // return something;
        if (/return\s*[^;]+?;/gi.test(o)) return ": any";

        // don't know
        return ": any";
    }

    export function toClass(o: any): string {
        var isClass = o["__class"] == true;
        var typeName = o["__typeName"];

        var results = "interface " + typeName + "{\n";

        for (var member in o) {

            if (member.match(/\$|__/)) continue;

            var m = o[member];
            if (typeof (m) == "function") {
                var match = /function\s*(\(.*?\))/gi.exec(m);
                if (match) {
                    results += "function " + member + match[1] + findReturnType(m) + ";\n";
                }
            }
            else {
                results += "" + member + " : " + typeof (m) + ";\n";
            }
        }

        results += "}\n";

        return results;

    }

    export function toEnum(o: any): string {

        var typeName = o["__typeName"];
        var results = "interface " + typeName + "{\n";

        for (var member in o) {

            if (member.match(/\$|__/)) continue;

            var m = o[member];
            if (typeof (m) == "function") {
                continue;
            }
            else {
                results += "" + member + " : " + typeof (m) + ";\n";
            }
        }

        results += "}\n";
        return results;
    }

    export function toTypeScript(o: any): string {
        var isClass = o["__class"] == true;
        var isNamespace = o["__namespace"] == true;
        var isEnum = o["__enum"] == true;

        if (isClass) {
            return toClass(o);
        }
        if (isEnum) {
            return toEnum(o);
        }
        return "";
    }
}

 

What does this do?

 

When you run this code in the SharePoint browser console, you'd get this:

image

Which is nearly a usable TypeScript definition file. 

There are still a bunch of clean up to do, since this is a really basic list:

  • You will need to clean up the interface name. 
  • If you want, improve the arguments list, a number of the arguments are actually optional.
  • Remove zIndexStep and zIndexStart - which are properties in SP.UI.ModalDialog but aren't for public use.
  • Remove bind function - that's from jQuery

 

Here's another example, with enum's defined in SP.UI

image

 

Summary

In this quick blog article, I talked about using a TypeScript program to read the javascript object, and infer TypeScript definitions.  Since TypeScript contains far more information that isn't available in JavaScript, there will still be need to manually tweak the output.

Eventually, I hope we'll arrive at a place where we have fully documented TypeScript definitions for SharePoint available. 

Charlie Holland has started such a work, and it is available on https://github.com/chaholl/TypeScriptDefinitions/

http://www.chaholl.com/archive/2013/02/18/a-collection-of-typescript-definition-files-for-sharepoint-2013-et-al.aspx

Example uses of SPServices, JavaScript and SharePoint

 

I wanted to write about spservices.codeplex.com from Marc D Anderson - we've found ourselves using this really special library time and again across different projects to talk back to SharePoint quickly.

 

Starting Workflows

Here's a page from one of our Process Wiki articles.

image

 

  • We have a special "Contributor-only" webpart on the right. 
  • It shows the various workflow status' on the current page, as traffic light bubbles. 
  • The "Certify Process Page" calls a javascript function that calls StartWorkflow via SPServices.
  • The workflow is a Nintex workflow and triggers a significant multi-stage approval process.  But you can use StartWorkflow to start SharePoint workflows as well.

 

Getting List data, lots of list data

Here's our task list, represented as a taskboard.

image

  • This one is completely done with SPServices to get the list items
  • Convert the objects to JSON using SPServices.SPXmlToJson
  • Then binding the objects to UI via KnockoutJS
  • There's JQuery UI's drag and drop in play, so we can change the Task's status by dragging the task across a different column.
  • Update task using SPServices' UpdateItem call.
  • And some nice CSS. 
  • This particular page also runs via SharePoint 2010's OData listdata.svc, but is completely viable with SPServices on SP2007 as well.

 

Getting User Profiles via Search

Here's our People page.

image

 

  • First, get SharePoint to index your people.
  • Use SPServices to call SharePoint search to return a bunch of people, including their picture (one would say, especially their picture).
  • Here I use Knockout to render the pictures.  When clicked, each one opens that user's My Site page.
  • There's a filter box on the top right, as well as "fake" refinements on the left hand side that allows us to re-query SharePoint search for filtered people.
  • One possible idea here would be to use SPServices' User Profile Service support and talk directly to the User Profile service, if you want to skip the search service.

 

Summary

A quick post of 3 recent javascript customizations that heavily used SPServices.  Hope that give you guys a lot of ideas.  Let me know what you guys think.