Your first webpart with Sharepoint Framework

In the previous post we have created our developer tenant and set it up, then we set up our development machine to start coding our first web part with the SharePoint Framework.

Today, we will make the easiest Web Part that we can do, something that has one property and that based on the property the web part would need to do some action, so lets get our hands dirty, and start with this.

First than we have to know that what we are building here is pure client side web part, client side webparts are already supported in SharePoint and Office 365 but in a different way, you can add a Code Editor, and paste your JavaScript and HTML code there, that will work fine, but the problem with that approach is maintainability,the code resides on a page, in the code section of a webpart.

With Sharepoint Framework we can leverage the code development to real IDE, like Visual Studio, VS Code, Brackets, etc, and at the same time we can use Team Foundation Server for source code integration, unit testing, and probably continuous deployment, if TFS is not your friend we can do the same with Git, an internal Git Server or github for your hobby projects.

At this point, we can use CMD for some of the commands we need to execute, but I want to introduce a tool that some of you might not know, CMDER, a great replacement with a better look and feel and advanced features. You can download it here.

Step 1

Lets create our directory where our application will be hold.

mkdir OurFirstSPFApp  
cd OurFirstSPFApp  

Step 2

Create the webpart project, for this we will use the yeoman generator that we built on the previous step

yo @microsoft/sharepoint  

You will be prompted with a series of questions:

Accept the default name as your solution name and press Enter.
Select Use the current folder to place the files.

The next set of prompts will ask specific information about your web part:

Accept the default Name as your web part name and press Enter.
Accept the default Description as your web part description and press Enter.
Accept the default No javascript web framework as the framework you would like to use and press Enter.

Yeoman will install all required dependencies and scaffold the project structure as shown here:

Step 3

You can use any code editor you like, I like VS Code, and thats how you will see the screenshots.

To open the webpart in VS CODE just type:

code .  

Step 4

Now we need to preview our webpart, for that we need to rely on gulp, its task runner which handles build process such as:

Bundle and minify JavaScript and CSS files.
Run tools to call the bundling and minification tasks before each build.
Compile SASS files to CSS.
Compile TypeScript files to JavaScript.

In future post we will customize the build process with gulp.

For now, we will use the following command:

gulp serve  

This will create a local NodeJS Server
Once we run gulp serve a browser will be opened with our local workbench, this is where we will edit our page and add the webpart for testing.

Step 5

Lets buildour webpart,

Visual Studio Code provides built-in support for gulp and other task runners. You can press Ctrl+Shift+B if you are in Windows or Cmd+Shift+B if you are in Mac within Visual Studio Code to debug and preview your web part.

Once we hit this, you will be able to see on the Output window how the project is being built

Now you can add the webpart to your page,

And see it in action,

Step 5

Lets learn about the project structure

The src is where all magic happen, this is the folder that actually matters, and where we will be coding.

TypeScript is the primary language to build SharePoint client-side web parts. TypeScript is a typed superset of JavaScript that compiles to plain JavaScript. SharePoint client-side development tools are built using TypeScript classes, modules and interfaces to help developers build robust client-side web parts.

Step 6

Lets give a short walk through to the code and the most important files

OurFirstSpAppWebPart.ts The Web part class

OurFirstSpAppWebPart.ts defines the main entry point for the your web part where the web part class OurFirstSpAppWebPart extends the BaseClientSideWebPart. Any client-side web part should extend this class.

public constructor(context: IWebPartContext) {  
    super(context);
}

BaseClientSideWebPart implements the minimal functionality that is required to build a web part. This class also provides a bunch of parameters to validate and access to readonly properties such as displayMode, web part properties, web part context, web part instanceId, the web part domElement and much more.

Notice that we are also defining our web part class to accept a property type IOurFirstSpfWebPartWebPartProps

The property type is defined as an interface in a separate file IOurFirstSpfWebPartWebPartProps.ts

export interface IOurFirstSpfAppWebPartProps {  
  description: string;
}

This property definition is used to define your custom property types for your web part, which we will see in the Property Pane.

Web part render()

The DOM element where the web part should be rendered is available in the render method. This method is used to render the web part inside that DOM element. In our OurFirstSpfAppWebPart web part, we pass in the DIV to the DOM element. The method parameters include the display mode (either Read or Edit) and the configured web part properties if any:

