Create multiple lists from SharePoint Framework app

“The SharePoint Framework (SPFx) is a page and web part model that provides full support for client-side SharePoint development, easy integration with SharePoint data, and support for open source tooling.” – as Microsoft writes on its official documentation site. https://docs.microsoft.com/en-us/sharepoint/dev/spfx/sharepoint-framework-overview

The dark side of this story is that, SPFx is very under documented. 🙁 This means you can’t find really good examples like case studies for Azure. Therefore when you should do a simple solution which creates at least 2 lists with a Lookup field between them, you are in trouble, because Microsoft doesn’t spend enough time to provide you a great documentation.

Luckily, I must solve this and my ambition pushes me toward the solution. After several days (in this case 6 working days), I spent in front of my laptop and tried to collect the crumbs of the information from the Internet…I made it. And now I would like to share it with you to avoid the sucks if you have to do this stuff. 🙂

Our target for Today to create an SPFx based app to SharePoint online which creates 2 lists with a Lookup field.

Step 1: Prepare the solution in Visual Studio code

For this the Microsoft provides a quite good overview documentation. Nevertheless I put here some extra steps for the better result.

  1. Install the Node.JS 10.20.1 (please don’t use different version because it won’t work well): https://nodejs.org/en/blog/release/v10.20.1/
  2. Prepare your development environment. https://docs.microsoft.com/en-us/sharepoint/dev/spfx/set-up-your-development-environment
  3. Configure msvs_version. This depends on your computer so you can use the following version related configurations. Choose one which works for you:
    npm config set msvs_version 2017 or npm config set msvs_version 2019

Now you can start to create your solution.

Step 2: Create basic project/solution in Visual Studio code

  1. Open the root directory of your development location on your computer.
  2. Create a directory for your solution. Today this would be multiple-lists-spfx
  3. Step into the newly created directory
  4. Open Visual Studio code on this directory
    From PowerShell: code .
    From Windows explorer: Open with Code
  5. Open a Terminal, then enter the following command:
    yo @microsoft/sharepoint
  6. Preconfigure the project:
    1. Accept the default multiple-lists-spfx as your solution name, and then select Enter.
    2. Select SharePoint Online only (latest), and then select Enter.
    3. Select Use the current folder as the location for the files.
    4. Select N to require the extension to be installed on each site explicitly when it’s being used.
    5. Select N on the question if solution contains unique permissions.
    6. Select WebPart as the client-side component type to be created.
    7. Web part name: MultipleLists
    8. Web part description: MultipleLists description
    9. Accept the default No JavaScipt framework option for the framework, and then select Enter to continue.

At this point, Yeoman installs the required dependencies and scaffolds solution files. It takes several minutes.

Post-configuration / additional checks

1. Open gulpfile.js and replace its content to the following – to use gupl as a global variable

'use strict';
const gulp = require('gulp');
const build = require('@microsoft/sp-build-web');
build.addSuppression(`Warning - [sass] The local CSS class 'ms-Grid' is not camelCase and will not be type-safe.`);
build.initialize(gulp);

2. Open package.json and check gulp version. Do not use the latest gulp version, because that doesn’t work well with SPFx. Use this exact version

"gulp": "~3.9.1"

3. Create the following folder structure to root folder

sharepoint
		- assets
		- solution

4. Check if deasync was blocked by your Anti-Virus software or not. If yes, please execute these

npm install deasync@0.1.19   
cd node_modules\deasync
node .\build.js
cd ../..

5. Trusting the self-signed developer certificate. (this also tests the whole of your project/solution configuration such as gulp version, deasync)

gulp trust-dev-cert

6. Install Insert GUID extension for Visual Studio Code. With this you can easily generate GUIDs for:

Guide instructions for the future:

  • For content types. Item related content type id:
    0x0100 + <Insert GUID – 5>
  • For Filed id:
    0x0100 + <Insert GUID – 2>
  • For id’s in package-solution.json:
    0x0100 + <Insert GUID – 1>

Done 🙂

Step 3: Create your List creation code

This is the most important part. The others above are “only” the preparation. You can apply this part in case of any type of client-side component such as WebPart and Extension.

1. After you created you basic project/solution, please create the following files into sharepoint/assets directory

  • elements.xml: this contains the site columns, content types and list instance definitions
  • primarySchema.xml: this contains the primary list related definitions, such as views and forms
  • secondarySchema.xml: this contains the secondary list related definitions, such as views and forms

