SPFx: Back to Script Editor

SPFx: Back to Script Editor

Challenge 

SharePoint Framework allows developers the ability to create applications using modern front-end technologies, such as Gulp, TypeScript, LESS/SASS and many others.

1

However, you can spend months of development and get stuck on one of following: 

  • You want the SPFx app provided together with a site template. 
  • You want to provide your app dynamically on multiple sites using remote API. 
  • You want to use the same app for legacy SharePoint 2010/2013 installations. 
  • … your unsupported case … 

We faced the first two cases and started thinking about appropriate solution.

Solution 

Since SharePoint framework web parts are all about JavaScript and HTML, we decided to create a bridge that can be used as an entry point - something like a container and a starter script that gets web part settings and creates a React component. 
One of our goals was to keep as much code as possible from the original project so we could switch to SPFx again later. 
Let me explain how to untie your web part from the SharePoint Framework without losing its functionality.

1. Create SPFx project. 

Install Yeoman generator and follow the instructions from the following article. It clearly describes the architecture of the SharePoint Framework web part.
Implement your own logic here. I will use slightly modified example solution.

Sharepoint

Figure 1.1 - Web part screenshot 

In my example, ‘Title’ and ‘Description’ are localizable strings. I will describe how to make localization work later.

contents of ‘en-us.js’ file

Figure 1.2 – contents of ‘en-us.js’ file 

Values in these fields are web part settings and are set under the configuration menu.

SPFx web part settings

Figure 1.3 – SPFx web part settings 

Settings are declared in WebPart.ts file. That’s what we need to change.

Settings configuration

Figure 1.4 – Settings configuration

We will use JSON file on the server to store these settings. It can be the same folder where other scripts are stored. The entire file will be similar to what is shown on the following picture:

Properties JSON file

Figure 1.5 – Properties JSON file

Now we can start moving the code to separate solution.

2. Create React and TypeScript project.

We need to create a React project with TypeScript support. There are a lot of starter kits available on the Internet. You can also create your own project and configure it for your needs. For this example, I chose tsc-react-gulp-example by forcewake
Don’t forget to include "@microsoft/sp-core-library," "office-ui-fabric-react," and other packages that are used in your web part.

3. Copy source files.

Copy ‘webparts’ folder from SPFx project to new project. The folder structure should look similar to that (note that we don’t copy manifest, IListViewProps.ts and tests files):

‘webparts’ folder under SPFx (left) and Script Editor (right) projects

Figure 3.1 – 'webparts' folder under SPFx (left) and Script Editor (right) projects

4. Create localization file.

Create ‘listViewStrings.ts’ file as following:

Contents of localizable strings file

Figure 4.1 – Contents of localizable strings file

Just copy the contents of ‘en-us’ and other locale files into the object. Each localization is stored in a property named after the number representation of the locale. 1033 is for English, 1059 is for Belarusian and so on. The full list is available here. 
You can define default locale, change selection logic, implement independent translation for this web part only, etc. 
Now it is possible to use these strings.

Localized strings usage

Figure 4.2 – Localized strings usage

5. Create settings repository. 

In order to create our own settings storage, we use the ‘settings.txt’ file on the same server as mentioned in the end of Topic #1. For the example, we just need two methods: getSettingsAsJson and setSettings. The code is pretty simple and might be extended.

Settings store module

Figure 5.1 – Settings store module

6. Editing main.tsx file 

Now we are ready to create an entry point for our web part in the ‘main.tsx’ file. 
This file is responsible to getting/updating settings, providing access to a properties panel and web part creation using the properties.

Bridge that creates properties panel and web part

Figure 6.1 – Bridge that creates properties panel and web part

ListView is the web part that we moved from SPFx project. SettingsPanel is the component that emulates standard SPFx interface and allows changing properties. 
Upon creation, main component calls settings repository and gets settings from specified file. Then it writes settings into activeProperties object and shows the webpart. _getPropValueByName() method just finds the chosen property by name and returns its value. Figure 6.2 shows how it was implemented in the SPFx project. We just use _getPropValueByName() instead of this.properties object.