import {  
  BaseClientSideWebPart,
  IPropertyPaneSettings,
  IWebPartContext,
  PropertyPaneTextField
} from '@microsoft/sp-client-preview';

import styles from './OurFirstSpfWebPart.module.scss';  
import * as strings from 'ourFirstSpfWebPartStrings';  
import { IOurFirstSpfWebPartWebPartProps } from './IOurFirstSpfWebPartWebPartProps';

export default class OurFirstSpfWebPartWebPart extends BaseClientSideWebPart<IOurFirstSpfWebPartWebPartProps> {

  public constructor(context: IWebPartContext) {
    super(context);
  }

public render(): void {  
  this.domElement.innerHTML = `
    <div class="${styles.helloWorld}">
      <div class="${styles.container}">
        <div class="ms-Grid-row ms-bgColor-themeDark ms-fontColor-white ${styles.row}">
          <div class="ms-Grid-col ms-u-lg10 ms-u-xl8 ms-u-xlPush2 ms-u-lgPush1">
            <span class="ms-font-xl ms-fontColor-white">Welcome to SharePoint!</span>
            <p class="ms-font-l ms-fontColor-white">Customize SharePoint experiences using Web Parts.</p>
            <p class="ms-font-l ms-fontColor-white">${this.properties.description}</p>
            <a href="https://github.com/SharePoint/sp-dev-docs/wiki" class="ms-Button ${styles.button}">
              <span class="ms-Button-label">Learn more</span>
            </a>
          </div>
        </div>
    </div>
  </div>`;
}

Lets analyze this code, the most important one, as you can see we import the styles from a css, but what is amazing about TypeScript is that we can replace styles dinamically using variables with bracket syntax

${styles.helloWorld}

Also here you can see that we can use

${this.properties.description}

to use the properties from the property panel, but what about if we want to make something more interesting, well this sample is not rocket science, but what I want you to notice is something called the Reactive Property Pane, we can explain about this later, but basically whatever you type or select on your properties is immediately reflected on your webpart zone doing whatever operation you are supposed to do, like calling webservices, etc.

For the example, I just added 2 properties on the file: IOurFirstSpfWebPartWebPartProps.ts

export interface IOurFirstSpfWebPartWebPartProps {  
  description: string;
  n1: string;
  n2: string;
}

Then I added these properties on the manifest.json

{
  "$schema": "../../../node_modules/@microsoft/sp-module-interfaces/lib/manifestSchemas/jsonSchemas/clientSideComponentManifestSchema.json",

  "id": "1ac1bfca-4ac6-4bb8-906e-6715ab383a2b",
  "componentType": "WebPart",
  "version": "0.0.1",
  "manifestVersion": 2,

  "preconfiguredEntries": [{
    "groupId": "1ac1bfca-4ac6-4bb8-906e-6715ab383a2b",
    "group": { "default": "Under Development" },
    "title": { "default": "OurFirstSpfWebPart" },
    "description": { "default": "OurFirstSPFWebPart description" },
    "officeFabricIconFontName": "Page",
    "properties": {
      "description": "OurFirstSpfWebPart",
       "n1": "1",
       "n2": "2"
    }
  }]
}

And finally on my render method I used these to sum 2 numbers.

  public render(): void {
    this.domElement.innerHTML = `
      <div class="${styles.ourFirstSpfWebPart}">
        <div class="${styles.container}">
          <div class="ms-Grid-row ms-bgColor-themeDark ms-fontColor-white ${styles.row}">
            <div class="ms-Grid-col ms-u-lg10 ms-u-xl8 ms-u-xlPush2 ms-u-lgPush1">
              <span class="ms-font-xl ms-fontColor-white">Welcome to SharePoint!</span>
              <p class="ms-font-l ms-fontColor-white">Customize SharePoint experiences using Web Parts.</p>
              <p class="ms-font-l ms-fontColor-white">${parseInt(this.properties.n1)+parseInt(this.properties.n2)}</p>
              <a href="https://github.com/SharePoint/sp-dev-docs/wiki" class="ms-Button ${styles.button}">
                <span class="ms-Button-label">Learn more</span>
              </a>
            </div>
          </div>
        </div>
      </div>`;
  }

The end result