2. Now start to edit elements.xml

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
    <!-- IsActive global field -->
    <Field ID="{9b9df7c1-8dca-4954-90c1-8dcf131e30af}" Name="IsItActive" DisplayName="Active" Type="Boolean" Required="FALSE" Group="CloudSteak Columns" />
    <!-- Content type for Secondary list -->
    <ContentType ID="0x010036ee6af136ed47a48c82fb0916a627ba" Name="SecondaryCT" Group="CloudSteak Content Types" Description="Sample content types from web part solution">
        <FieldRefs>
            <FieldRef ID="{9b9df7c1-8dca-4954-90c1-8dcf131e30af}" />
        </FieldRefs>
    </ContentType>
    <!-- Secondary list -->
    <ListInstance CustomSchema="secondarySchema.xml" FeatureId="00bfea71-de22-43b2-a848-c05709900100" Title="Secondary" Description="Secondary List" TemplateType="100" Url="Lists/Secondary">
    </ListInstance>
    <!-- Lookup field for Secondary list -->
    <Field ID="{B2C98746-DE9D-4878-90C1-D3749881790F}" Name="SecondaryLookup" DisplayName="Secondary" Type="Lookup" ShowField="Title" List="Lists/Secondary" Required="TRUE" Group="CloudSteak Columns" />

    <!-- Content type for Primary lists -->
    <ContentType ID="0x010042D013E716C0B03B457EB2E6699537B99CFE" Name="PrimaryCT" Group="CloudSteak Content Types" Description="Sample content types from web part solution">
        <FieldRefs>
            <FieldRef ID="{B2C98746-DE9D-4878-90C1-D3749881790F}" />
        </FieldRefs>
    </ContentType>

    <!-- Primary list -->
    <ListInstance CustomSchema="primarySchema.xml" FeatureId="00bfea71-de22-43b2-a848-c05709900100" Title="Primary" Description="Primary List" TemplateType="100" Url="Lists/Primary">
    </ListInstance>
</Elements>

Important! If you create Custom List you must use FeatureId=”00bfea71-de22-43b2-a848-c05709900100″ every time inside tag. For other instance types, you can find the required FeatureIds here: https://docs.microsoft.com/en-us/archive/blogs/vinitt/list-of-feature-id-listtemplate

3. Edit primarySchema.xml

<List xmlns:ows="Microsoft SharePoint" Title="Basic List" EnableContentTypes="TRUE" FolderCreation="FALSE" Direction="$Resources:Direction;" Url="Lists/Basic List" BaseType="0" 
    xmlns="http://schemas.microsoft.com/sharepoint/">
    <MetaData>
        <ContentTypes>
            <ContentTypeRef ID="0x010042D013E716C0B03B457EB2E6699537B99CFE" />
        </ContentTypes>
        <Fields>

        </Fields>
        <Views>
            <View BaseViewID="1" Type="HTML" WebPartZoneID="Main" DisplayName="$Resources:core,objectiv_schema_mwsidcamlidC24;" DefaultView="TRUE" MobileView="TRUE" MobileDefaultView="TRUE" SetupPath="pages\viewpage.aspx" ImageUrl="/_layouts/images/generic.png" Url="AllItems.aspx">
                <XslLink Default="TRUE">main.xsl</XslLink>
                <JSLink>clienttemplates.js</JSLink>
                <RowLimit Paged="TRUE">30</RowLimit>
                <Toolbar Type="Standard" />
                <ViewFields>
                    <FieldRef Name="LinkTitle"></FieldRef>
                    <FieldRef Name="SecondaryLookup"></FieldRef>
                </ViewFields>
                <Query>
                    <OrderBy>
                        <FieldRef Name="ID" />
                    </OrderBy>
                </Query>
            </View>
        </Views>
        <Forms>
            <Form Type="DisplayForm" Url="DispForm.aspx" SetupPath="pages\form.aspx" WebPartZoneID="Main" />
            <Form Type="EditForm" Url="EditForm.aspx" SetupPath="pages\form.aspx" WebPartZoneID="Main" />
            <Form Type="NewForm" Url="NewForm.aspx" SetupPath="pages\form.aspx" WebPartZoneID="Main" />
        </Forms>
    </MetaData>
</List>

4. Modify secondarySchema.xml

