The SharePoint Trip to Modern – Are We There Yet? Part 2

On the trip to SharePoint “Modern”…  I’m having a serious case of deja vu. Some macro-patterns I saw eons ago as a Microsoft Windows Developer I see again in SharePoint “Modern”… especially with SharePoint “Modern” forms.

SharePoint forms – “classic” and “Modern” – fall into three broad categories: list and library forms, survey forms, and “forms over data” applications (aka InfoPath). Classic forms in each category are functional… but hard to customize, and definitely not beautiful. So where are we, exactly, on the trip to modern forms, and what are these “macro-patterns” I see?

Let’s break it down.

Microsoft Forms is the “Modern” replacement for SharePoint classic surveys, PowerApps is the “Modern” replacement for InfoPath, and Modern list forms …we’ll discuss those momentarily.

I never cared much for SharePoint “classic”  surveys.  They seem too toy-like for anything but the simplest of surveys, and look ugly (to me). In fact, beautifying them requires custom development… typically with React or Angular, and supporting documentation for users to use it, site owners to configure it, and developers to support it. All for very little functionality. Which is why I was happy to see Microsoft Forms…  the “Modern” answer to SharePoint “classic” surveys.

Actually, I thought Microsoft Forms (which sort of sneaked up on me last year) was also too toy-like at first. But with constant improvements over the last year…  I think Microsoft has a winner here. The surveys are easy to design, look nice, are easily embedded in a SharePoint page, and easy to configure. Microsoft Forms plays well with others too – particularly with Microsoft Flow. There is even a curious integration with Excel (someone please tell me if this is useful). If Microsoft Forms stays on its current trajectory, it’ll be the SurveyMonkey® for corporate intranets.

PowerApps is out of the toy-stage, and positioned to replace InfoPath.  I expect PowerApps will do for SharePoint what Visual Basic did for Microsoft Windows development… and become the most popular tool for SharePoint “Modern” power users and developers.  A word to the wise for “I’m too cool for PowerApps… I do React/Angular/Vue” developers out there….  Visual Basic supplanted C++/MFC for corporate Windows development – because it was easier to learn, and quicker for creating “Forms over Data” applications. Will history repeat here, and relegate SPFx development to a smaller – but important – niche for high-end customizations? Maybe.  Regardless, I predict the PowerApps tsunami is coming. Are you ready?

Lastly, consider SharePoint List forms. Specifically, the classic EditForm.aspx, NewForm.aspx and listview.aspx forms, and their Modern alternatives. Many sophisticated SharePoint workflows depend on highly customized versions of these forms to view, create and update SharePoint list items.

SharePoint List/Library forms can be quite complex mini-applications in service to SharePoint workflows. Form data must be loaded, and fields labelled, disabled/enabled, validated, hidden or revealed – depending on the workflow state and who is looking. Error handling must be friendly and helpful.  Extra points for beauty.

Clients often don’t realize the effort required to achieve all this…  so it’s important to set expectations, and decide if functional – albeit ugly – forms are sufficient.  Or is beauty important too?

The “Microsoft approved” way to customize SharePoint “classic” forms is via JS Link and Client Side Rendering (CSR)  – you add customizations with client-side JavaScript/TypeScript, using Microsoft-provided hooks at key points in the form life-cycle. The coding patterns take some getting used to. And to make the forms visually appealing, you’re on your own. Many SharePoint developers have crashed and burned attempting to wrangle the ridiculously daunting CSS in SharePoint “classic” forms. Which brings me to SharePoint “Modern” form options.

We’re still screwed…  but less so. Beauty is within reach – with Microsoft Office UI Fabric React-based components and SPFx. But a few things are missing for developers.

When I built my first SharePoint “Modern” modal dialog box as an SPFx web part with these components, I was reminded of the early days of Microsoft Windows development, when Microsoft provided a Windows Software Development Kit (SDK) without a GUI-based dialog editor. Windows developers resorted to “imagining” their dialog layouts while coding them with a text editor. It was highly inefficient….  much like the situation today with SharePoint “Modern” modal dialogs. There is no GUI-based form Editor… the React-based field controls are “laid out” using JSX in a code editor. I hope Microsoft will get around to providing a GUI-based editor for list-item forms with Office UI Fabric React components (yes… I know Modern lists can be customized with PowerApps – but it’s not a viable option – not yet – for a SharePoint Modern modal dialog box containing Office UI Fabric components).