SPFx properties usage

Figure 6.2 – SPFx properties usage

7. Build and deploy. 

The main part is ready, so now you can build your solution with ‘gulp bundle’ command. 
That will create ‘dist’ folder with the following structure:

7.1

Figure 7.1 – Bundle files for deployment

Index.html file contains main container and links to JS and CSS files. Just upload bundle.css and bundle.js to your Site Assets Library, create settings.txt, (Figure 1.5) and place it into the same folder. 
The next step is to copy HTML markup into your Script Editor web part and insert correct URLs to bundle files. You also have to add one more tag and specify settings.txt path:

Contents of the Script Editor snippet

Figure 7.2 – Contents of the Script Editor snippet

Note, that the listViewConfigFilePath variable must be declared before bundle.js script. If everything is OK, you will see the web part. 
‘bootstrap.ts’ file inside the ‘src’ folder is responsible for the creation of root component. It must be modified to use class property instead of id, because sometimes we need to have two or more web parts on the page. Using classes, we can append our component to the nearest element which is not processed.

Bootstrap.ts which appends web part to the DOM-container

Figure 7.3 – Bootstrap.ts which appends web part to the DOM-container

Modified Bootstrap.ts file

Figure 7.4 – Modified Bootstrap.ts file

This solution allows us to put several web parts on the same page without any risks. You can even create two web parts and use the same settings file for both of them.

Web part from a Script Editor

Figure 7.5 – Web part from a Script Editor

It works, but it is not very friendly without styles.

8. Handle styles. 

Since SPFx uses SASS, we need to translate *.scss files into bundle.css. You can use any appropriate Node package for that. 
One more thing you should care about is the *.scss.ts files generated by SPFx build process. These files contain style name declarations as a JavaScript objects. In my example, I do not use style modules, so I removed prefixes:

Web part styles as a JS object (SPFx – left, SE - right)Web part styles as a JS object (SPFx – left, SE - right)     

Figure 8.1 – Web part styles as a JS object (SPFx – left, SE - right)

Configure your gulp to process SASS files and concatenate CSS files. Build and deploy your project again and you should see the following result:

Web part with styles applied

Figure 8.2 – Web part with styles applied

9. Implement SettingsPanel component. 

The final part of the process is implementation of graphical UI for editing settings. Of course, you can change settings.txt file using your favorite text-editor, but it can be simplified and done in SPFx style. 
This component should be able to show different types of settings (string, number, choice, etc.), handle changes, and return the updated result. I use switch-case construction in order to create inputs, textareas, selects and other elements depend on setting type.

Render method of SettingsPanel. Creates layout for each property by type

Figure 9.1 – Render method of SettingsPanel. Creates layout for each property by type

Place settings into a Panel component which is part of ‘office-ui-fabric-react’ node package.

Panel with setting groups inside the SettingsPanel component

Figure 9.2 – Panel with setting groups inside the SettingsPanel component

Implement change handlers (validation if needed) and insert into the main component as shown on Figure 6.1. _updateProperties() method receives new state of settings and calls Settings repository which updates settings.txt file.

Panel with setting groups inside the SettingsPanel component

Figure 9.3 – Method which updates web part properties 

Build and deploy your updated project. Now you can click on the Edit button to show the settings panel. It looks like the standard panel for SPFx. Change anything and click ‘Save’ button, the web part values will be updated.

Settings Panel

Figure 9.4 – Settings Panel 

Then, after reloading the page, these new values remain as expected. 

What’s Next? 

1. As you may see, there are no pages in the settings panel. It is not very complicated to implement pagination. 
2. Add more input types like checkbox, dropdowns, etc. 
3. In section #8 of this post, I mentioned that I just deleted all style prefixes. It is better to have separate Gulp task that updates *.scss.ts files on every build.

Created and shared by Mikhail Krupsky