<List xmlns:ows="Microsoft SharePoint" Title="Basic List" EnableContentTypes="TRUE" FolderCreation="FALSE" Direction="$Resources:Direction;" Url="Lists/Basic List" BaseType="0" 
    xmlns="http://schemas.microsoft.com/sharepoint/">
    <MetaData>
        <ContentTypes>
            <ContentTypeRef ID="0x010036ee6af136ed47a48c82fb0916a627ba" />
        </ContentTypes>
        <Fields></Fields>
        <Views>
            <View BaseViewID="1" Type="HTML" WebPartZoneID="Main" DisplayName="$Resources:core,objectiv_schema_mwsidcamlidC24;" DefaultView="TRUE" MobileView="TRUE" MobileDefaultView="TRUE" SetupPath="pages\viewpage.aspx" ImageUrl="/_layouts/images/generic.png" Url="AllItems.aspx">
                <XslLink Default="TRUE">main.xsl</XslLink>
                <JSLink>clienttemplates.js</JSLink>
                <RowLimit Paged="TRUE">30</RowLimit>
                <Toolbar Type="Standard" />
                <ViewFields>
                    <FieldRef Name="LinkTitle"></FieldRef>
                    <FieldRef Name="IsItActive"></FieldRef>
                </ViewFields>
                <Query>
                    <OrderBy>
                        <FieldRef Name="Title" />
                    </OrderBy>
                </Query>
            </View>
        </Views>
        <Forms>
            <Form Type="DisplayForm" Url="DispForm.aspx" SetupPath="pages\form.aspx" WebPartZoneID="Main" />
            <Form Type="EditForm" Url="EditForm.aspx" SetupPath="pages\form.aspx" WebPartZoneID="Main" />
            <Form Type="NewForm" Url="NewForm.aspx" SetupPath="pages\form.aspx" WebPartZoneID="Main" />
        </Forms>
    </MetaData>
</List>

5. Configure package

  • Open config/package-solution.json
  • After “isDomainIsolated”: false insert the following lines
,
        "features": [
            {
                "title": "Create lists for CloudSteak solution",
                "description": "Lists builder",
                "id": "0bc610db-74ec-40c4-a867-1108fdf2b5f0",
                "version": "1.0.0.0",
                "assets": {
                    "elementManifests": [
                        "elements.xml"
                    ],
                    "elementFiles": [
                        "primarySchema.xml",
                        "secondarySchema.xml"
                    ]
                }
            }
        ]

6. Create a finalBuild.ps1 for easy package building. Then insert into it the following codes

clear
Write-Host "###################################    Increase build number   ###################################"
$psfile = Get-Content '.\config\package-solution.json' -raw | ConvertFrom-Json
$version = $psfile.solution.version
Write-Host "Old version number: " $version
$newVersion = $version.Split('.')[0] + '.' + $version.Split('.')[1] + '.' + $version.Split('.')[2] + '.' + ([INT]$version.Split('.')[3] + 1)
$psfile.solution.version = $newVersion
Write-Host "New version number: " $newVersion
$psfile | ConvertTo-Json -depth 32| set-content '.\config\package-solution.json'

Write-Host "###################################    gulp clean    ###################################"
gulp clean
Write-Host "###################################    gulp bundle --ship    ###################################"
gulp bundle --ship
Write-Host "###################################    gulp package-solution --ship    ###################################"
gulp package-solution --ship

7. Run finalBuild.ps1 from PowerShell terminal

.\finalBuild.ps1

Step 4: Upload to SharePoint AppCatalog

  1. Open AppCatalog page
    1. Open SharePoint Admin Center
    2. Under More Features: Apps > App Catalog > Apps for SharePoint
  2. Click on Upload option
  3. Click on Choose Files button
  4. Browse sppkg file:
    multiple-lists-spfx\sharepoint\solution\multiple-lists-spfx.sppkg
  5. Click open then ok
  6. Deploy
  7. Check package data

Step 5: Create Team Site for testing

  1. Open SharePoint Admin Center
  2. Navigate to Sites > Active Sites
  3. Click on Create button
  4. Select Team Site
  5. Enter required data. Next
  6. Add additional admins then click Finish

Step 6: Test package/solution

  1. Open team site
  2. Go to Site contents
  3. Click on add an app
  4. Select the name of our app’s name
  5. Wait for installation (refresh the page sometimes)
  6. After you can see the two newly created lists.

If you create some list items in Secondary list.

Then you start to create a list item in Primary list you can choose the list items of Secondary list to field Secondary.

This is quite cool and easy….now. 🙂

Notes

  1. You can find this code on GitHub: https://github.com/cloudsteak/SPFx/tree/master/multiple-lists-spfx
    • Note: If you want to use the cloned code, please run this command in the solution root directory: npm install
  2. For a very basic scenario, you can follow the official documentation: https://docs.microsoft.com/en-us/sharepoint/dev/spfx/web-parts/get-started/provision-sp-assets-from-package
  3. Upgrade package on SharePoint side:
    1. Open team site
    2. Go to Site contents
    3. Click on beside the app
    4. Click on About
    5. You can see the new version. To installation of the latest version click on Get button.

I hope this is an another useful material for you. 🙂

Create Multiple List with SPFx

CloudSteak on Twitter ...