What else is missing? For starters, the Office UI Fabric React components lack “SharePoint awareness”. So you’ll need an abstraction layer over them. You could add your own abstraction layer… but smarter to use the SharePoint Patterns and Practices SPFx React Controls. These extend the Office UI Fabric React controls… adding SharePoint awareness.  But even here… we see signs of immaturity. Take for instance the oh-so-innocent looking People Picker control.

A SharePoint People Picker control is one of the nastiest, most difficult form controls to write yourself. And this is from personal experience. It’s the “iceberg” of SharePoint field controls, because so much is hidden beneath the surface. So I was very happy to see it offered in the Office UI Fabric React component library… that is, until I discovered it was neutered.  That is, the darn thing isn’t connected to SharePoint (or rather, the Azure AD instance attached to a SharePoint tenant).

But the PnP People Picker control fixes this.  You add it within your Office UI Fabric Dialog component…  and it just works…. almost. At the time of this writing, it lacks a property to initialize the people picker with users and/or SharePoint Groups (I’ve requested an enhancement to rectify this… so stay tuned). This means that if you have an existing list item containing a people field, and that people field is not empty… you cannot initialize the people picker control with that person.  While we’re waiting for a fix, you can do what I did and create your own people picker abstraction layer, starting from this React people picker control.

My beloved Knockout library is useless with these Office UI Fabric controls (and the PnP offshoots)… because you cannot add the Knockout bindings to the HTML attributes within the controls.. you don’t have access to the innards. Knowing how much Knockout reduces “classic” form complexity,  I worried that Modern form complexity would be unwieldy. But my fears were unfounded, since the controls have sufficient hooks to capture mouse and keyboard events, and properties to control the enabling, disabling, and show/hide behavior. At this point, it’s probably better to show you, rather than tell you about it.

But let’s pull over at the next rest stop….   I need a short break before showing you some code. And no… stop asking… we’re still not there yet… on our SharePoint trip to Modern. But almost.

Here’s our stop… want some Ice cream?

-bob

 

 

 

 

 

 

 

 

Want Simplicity? Use the SharePoint PnP JavaScript Core Library

If you’re a SharePoint developer and not using the SharePoint PnP JavaScript Core Library… you’re working too hard.

In an earlier blog post, I looked at Typescript’s asynch/await feature as a way to simplify asynchronous SharePoint code. In retrospect, the SharePoint PnP JavaScript Core Library is a better, simpler, more elegant solution.

We’ve all been here…  deciding to drop what works… in favor of risking something better. For SharePoint client-side asynchronous code… this was an easy decision.  Here’s a short snippet to illustrate the point:

static GetRoles ()
{
let deferred = $.Deferred();
// Get the groups the current user belongs to.
//
$.ajax({
url: _spPageContextInfo.webAbsoluteUrl + 
"/_api/web/currentuser/Groups?$select=Title",
method: "GET",
headers: {"accept": "application/json;odata=verbose"},
success: function (resultsData)
   {
   deferred.resolve(resultsData.d.results);
   },
error: function (jqXHR, textStatus, errorThrown)
   {
   window.console.log('error: loggedInUser.GetRoles returned an error');
   deferred.reject();
   }
});
return deferred.promise();
}

:
:

let promise1 = GetRoles();
:
$.when (promise1).done(function(data1)
   {
   processRoles (data1);

The GetRoles function make an asynch call into SharePoint, returning a promise, and the results are processed later. The GetRoles function is loaded with (typical) ugly asynch artifacts.

Now compare that version to this PnP version:
$pnp.sp.web.siteUsers.getById(_spPageContextInfo.userId).groups.select("Title").get()
.then ( groups=>
{
for (let group of groups)
   {
   // process groups...

Wow…  the GetRoles function is reduced to a one-liner…  with low-level asynch plumbing out of sight. I found that stringing multiple asynch calls together in parallel or serial fashion was easy, too.

I took the PnP code snippet above from a “traditional CSR” SharePoint list form…  where the PnP library was “included” via this JSLink expression:

https://cdnjs.cloudflare.com/ajax/libs/sp-pnp-js/3.0.2/pnp.min.js

I used the dollar sign, like this: “$pnp” to reference the PnP library in my (non-React) TypeScript code.

But in my React components, I import the PnP library like this:

import pnp from "sp-pnp-js";
 and reference the PnP library without the $,  like this:

pnp.sp.web.siteUsers.getById(loggedInUserId).get().then ( result=>
It’s all explained in the PnP Core Library github site.
I hope you find the SharePoint PnP JavaScript Core Library as enjoyable as I do.