Tag: SharePoint Online

QR Code Generator in the SharePoint Framework (SPFx) web part

This article provides steps to implement the QR Code Generator in the SharePoint Framework (SPFx) web part, generally, QR Code Generator is a simple and convenient tool that help you create QR Code image displayed on the screen. Several content types are supported, include Text, Url, Email, Phone number, Contact, Geolocation and SMS.

Create a new web part project

Open power shell and run following comment to create a new web part by running the Yeoman SharePoint Generator

yo @microsoft/sharepoint

When prompted:

Enter the webpart name as your solution name, and then select Enter.
Select Create a subfolder with solution name for where to place the files.
Select Y to allow the solution to be deployed to all sites immediately.
Select N on the question if solution contains unique permissions.
Select WebPart as the client-side component type to be created.

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

Enter your web part name, and then select Enter.
Enter your web part description, and then select Enter.
Select React framework as the framework you would like to use, and then select Enter.

Start Visual Studio Code (or your favorite code editor) within the context of the newly created project folder.

cd .\web part name\
code .

Install the library and required dependencies

npm install --save qrcode

In the react component properties interface file, replace below properties  

export interface ISpfxQrcodeProps {
  qrcontent: string;
  qrcodedata: string;
}

In the client-side web part class file, import the QRCode and the modify the client-side web part properties, property pane configuration and render functions are modified according to get and set QR code values, please refer below code.  

import * as React from 'react';
import * as ReactDom from 'react-dom';
import { Version } from '@microsoft/sp-core-library';
import {
  IPropertyPaneConfiguration,
  PropertyPaneTextField
} from '@microsoft/sp-property-pane';
import { BaseClientSideWebPart } from '@microsoft/sp-webpart-base';
import * as strings from 'SpfxQrcodeWebPartStrings';
import SpfxQrcode from './components/SpfxQrcode';
import { ISpfxQrcodeProps } from './components/ISpfxQrcodeProps';
import QRCode from 'qrcode'

export interface ISpfxQrcodeWebPartProps {
  qrcontent: string;
}

export default class SpfxQrcodeWebPart extends BaseClientSideWebPart<ISpfxQrcodeWebPartProps> {

  public render(): void {
    QRCode.toDataURL(this.properties.qrcontent)
      .then(url => {
        const element: React.ReactElement<ISpfxQrcodeProps> = React.createElement(
          SpfxQrcode,
          {
            qrcontent: this.properties.qrcontent,
            qrcodedata: url
          }
        );
        ReactDom.render(element, this.domElement);
      })
      .catch(err => {
        console.error(err)
      })
  }

  protected onDispose(): void {
    ReactDom.unmountComponentAtNode(this.domElement);
  }

  protected get dataVersion(): Version {
    return Version.parse('1.0');
  }

  protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
    return {
      pages: [
        {
          header: {
            description: strings.PropertyPaneDescription
          },
          groups: [
            {
              groupName: strings.BasicGroupName,
              groupFields: [
                PropertyPaneTextField('qrcontent', {
                  label: 'Code content'
                })
              ]
            }
          ]
        }
      ]
    };
  }
}

In the react component just replace the default render function to blow render function we just add the image to display the code  

import * as React from 'react';
import styles from './SpfxQrcode.module.scss';
import { ISpfxQrcodeProps } from './ISpfxQrcodeProps';

export default class SpfxQrcode extends React.Component<ISpfxQrcodeProps, {}> {
  public render(): React.ReactElement<ISpfxQrcodeProps> {
    return (
      <div className={styles.spfxQrcode}>
        <img className={styles.img} src={this.props.qrcodedata} alt={this.props.qrcontent} />
        <small>{this.props.qrcontent}</small>
      </div>
    );
  }
}

Deploy the solution

You’re now ready to build, bundle, package, and deploy the solution.

Run the gulp commands to verify that the solution builds correctly.

gulp build

Use the following command to bundle and package the solution.

gulp bundle --ship
gulp package-solution --ship

Browse to the app catalog of your target tenant and upload the solution package. You can find the solution package under the sharepoint/solution folder of your solution. It is the .sppkg file. After you upload the solution package in the app catalog. you can find and the web part anywhere across the tenant.

For your reference, this complete project added in to the GitHub

Sharing is caring!

If you have any questions, feel free to let me know in the comments section.
Happy coding!!!

Modern Page Provisioning in the SharePoint Framework (SPFx)

This article provides steps to implement the mordern page provisioning using PnPjs in the SharePoint Framework (SPFx), generally PnPjs clientside pages module allows you to created, edit, and delete modern SharePoint pages. There are methods to update the page settings and add/remove client-side webparts.

Create a new web part project

Open power shell and run following comment to create a new web part by running the Yeoman SharePoint Generator

yo @microsoft/sharepoint

When prompted:

Enter the webpart name as your solution name, and then select Enter.
Select Create a subfolder with solution name for where to place the files.
Select Y to allow the solution to be deployed to all sites immediately.
Select N on the question if solution contains unique permissions.
Select WebPart as the client-side component type to be created.

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

Enter your web part name, and then select Enter.
Enter your web part description, and then select Enter.
Select React framework as the framework you would like to use, and then select Enter.

Start Visual Studio Code (or your favorite code editor) within the context of the newly created project folder.

cd .\web part name\
code .

Install the library and required dependencies

npm install @pnp/sp --save

Import the library into your application, update constructor, and access the root sp object in render for PnPjs libraries.

sp.setup({spfxContext: this.props.spcontect});

Configure the custom properties

Create a new source code file under the src\webparts\<Webpart name>\components\ folder of the solution. Create the new file I<web part name>State.ts and use it to create a TypeScript Interface

export interface ISpfxPnpPageprovisioningState {
  title: string;
  name:string;
}

In addition, you need to update the render method of the client-side web part to create a properly configured instance of the React component for rendering. The following code shows the updated method definition.

  public render(): void {
    const element: React.ReactElement<ISpfxPnpPageprovisioningProps> = React.createElement(
      SpfxPnpPageprovisioning,
      {
        description: this.properties.description,
        context:this.context
      }
    );
    ReactDom.render(element, this.domElement);
  }

Update the tsx file located under the components. First, add some import statements to import the types you defined earlier. Notice the import for I<web part name>Props and I<web part name>State. There are also some imports pnp sp imports.

import * as React from 'react';
import styles from './SpfxPnpPageprovisioning.module.scss';
import { ISpfxPnpPageprovisioningProps } from './ISpfxPnpPageprovisioningProps';
import { ISpfxPnpPageprovisioningState } from './ISpfxPnpPageprovisioningState';
import { autobind } from 'office-ui-fabric-react/lib/Utilities';
import { sp } from "@pnp/sp";
import "@pnp/sp/webs";
import "@pnp/sp/clientside-pages/web";
import { PrimaryButton, TextField } from 'office-ui-fabric-react';
import { ClientsideText, ClientsideWebpart } from "@pnp/sp/clientside-pages";
import "@pnp/sp/comments/clientside-page";

Replace this render function with the following code.

  public render(): React.ReactElement<ISpfxPnpPageprovisioningProps> {
    return (
      <div className={styles.spfxPnpPageprovisioning}>
        <TextField label="Page Name" onChanged={(val) => { this.setState({ name: val }) }} />
        <TextField label="Page Title" onChanged={(val) => { this.setState({ title: val }) }} />
        <br />
        <PrimaryButton text="Create Page" onClick={this._CreatePage} />
      </div>
    );
  }

Update the React component type declaration and add a constructor, as shown in the following example.

export default class SpfxPnpPageprovisioning extends React.Component<ISpfxPnpPageprovisioningProps, ISpfxPnpPageprovisioningState> {
  constructor(props: ISpfxPnpPageprovisioningProps) {
    super(props);
    sp.setup({
      spfxContext: this.props.context
    });
    this.state = {
      title: '',
      name: ''
    }
  }

place the below code inside the react component code, these function using PnPjs to create modern page in the Site Pages library

@autobind
  private async _CreatePage() {
    //Page layout type are "Article" | "Home"
    const page = await sp.web.addClientsidePage(this.state.name, this.state.title, "Article");
    let section = page.addSection()
    //Column size factor. Max value is 12 (= one column), other options are 8,6,4 or 0
    let column1 = section.addColumn(8);
    let column2 = section.addColumn(4);

    column1.addControl(new ClientsideText("This is text added into column 1"))
    column2.addControl(new ClientsideText("This is text added into column 2"))

    const partDefs = await sp.web.getClientsideWebParts();
    const partDef = partDefs.filter(c => c.Id === "490d7c76-1824-45b2-9de3-676421c997fa");
    const part = ClientsideWebpart.fromComponentDef(partDef[0]);
    column1.addControl(part);
    await page.save();
    // //Header
    // page.topicHeader = "My cool header!";
    // page.headerTextAlignment = "Center";

    // //You can manage to show and hide the published date
    // page.showPublishDate = true;

    // //can hide/show the comments
    // await page.enableComments();
    // //Banner image can change like this
    // page.bannerImageUrl = "/server/relative/path/to/image.png";
  }

Webpart name and id for your reference

ContentRollupWebPart ------- daf0b71c-6de8-4ef7-b511-faae7c388708
BingMapsWebPart ------- e377ea37-9047-43b9-8cdb-a761be2f8e09
ButtonWebPart ------- 0f087d7f-520e-42b7-89c0-496aaf979d58
CallToActionWebPart ------- df8e44e7-edd5-46d5-90da-aca1539313b8
CodeSnippetWebPart ------- 7b317bca-c919-4982-af2f-8399173e5a1e
ConnectorWebPart ------- 893a257e-9c92-49bc-8a36-2f6bb058da34
ContentEmbedWebPart ------- 490d7c76-1824-45b2-9de3-676421c997fa
CountdownWebPart ------- 62cac389-787f-495d-beca-e11786162ef4
CustomMessage ------- 71c19a43-d08c-4178-8218-4df8554c0b0e
DividerWebPart ------- 2161a1c6-db61-4731-b97c-3cdb303f7cbb
DocumentEmbedWebPart ------- b7dd04e1-19ce-4b24-9132-b60a1c2b910d
EventsWebPart ------- 20745d7d-8581-4a6c-bf26-68279bc123fc
FieldsWebPart ------- cf91cf5d-ac23-4a7a-9dbc-cd9ea2a4e859
FormsWebPart ------- b19b3b9e-8d13-4fec-a93c-401a091c0707
GroupCalendarWebPart ------- 6676088b-e28e-4a90-b9cb-d0d0303cd2eb
HeroWebPart ------- c4bd7b2f-7b6e-4599-8485-16504575f590
ImageWebPart ------- d1d91016-032f-456d-98a4-721247c305e8
ImageGalleryWebPart ------- af8be689-990e-492a-81f7-ba3e4cd3ed9c
KindlePreviewWebPart ------- 46698648-fcd5-41fc-9526-c7f7b2ace919
LinkPreviewWebPart ------- 6410b3b6-d440-4663-8744-378976dc041e
ListPropertiesWebPart ------- a8cd4347-f996-48c1-bcfb-75373fed2a27
ListWebPart ------- f92bf067-bc19-489e-a556-7fe95f508720
MarkdownWebPart ------- 1ef5ed11-ce7b-44be-bc5e-4abd55101d16
MyDocumentsWebPart ------- b519c4f1-5cf7-4586-a678-2f1c62cc175a
NewsWebPart ------- 8c88f208-6c77-4bdb-86a0-0c47b4316588
NewsfeedWebPart ------- 0ef418ba-5d19-4ade-9db0-b339873291d0
NewsLink ------- c1b5736d-84dd-4fdb-a7be-e7e9037bd3c3
NewsreelWebPart ------- a5df8fdf-b508-4b66-98a6-d83bc2597f63
PageTitle ------- cbe7b0a9-3504-44dd-a3a3-0e5cacd07788
PeopleWebPart ------- 7f718435-ee4d-431c-bdbf-9c4ff326f46e
PlannerWebPart ------- 39c4c1c2-63fa-41be-8cc2-f6c0b49b253d
PowerAppPlayerWebPart ------- 9d7e898c-f1bb-473a-9ace-8b415036578b
PowerBIReportEmbedWebPart ------- 58fcd18b-e1af-4b0a-b23b-422c2c52d5a2
QuickChartWebPart ------- 91a50c94-865f-4f5c-8b4e-e49659e69772
QuickLinksWebPart ------- c70391ea-0b10-4ee9-b2b4-006d3fcad0cd
SiteActivityWebPart ------- eb95c819-ab8f-4689-bd03-0c2d65d47b1f
SitesWebPart ------- 7cba020c-5ccb-42e8-b6fc-75b3149aba7b
SpacerWebPart ------- 8654b779-4886-46d4-8ffb-b5ed960ee986
DocLibWebPart ------- 6ee6fe3d-ed5f-4c42-b663-b1df52a8ae3b
FileViewerWebPart ------- 2a8b07f2-b38f-4df0-8e8b-2cd2a8b8d32b
ImageViewerWebPart ------- 5e945ea8-0e6c-4f52-b7c2-75ae618396e5
MRModelViewerWebPart ------- e19cef07-c1ad-42ea-a3d8-a536d6415476
People ------- 102f1fc1-3369-4372-8e44-f27dd11a9377
SpacesTestWebPart ------- b3a690f0-bed6-4ccb-a186-ed70412fc35b
Text2DWebPart ------- e30ff702-e1a4-4e02-8c11-3cce0139727a
MrImageThreeSixtyWebPart ------- 8bcd4369-10e6-46a9-b718-fa47db2864ca
MrVideoThreeSixtyWebPart ------- 4bdfb4be-6e39-4b1d-af8b-addbd3a582ff
VideoPlayerWebPart ------- 8902cf6d-22e5-4615-b036-57c613b8db6b
TwitterWebPart ------- f6fdf4f8-4a24-437b-a127-32e66a5dd9b4
EmbeddedVideoWebPart ------- 275c0095-a77e-4f6d-a2a0-6a7626911518
WeatherWebPart ------- 868ac3c3-cad7-4bd6-9a1c-14dc5cc8e823
WorldClockWebPart ------- 81b57906-cbed-4bb1-9823-2e3314f46f28
YammerFullFeedWebPart ------- cb3bfe97-a47f-47ca-bffb-bb9a5ff83d75
YammerEmbedWebPart ------- 31e9537e-f9dc-40a4-8834-0e3b7df418bc
YouTubeEmbedWebPart ------- 544dd15b-cf3c-441b-96da-004d5a8cea1d
tslib ------- 01c4df03-e775-48cb-aa14-171ee5199a15
SPTelemetry ------- 8217e442-8ed3-41fd-957d-b112e841286a
SPSuiteNav ------- f8a8ad94-4cf3-4a19-a76b-1cec9da00219
SPLoader ------- 1c6c9123-7aac-41f3-a376-3caea41ed83f
OfficeUIFabricReact ------- 02a01e42-69ab-403d-8a16-acd128661f8e
SPLodashSubset ------- 73e1dc6c-8441-42cc-ad47-4bd3659f8a3a
SPDataProviders ------- 1cea229f-b208-4202-8014-22503d92a019
sp-webpart-shared ------- 914330ee-2df2-4f6e-a858-30c23a812408
SPCoreLibrary ------- 7263c7d0-1d6a-45ec-8d85-d4d1d234171b
SPPageContext ------- 1c4541f7-5c31-41aa-9fa8-fbc9dc14c0a8
SPWebPartBase ------- 974a7777-0990-4136-8fa6-95d80114c2e0
FabricStyling ------- 17ce0976-e69a-4355-be84-89b69a74717d
SPComponentUtilities ------- 8494e7d7-6b99-47b2-a741-59873e42f16f
SPLoadThemedStyles ------- 229b8d08-79f3-438b-8c21-4613fc877abd
SPDeferredComponent ------- fa4155f6-2498-4a20-8406-5cb3b385b142
SPDiagnostics ------- 78359e4b-07c2-43c6-8d0b-d060b4d577e8
Decorators ------- f97266fb-ccb7-430e-9384-4124d05295d3
OdspUtilitiesBundle ------- cc2cc925-b5be-41bb-880a-f0f8030c6aff
SPComponentBase ------- 467dc675-7cc5-4709-8aac-78e3b71bd2f6
SPBingMap ------- ab22169a-a644-4b69-99a2-4295eb0f633c
RichImage ------- 4e1d8ea3-d90c-46fc-b4a1-367b9bc0046a
SPHttp ------- c07208f0-ea3b-4c1a-9965-ac1b825211a6
SPEmbedWebPartBase ------- 1de47009-ab52-4ff1-a8ed-f5876549bcac
SPHtmlEmbed ------- 3fbad3f4-a628-41b0-8694-2054c09edccd
SPPropertyPane ------- f9e737b7-f0df-4597-ba8c-3060f82380db
I18nUtilities ------- c83d5509-ccd5-4c67-919f-2440f237927a
FlexLayout ------- 0447e11d-bed9-4898-b600-8dbcd95e9cc2
SPCarouselLayout ------- 8ac0c53c-e8d0-4e3e-87d0-7449eb0d4027
SPA11y ------- 05ed6956-59ad-4aa6-9e4e-b832c96ae87b
SpListViewCommon ------- 5f18a9a1-d34e-4b05-a71f-e5e554d8649b
ListDocumentLayout ------- c6eb85d4-7fd2-4938-bfb8-5a899344ee86
GridLayout ------- 706e33c8-af37-4e7b-9d22-6e5694d92a6f
SPTopicShared ------- 49d290fb-a38e-4001-97d3-a2db486db2fa
SPSitePicker ------- 7ad20b0d-6a5d-43c3-a111-8c7f425b6bf2
sp-safehtml ------- 6d3c733c-8cb7-4871-bb22-b5b37c1d518d
BabylonJs ------- 80a36065-cad6-4380-987d-369f14527bbd
SPMLib ------- feb89e5b-d4ba-4f56-a328-01558d50086b
SPDynamicData ------- e40f8203-b39d-425a-a957-714852e33b79
SPListViewExtensibility ------- d37b65ee-c7d8-4570-bc74-2b294ff3b380
SPApplicationBase ------- 4df9bb86-ab0a-4aab-ab5f-48bf167048fb
SPExtensionBase ------- 0773bd53-a69e-4293-87e6-ba80ea4d614b
SPDragZone ------- f7fa85fe-da91-45cb-9813-5c31106cba7b
SPDialog ------- c0c518b8-701b-4f6f-956d-5782772bb731
SPSearchExtensibility ------- 4958ea79-6ff3-4480-8291-0932dd010869

Deploy the solution

You’re now ready to build, bundle, package, and deploy the solution.

Run the gulp commands to verify that the solution builds correctly.

gulp build

Use the following command to bundle and package the solution.

gulp bundle
gulp package-solution

Browse to the app catalog of your target tenant and upload the solution package. You can find the solution package under the sharepoint/solution folder of your solution. It is the .sppkg file. After you upload the solution package in the app catalog. you can find and the web part anywhere across the tenant.

Sharing is caring!

If you have any questions, feel free to let me know in the comments section.
Happy coding!!!

Simple list operations in SPFx using PnPjs

In your SharePoint Framework solutions, you will likely want to interact with data stored in SharePoint. PnPjs offers a fluent api used to call the SharePoint rest services. This article outlines what options you have, how they work and what their advantages.

Create a new web part project

Open power shell and run following comment to create a new web part by running the Yeoman SharePoint Generator

yo @microsoft/sharepoint

When prompted:

Enter the webpart name as your solution name, and then select Enter.
Select Create a subfolder with solution name for where to place the files.
Select Y to allow the solution to be deployed to all sites immediately.
Select N on the question if solution contains unique permissions.
Select WebPart as the client-side component type to be created.

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

Enter your web part name, and then select Enter.
Enter your web part description, and then select Enter.
Select React framework as the framework you would like to use, and then select Enter.

Start Visual Studio Code (or your favorite code editor) within the context of the newly created project folder.

cd .\Simple_List_Operations\
code .

Install the library and required dependencies

npm install @pnp/sp --save

Import the library into your application, update constructor, and access the root sp object in render for PnPjs libraries

    sp.setup({
      spfxContext: this.props.spcontect
    });

Configure the custom properties

Create a new source code file under the src\webparts\simpleListOperations\components\ folder of the solution. Call the new file ISimpleListOperationsState.ts and use it to create a TypeScript Interface

export interface ISimpleListOperationsState {
  addText: string;
  updateText:IListItem[];
}

and one more in the same file

export interface IListItem {
  id: number;
  title: string;
}

In addition, you need to update the render method of the client-side web part to create a properly configured instance of the React component for rendering. The following code shows the updated method definition.

public render(): void {
    const element: React.ReactElement<ISimpleListOperationsProps> = React.createElement(
      SimpleListOperations,
      {
        description: this.properties.description,
        spcontext: this.context
      }
    );
    ReactDom.render(element, this.domElement);
  }

Update the SimpleListOperations.tsx file. First, add some import statements to import the types you defined earlier. Notice the import for ISimpleListOperationsPropsISimpleListOperationsState and IListItem. There are also some imports for the Office UI Fabric components used to render the UI of the React component and pnp sp imports.

import * as React from 'react';
import styles from './SimpleListOperations.module.scss';
import { ISimpleListOperationsProps } from './ISimpleListOperationsProps';
import { ISimpleListOperationsState, IListItem } from './ISimpleListOperationsState';
import { TextField, DefaultButton, PrimaryButton, Stack, IStackTokens, IIconProps } from 'office-ui-fabric-react/lib/';
import { Environment, EnvironmentType } from '@microsoft/sp-core-library';
import { autobind } from 'office-ui-fabric-react/lib/Utilities';

import { sp } from "@pnp/sp";
import "@pnp/sp/webs";
import "@pnp/sp/lists";
import "@pnp/sp/items";
import { IItemAddResult } from "@pnp/sp/items";

After the imports, define the icon for button component of Office UI Fabric

const stackTokens: IStackTokens = { childrenGap: 40 };
const DelIcon: IIconProps = { iconName: 'Delete' };
const ClearIcon: IIconProps = { iconName: 'Clear' };
const AddIcon: IIconProps = { iconName: 'Add' };

Replace this component with the following code.

 public render(): React.ReactElement<ISimpleListOperationsProps> {
    return (
      <div className={styles.simpleListOperations}>
        <div className={styles.container}>
          <div className={styles.row}>
            <div className={styles.column}>
              {this.state.updateText.map((row, index) => (
                <Stack horizontal tokens={stackTokens}>
                  <TextField label="Title" underlined value={row.title} onChanged={(textval) => { row.title = textval }} ></TextField>
                  <PrimaryButton text="Update" onClick={() => this._updateClicked(row)} />
                  <DefaultButton text="Delete" onClick={() => this._deleteClicked(row)} iconProps={DelIcon} />
                </Stack>
              ))}

              <br></br>
              <hr></hr>
              <label>Create new item</label>
              <Stack horizontal tokens={stackTokens}>
                <TextField label="Title" underlined value={this.state.addText} onChanged={(textval) => this.setState({ addText: textval })} ></TextField>
                <PrimaryButton text="Save" onClick={this._addClicked} iconProps={AddIcon} />
                <DefaultButton text="Clear" onClick={this._clearClicked} iconProps={ClearIcon} />
              </Stack>
            </div>
          </div>
        </div>
      </div>
    );
  }

Update the React component type declaration and add a constructor, as shown in the following example.

  constructor(prop: ISimpleListOperationsProps, state: ISimpleListOperationsState) {
    super(prop);
    this.state = {
      addText: '',
      updateText: [],
    };
    sp.setup({
      spfxContext: this.props.spcontext
    });
    if (Environment.type === EnvironmentType.SharePoint) {
      this._getListItems();
    }
    else if (Environment.type === EnvironmentType.Local) {
      // return (<div>Whoops! you are using local host...</div>);
    }
  }

place the below code after the react component code, these functions using PnPjs to get the data, create list items, update list item and delete the list item.

async _getListItems() {
    const allItems: any[] = await sp.web.lists.getByTitle("Colors").items.getAll();
    console.log(allItems);
    let items: IListItem[] = [];
    allItems.forEach(element => {
      items.push({ id: element.Id, title: element.Title });
    });
    this.setState({ updateText: items });
  }

  @autobind
  async _updateClicked(row: IListItem) {
    const updatedItem = await sp.web.lists.getByTitle("Colors").items.getById(row.id).update({
      Title: row.title,
    });

  }

  @autobind
  async _deleteClicked(row: IListItem) {
    const deletedItem = await sp.web.lists.getByTitle("Colors").items.getById(row.id).recycle();
    this._getListItems();
  }

  @autobind
  async _addClicked() {
    const iar: IItemAddResult = await sp.web.lists.getByTitle("Colors").items.add({
      Title: this.state.addText
    });
    this.setState({ addText: '' });
    this._getListItems();
  }

  @autobind
  private _clearClicked(): void {
    this.setState({ addText: '' })
  }

Deploy the solution

You’re now ready to build, bundle, package, and deploy the solution.

Run the gulp commands to verify that the solution builds correctly.

gulp build

Use the following command to bundle and package the solution.

gulp bundle
gulp package-solution

Browse to the app catalog of your target tenant and upload the solution package. You can find the solution package under the sharepoint/solution folder of your solution. It is the .sppkg file. After you upload the solution package in the app catalog. you can find and the web part anywhere across the tenant.

Sharing is caring!

If you have any questions, feel free to let me know in the comments section.
Happy coding!!!

Office UI Fabric People Picker in Property Pane – SharePoint Framework (SPFx)

As we know Office UI Fabric which official front-end framework is for building a user interface that fits seamlessly into SharePoint modern experience. In this article, we going to see more detail about the adding custom controls like office UI fabric people picker and Persona in the property pane.

Creating a new SharePoint Framework web-part project

The first step we have to create a new SharePoint framework react web-part project, I have used SharePoint Framework version 1.8.2, if you have any question regarding set-up new SharePoint framework development environment then you can refer my one of the previous article where I explained simple steps to set up a new development environment and create the new project. While creating a project in the PowerShell you must select react framework.

Important files

In the new SharePoint framework web part solution contains many files, but in this article, we are going take look only files which are under src/webpart

Web part TS file (PropertyPaneSpFxWebPart.ts)

In this file, we create react element and created element assigned to the react DOM, also we are passing web part context as props so we can access these props in while create react component.

import * as React from 'react';
import * as ReactDom from 'react-dom';
import { BaseClientSideWebPart } from '@microsoft/sp-webpart-base';
import {
  IPropertyPaneConfiguration
} from '@microsoft/sp-property-pane';
import * as strings from 'PropertyPaneSpFxWebPartStrings';
import PropertyPaneSpFx from './components/PropertyPaneSpFx';
import { PropertyPanetextboxcustom } from './components/PropertyPaneControl';

export interface IPropertyPaneSpFxWebPartProps {
  selectedusers: any;
  onchange(stringvalue:string):void;
}

export default class PropertyPaneSpFxWebPart extends BaseClientSideWebPart<IPropertyPaneSpFxWebPartProps> {

  public render(): void {
    if(this.properties.selectedusers == "[]")
    {
      this.properties.selectedusers=[];
    }
    const element: React.ReactElement<IPropertyPaneSpFxWebPartProps> = React.createElement(
      PropertyPaneSpFx,
      {
        selectedusers: this.properties.selectedusers,
        onchange:this.onChanged
      }
    );
    ReactDom.render(element, this.domElement);
  }

  private onChanged(stringvalue:any): void {
    this.properties.selectedusers=stringvalue;
    this.render();
  }


  protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
    return {
      pages: [
        {
          header: {
            description: strings.PropertyPaneDescription
          },
          groups: [
            {
              groupName: strings.BasicGroupName,
              groupFields: [
                PropertyPanetextboxcustom(this.properties.selectedusers,this.onChanged.bind(this), this.context)
              ]
            }
          ]
        }
      ]
    };
  }
}

React component (CustomPeoplePicker.tsx)

In this file we creating the office UI fabric people picker component, So created component will be turned as property pane custom field in another file.

import * as React from 'react';
import { IPersonaProps } from 'office-ui-fabric-react/lib/Persona';
import { IPropertyFieldMessageBarPropsInternal } from './PropertyPaneControl';  
import { NormalPeoplePicker } from 'office-ui-fabric-react/lib/Pickers';
import { SPHttpClient, SPHttpClientResponse } from '@microsoft/sp-http'; 
import { autobind } from 'office-ui-fabric-react/lib//Utilities'; 

export default class customtext extends React.Component<IPropertyFieldMessageBarPropsInternal, {}> {

  public render(): React.ReactElement<{}> {
    return (
      <div>
          <NormalPeoplePicker onResolveSuggestions={this._onFilterChanged}  resolveDelay={200}  onChange={this._onChange1}/>
      </div>
    );
  }

  private _onChange1 = (items?:IPersonaProps[]) => {
    this.props.onPropertyChange(items);
  };

  @autobind 
  private _onFilterChanged(filterText: string) { 
    if (filterText) { 
      if (filterText.length > 2) { 
        return this.searchPeople(filterText);         
      } 
    } else { 
      return []; 
    } 
  } 

  private searchPeople(terms: string): IPersonaProps[] | Promise<IPersonaProps[]> { 
    return new Promise<IPersonaProps[]>((resolve, reject) => 
      this.props.spcontect.spHttpClient.get(`${this.props.spcontect.pageContext.web.absoluteUrl}/_api/search/query?querytext='*${terms}*'&rowlimit=10&sourceid='b09a7990-05ea-4af9-81ef-edfab16c4e31'`, 
        SPHttpClient.configurations.v1, 
        { 
          headers: { 
            'Accept': 'application/json;odata=nometadata', 
            'odata-version': '' 
          } 
        }).then((response: SPHttpClientResponse): Promise<{ PrimaryQueryResult: any }> => { 
          return response.json(); 
        }).then((response: { PrimaryQueryResult: any }): void => { 
          let relevantResults: any = response.PrimaryQueryResult.RelevantResults; 
          let resultCount: number = relevantResults.TotalRows; 
          let people = []; 
          if (resultCount > 0) { 
            relevantResults.Table.Rows.forEach(function (row) { 
              let persona: IPersonaProps = {}; 
              row.Cells.forEach(function (cell) { 
                if (cell.Key === 'JobTitle') 
                  persona.secondaryText = cell.Value; 
                if (cell.Key === 'PictureURL') 
                  persona.imageUrl = cell.Value; 
                if (cell.Key === 'PreferredName') 
                  persona.primaryText = cell.Value; 
              }); 
              people.push(persona); 
            }); 
          } 
          resolve(people); 
        }, (error: any): void => { 
          reject(); 
        })); 
  }
}

Property pane component file (PropertyPaneControl.ts)

In this file, we implement the generic interface of IPropertyPaneField and rendering the office UI fabric people picker component which we created. at the end of the file, we also created one function for calling the property pane field, basically this will help us to call without calling as a new class we can directly call this function.  

import * as React from 'react';
import * as ReactDom from 'react-dom';
import {  
  IPropertyPaneCustomFieldProps,  
  IPropertyPaneField,  
  PropertyPaneFieldType  
} from '@microsoft/sp-webpart-base';  
import customtext from './CustomPeoplePicker';

export interface IPropertyFieldMessageBarPropsInternal extends IPropertyPaneCustomFieldProps {  
  onPropertyChange(items:any[]): void;    
  onRender(elem: HTMLElement): void;
  onDispose(elem: HTMLElement): void;
  key: string;  
  spcontect?:any|null;
}  


export default class propertypanecontrol implements IPropertyPaneField<IPropertyFieldMessageBarPropsInternal> {
  public properties: IPropertyFieldMessageBarPropsInternal;  
  public targetProperty: string;  
  public type: PropertyPaneFieldType = PropertyPaneFieldType.Custom;  
 // private onPropertyChange: (propertyPath: string, oldValue: any, newValue: any) => void;  
  private key: string;  
  private elem: HTMLElement;

  constructor(targetProperty: string,  userproperties: IPropertyFieldMessageBarPropsInternal) {
    this.targetProperty = targetProperty;
    this.render = this.render.bind(this);  
    this.properties = userproperties;  
    this.properties.onDispose = this.dispose;  
    this.properties.onRender = this.render;  
    this.properties.spcontect=userproperties.spcontect;
  //  this.onPropertyChange = userproperties.onPropertyChange;  
    this.key = userproperties.key;  
  }

  public render(elem: HTMLElement): void {
    if (!this.elem) {
      this.elem = elem;
    }
    const element: React.ReactElement<IPropertyFieldMessageBarPropsInternal> = React.createElement(customtext, {  
      onDispose: null,  
      onRender: null,  
      onPropertyChange: this.onChanged.bind(this),
      key: this.key,
      spcontect: this.properties.spcontect 
    });
    ReactDom.render(element, elem);
  }

  private onChanged(selectedusers: any): void {
    this.properties.onPropertyChange(selectedusers);
  }

  private dispose(elem: HTMLElement): void {  
  }
}

export function PropertyPanetextboxcustom(selectedusers:any, onChanged,spcontect?:any|null): IPropertyPaneField<IPropertyPaneCustomFieldProps> { 
  var newProperties: IPropertyFieldMessageBarPropsInternal = {  
    onPropertyChange: onChanged,  
    onDispose: null,  
    onRender: null,  
    key: 'test',
    spcontect:spcontect
  };  
  return new propertypanecontrol(selectedusers,newProperties);  
} 

Web part body react component (PropertyPaneSpFx.tsx)

In this file we creating web parts body part as react component, we used the office UI fabric Persona component to list the selected users 

import * as React from 'react';
import styles from './PropertyPaneSpFx.module.scss';
import { IPropertyPaneSpFxWebPartProps } from '../PropertyPaneSpFxWebPart';
import { escape } from '@microsoft/sp-lodash-subset';
import { Persona } from 'office-ui-fabric-react/lib/Persona';

export default class PropertyPaneSpFx extends React.Component<IPropertyPaneSpFxWebPartProps, {}> {
  public render(): React.ReactElement<IPropertyPaneSpFxWebPartProps> {
    return (
      <div className={ styles.propertyPaneSpFx }>
        <div className={ styles.container }>
          <div className={ styles.row }>
            <div className={ styles.column }>
              <span className={ styles.title }>Welcome to Ravichandran blog!</span>
              <p className={ styles.subTitle }>Seleted Users</p>
                {this.props.selectedusers.map((row, index) => (
                        <Persona {...row}  />
                ))}
            </div>
          </div>
        </div>
      </div>
    );
  }
}

Click below button to redirect Microsoft code galley to download this project

Sharing is caring!

If you have any questions, feel free to let me know in the comments section.
Happy coding!!!

Quick Launch and Top Navigation link programmatically – SharePoint Add In

We can add or remove Quick Launch and Top Navigation link programmatically using SharePoint JavaScript Object Model (JSOM), in this below sample I have added both links for this I have used web.get_navigation().get_topNavigationBar() and web.get_navigation().get_quickLaunch(). You can find the full source code download link in this page,

Source code download link

174https://code.msdn.microsoft.com/Quick-Launch-and-Top-0dbcba8b

get_topNavigationBar

Solution compatibility
This sample is tested with SharePoint Online
This sample also compatible with SharePoint 2013 and SharePoint 2016

To create new project
Open visual studio 2015
On the file menu select New -> Project (Ctrl + Shift + N)
In the New Project window select or search “App for SharePoint”
In the “New App for SharePoint” wizard choose options based on your preferences

Add new “Client Web Part (Host Web)” and select “Create a new app web page for the client web part content”, Edit newly created aspx page which is located in the Pages folder.

Code Flow
I have added four buttons for add and remove both Quick Launch and Top Navigation links, buttons call respective function for do operation. in the page load I got the web object and utilized in button events

After Add or Remove links we have refresh the page for see the changes, in below i have shared both HTML and JavaScript. you can also download complete project.

'use strict';

var context;
var web;
context = SP.ClientContext.get_current();
var hostweburl;
var appweburl;
var appContextSite;

// This code runs when the DOM is ready and creates a context object which is needed to use the SharePoint object model
$(document).ready(function () {
getUrl();
});

// This function get the URL informations
function getUrl() {
hostweburl = getQueryStringParameter("SPHostUrl");
appweburl = getQueryStringParameter("SPAppWebUrl");
hostweburl = decodeURIComponent(hostweburl);
appweburl = decodeURIComponent(appweburl).toString().replace("#", "");
var scriptbase = hostweburl + "/_layouts/15/";
$.getScript(scriptbase + "SP.RequestExecutor.js", execOperation);
}

// This function get list data from SharePoint
function execOperation() {
var factory = new SP.ProxyWebRequestExecutorFactory(appweburl);
context.set_webRequestExecutorFactory(factory);
appContextSite = new SP.AppContextSite(context, hostweburl);
web = appContextSite.get_web();
context.load(web);
context.executeQueryAsync(onGetWebSuccess, onFail);
}

// This function is executed if the above call is successful
function onGetWebSuccess() {
console.log('Hello ' + web.get_title());
}

// This function is executed if the above call fails
function onFail(sender, args) {
console.log('Failed. Error:' + args.get_message());
}

//for adding new link to Quick Launch
function AddQuickLaunchLink() {
var ql = web.get_navigation().get_quickLaunch();
var nnci = new SP.NavigationNodeCreationInformation();
nnci.set_title('My Custom Link');
nnci.set_url('/_layouts/settings.aspx');
nnci.set_asLastNode(true);
ql.add(nnci);
context.load(ql);
context.executeQueryAsync(
function () {
$('#lblmessage').append("QuickLaunch link added successfully...");
}, onFail);
}

//adding new link to Top Navigation
function AddTopNavicationLink() {
var TopNav = web.get_navigation().get_topNavigationBar();
var nnci = new SP.NavigationNodeCreationInformation();
nnci.set_title('My Custom Link');
nnci.set_url('/_layouts/settings.aspx');
nnci.set_asLastNode(true);
TopNav.add(nnci);
context.load(TopNav);
context.executeQueryAsync(
function () {
$('#lblmessage').append("Top Navigation link added successfully...");
console.log("TopNav Added");
}, onFail);
}

//Removing new link to Quick Launch
function RemoreQuickLaunchLink() {
var ql = web.get_navigation().get_quickLaunch();
context.load(ql);
context.executeQueryAsync(
function () {
var e = ql.getEnumerator();
var notFound = true;
while (notFound && e.moveNext()) {
var node = e.get_current();
if (node.get_title() === "My Custom Link") {
node.deleteObject();
notFound = false;
}
}
context.executeQueryAsync(
function () {
$('#lblmessage').append("QuickLaunch link removed successfully...");
console.log("QuickLaunch link removed");
},
onFail);

},
onFail);
}

//removing new link to Top Navigation
function RemoveTopNavicationLink() {
var tn = web.get_navigation().get_topNavigationBar();
context.load(tn);
context.executeQueryAsync(
function () {
var e = tn.getEnumerator();
var notFound = true;
while (notFound && e.moveNext()) {
var node = e.get_current();
if (node.get_title() === "My Custom Link") {
node.deleteObject();
notFound = false;
}
}
context.executeQueryAsync(
function () {
$('#lblmessage').append("Top Navigation link removed successfully...");
console.log("TopNav link removed");
},
onFail);

},
onFail);
}



//This function split the url and trim the App and Host web URLs
function getQueryStringParameter(paramToRetrieve) {
var params =
document.URL.split("?")[1].split("&");
for (var i = 0; i < params.length; i = i + 1) {
var singleParam = params[i].split("=");
if (singleParam[0] == paramToRetrieve)
return singleParam[1];
}
}
<%@ Page Language="C#" Inherits="Microsoft.SharePoint.WebPartPages.WebPartPage, Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>

<%@ Register TagPrefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register TagPrefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register TagPrefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages" Assembly="Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>

<WebPartPages:AllowFraming ID="AllowFraming" runat="server" />

<html>
<head>
<title></title>
<script type="text/javascript" src="../Scripts/jquery-1.9.1.min.js"></script>
 <script type="text/javascript" src="/_layouts/1033/init.js"></script>
<script type="text/javascript" src="/_layouts/15/MicrosoftAjax.js"></script>
 <script type="text/javascript" src="/_layouts/15/sp.runtime.js"></script>
<script type="text/javascript" src="/_layouts/15/sp.js"></script>
 <script type="text/javascript" src="../Scripts/App.js"></script>
	<link href="../Content/bootstrap.min.css" rel="stylesheet" />
<script type="text/javascript">
 // Set the style of the client web part page to be consistent with the host web.
 (function () {
 'use strict';

 var hostUrl = '';
 if (document.URL.indexOf('?') != -1) {
 var params = document.URL.split('?')[1].split('&');
 for (var i = 0; i < params.length; i++) {
 var p = decodeURIComponent(params[i]);
 if (/^SPHostUrl=/i.test(p)) {
 hostUrl = p.split('=')[1];
 document.write('	<link rel="stylesheet" href="' + hostUrl + '/_layouts/15/defaultcss.ashx" />');
 break;
 }
 }
 }
 if (hostUrl == '') {
 document.write('	<link rel="stylesheet" href="/_layouts/15/1033/styles/themable/corev15.css" />');
 }
 })();
 </script>
</head>
<body>
<style>
input {
margin: 10px;
}
</style>
<div style="width: 450px">
<input type="button" id="btnQLAdd" onclick="AddQuickLaunchLink()" value="Add Link to QuickLaunch" />
<input type="button" id="btnQLRemove" onclick="RemoreQuickLaunchLink()" value="Remove Link from QuickLaunch" />
<input type="button" id="btnTopAdd" onclick="AddTopNavicationLink()" value="Add Top Navication Link" />
<input type="button" id="btnTopRemove" onclick="RemoveTopNavicationLink()" value="Remove Top Navication Link" />
</div>
<p id="lblmessage" style="color: green"></p>

</body>
</html>

Please let me know if you have any queries regarding this sample in comments

Souce Code Download link

174https://code.msdn.microsoft.com/Quick-Launch-and-Top-0dbcba8b

 

SharePoint List to JQuery Chart SharePoint Add In

JQuery Chart is easy to implement as a SharePoint Add In, in this sample I have retrieved SharePoint list data and formed it as JSON data and then JSON data object is passed into JQuey chart as input parameter. we can implement various type of chart using JQuery chart for as example bar, circle, line, doughnut, etc,… Here I’m going to explain detail about this SharePoint Add-In implementation.

You can download complete source code from the below URL

174https://code.msdn.microsoft.com/SharePoint-List-to-JQuery-90bfd45f

JQuery Chart SharePoint List

To create new project

Open visual studio 2015

On the file menu select New -> Project (Ctrl + Shift + N)

In the New Project window select or search “App for SharePoint”

In the “New App for SharePoint” wizard choose options based on your preferences

To add new resource file (.js or .css or Images) into project

Select a folder from solution explorer based on your file type (Images or Scripts or Content for CSS)

Right click and select “Open Folder in File Explorer” option

Now paste your files into the folder

Again in the solution explorer window at the top, click “Show All Files” icon

Now you can find the file without active icon, right click and select “Include in Project” Option

Solution compatibility

This sample is tested with SharePoint Online

This sample also compatible with SharePoint 2013 and SharePoint 2016

Code Flow

Fetching Host web URL and App web URL from query string

Host web content created using app web proxy

Retrieved list data from the host web

on the success event, list item collection converted as JSON data using JSON.parse

then the JSON data sent to chart js as parameter

//'use strict';

ExecuteOrDelayUntilScriptLoaded(initializePage, "sp.js");

function initializePage() {
var context = SP.ClientContext.get_current();
var user = context.get_web().get_currentUser();
var hostweburl;
var appweburl;
var appContextSite;
var list;
var listItems;
var web;


// This code runs when the DOM is ready and creates a context object which is needed to use the SharePoint object model
$(document).ready(function () {
getUrl();
});

// This function get the URL informations
function getUrl() {
hostweburl = getQueryStringParameter("SPHostUrl");
appweburl = getQueryStringParameter("SPAppWebUrl");
hostweburl = decodeURIComponent(hostweburl);
appweburl = decodeURIComponent(appweburl).toString().replace("#", "");
var scriptbase = hostweburl + "/_layouts/15/";
$.getScript(scriptbase + "SP.RequestExecutor.js", execOperation);
}

// This function get list data from SharePoint
function execOperation() {
var factory = new SP.ProxyWebRequestExecutorFactory(appweburl);
context.set_webRequestExecutorFactory(factory);
appContextSite = new SP.AppContextSite(context, hostweburl);
web = appContextSite.get_web();
context.load(web);
var camlQuery = new SP.CamlQuery();
list = web.get_lists().getByTitle("Post Reach");
listItems = list.getItems(camlQuery);
context.load(list);
context.load(listItems);
context.executeQueryAsync(onGetSPListSuccess, onGetSPListFail);
}


// This function is executed if the above call is successful
function onGetSPListSuccess() {
$("#DivSPGrid").empty();
var chartlabel = '';
var chartdata1 = '';
var chartdata2 = '';
var barChartData = '';
var listEnumerator = listItems.getEnumerator();
chartlabel = "{\"labels\":[";
chartdata1 = "],\"datasets\":[{" +
"\"fillColor\":\"rgba(220,220,220,0.5)\"," +
"\"strokeColor\":\"rgba(220,220,220,0.8)\"," +
"\"highlightFill\":\"rgba(220,220,220,0.75)\"," +
"\"highlightStroke\":\"rgba(220,220,220,1)\"," +
"\"data\":[";
chartdata2 = "]},{" +
"\"fillColor\":\"rgba(151,187,205,0.5)\"," +
"\"strokeColor\":\"rgba(151,187,205,0.8)\"," +
"\"highlightFill\":\"rgba(151,187,205,0.75)\"," +
"\"highlightStroke\":\"rgba(151,187,205,1)\"," +
"\"data\":[";
while (listEnumerator.moveNext()) {
var listItem = listEnumerator.get_current();
chartlabel += "\"" + listItem.get_item("Title") + "\",";
chartdata1 += listItem.get_item("Facebook") + ",";
chartdata2 += listItem.get_item("Twitter") + ",";
}
chartlabel = chartlabel.replace(/,\s*$/, "");
chartdata1 = chartdata1.replace(/,\s*$/, "");
chartdata2 = chartdata2.replace(/,\s*$/, "");
var str = chartlabel + chartdata1 + chartdata2 + ']}]}';
barChartData = JSON.parse(str);
var ctx = document.getElementById("chartCanvas").getContext("2d");
window.myBar = new Chart(ctx).Bar(barChartData, { responsive: true });
}

// This function is executed if the above call fails
function onGetSPListFail(sender, args) {
alert('Failed to get list data. Error:' + args.get_message());
}

//This function split the url and trim the App and Host web URLs
function getQueryStringParameter(paramToRetrieve) {
var params =
document.URL.split("?")[1].split("&");
for (var i = 0; i < params.length; i = i + 1) {
var singleParam = params[i].split("=");
if (singleParam[0] == paramToRetrieve)
return singleParam[1];
}
}
}
<%-- The following 4 lines are ASP.NET directives needed when using SharePoint components --%>

<%@ Page Inherits="Microsoft.SharePoint.WebPartPages.WebPartPage, Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" MasterPageFile="~masterurl/default.master" Language="C#" %>

<%@ Register TagPrefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register TagPrefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages" Assembly="Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register TagPrefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>

<%-- The markup and script in the following Content element will be placed in the <head> of the page --%>
<asp:Content ContentPlaceHolderID="PlaceHolderAdditionalPageHead" runat="server">
<script type="text/javascript" src="../Scripts/jquery-1.9.1.min.js"></script>
 <SharePoint:ScriptLink Name="sp.js" runat="server" OnDemand="true" LoadAfterUI="true" Localizable="false" />
 <meta name="WebPartPageExpansion" content="full" />

 <!-- Add your CSS styles to the following file -->
 	<link rel="Stylesheet" type="text/css" href="../Content/App.css" />

 <!-- Add your JavaScript to the following file -->
 <script type="text/javascript" src="../Scripts/App.js"></script>
<script type="text/javascript" src="../Scripts/Chart.js"></script>
</asp:Content>

<%-- The markup in the following Content element will be placed in the TitleArea of the page --%>
<asp:Content ContentPlaceHolderID="PlaceHolderPageTitleInTitleArea" runat="server">
SPListItemCollection to JQuery Chart SharePoint Add In
</asp:Content>

<%-- The markup and script in the following Content element will be placed in the <body> of the page --%>
<asp:Content ContentPlaceHolderID="PlaceHolderMain" runat="server">
<div style="width: 50%">
<canvas id="chartCanvas" height="300" width="450"></canvas>
</div>
</asp:Content>

You can download complete source code from the below URL

174https://code.msdn.microsoft.com/SharePoint-List-to-JQuery-90bfd45f

Hope you find this article helpful, check out my other articles too.
Like my Facebook page to get future articles notification
Let me know your Queries and feedback in comments

Notification and Status messages SharePoint Add In

Introduction
There are multiple ways we can show notifications or status from SharePoint Add In, in this article we can find more detail about SharePoint Out of box notification, status and JQuery notification implementation logic

You can download complete source code from the below URL

zip_iconhttps://code.msdn.microsoft.com/Notification-and-Status-34bd280f

Solution compatibility
This sample is tested with SharePoint Online
This sample also compatible with SharePoint 2013 and SharePoint 2016

To create new project
Open visual studio 2015
On the file menu select New -> Project (Ctrl + Shift + N)
In the New Project window select or search “App for SharePoint”
In the “New App for SharePoint” wizard choose options based on your preferences

To add new resource file (.js or .css or Images) into project
Select a folder from solution explorer based on your file type (Images or Scripts or Content for CSS)
Right click and select “Open Folder in File Explorer” option
Now paste your files into the folder
Again in the solution explorer window at the top, click “Show All Files” icon
Now you can find the file without active icon, right click and select “Include in Project” Option

main notification

In the aspx page I have added six buttons and one text box to execute this sample and “notify.min.js” file added into project and refereed as script file reference.

<%-- The following 4 lines are ASP.NET directives needed when using SharePoint components --%>

<%@ Page Inherits="Microsoft.SharePoint.WebPartPages.WebPartPage, Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" MasterPageFile="~masterurl/default.master" Language="C#" %>

<%@ Register TagPrefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register TagPrefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages" Assembly="Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register TagPrefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>

<%-- The markup and script in the following Content element will be placed in the <head> of the page --%>
<asp:Content ContentPlaceHolderID="PlaceHolderAdditionalPageHead" runat="server">
<script type="text/javascript" src="../Scripts/jquery-1.9.1.min.js"></script>
 <SharePoint:ScriptLink Name="sp.js" runat="server" OnDemand="true" LoadAfterUI="true" Localizable="false" />
 <meta name="WebPartPageExpansion" content="full" />

 <!-- Add your CSS styles to the following file -->
 	<link rel="Stylesheet" type="text/css" href="../Content/App.css" />

 <!-- Add your JavaScript to the following file -->
 <script type="text/javascript" src="../Scripts/App.js"></script>
<script type="text/javascript" src="../Scripts/notify.min.js"></script>
</asp:Content>

<%-- The markup in the following Content element will be placed in the TitleArea of the page --%>
<asp:Content ContentPlaceHolderID="PlaceHolderPageTitleInTitleArea" runat="server">
Notification and Status messages SharePoint Add In
</asp:Content>

<%-- The markup and script in the following Content element will be placed in the <body> of the page --%>
<asp:Content ContentPlaceHolderID="PlaceHolderMain" runat="server">
<div id="divNotification">
<input type="button" name="btnAddNotification" id="btnAddNotification" value="Add Notification" />
</div>
<div id="divStatus">
<input type="button" name="btnAddStatus" id="btnAddStatus" value="Add Status" />
<input type="button" name="btnModifyStatus" id="btnModifyStatus" value="Modify Status" />
<input type="button" name="btnStatusColour" id="btnStatusColour" value="Change Status Colour" />
<input type="button" name="btnRemoveStatus" id="btnRemoveStatus" value="Remove Status" />
</div>
<div id="divJQueryStatus">
<input type="button" name="btnAddStatus" id="btnJQueryStatus" value="Add Status" />
</div>
<input type="text" id="txtName" value="" />

</asp:Content>

In the App.js file (which is located under scripts folder) cleanup all unnecessary code, and using css selector select buttons and write functions inside click event.

SharePoint Out of Box Status 

SP.UI.Status class provides methods for managing status messages. while we pass the color name as parameter to methods use lower case, Ex: red, green… if you pass it as “Red” then JavaScript won’t recognize it,because JavaScript is case sensitive.

SharePoint Out of Box Notification

SP.UI.Notify calss provides methods for managing notifications, we can pass notification message as HTML and by default, notifications appear for five seconds also we have option to adjusting this time

JQuery Notification

Notify.min.js used for JQuery notification, we can get extreme level of flexibility when we use JQuery notification also it is very simple to call with varies parameter. We can call any corner of the window or any side of the element

'use strict';

ExecuteOrDelayUntilScriptLoaded(initializePage, "sp.js");

function initializePage() {

//This function creates a new notification on your this Add-In
$('#btnAddNotification').click(function () {
//The message inside the notification.
var strHtml = "<img width='15px' src=\"../Images/loading.gif\" /> Loading <b>please wait...</b>";
//Specifies whether the notification stays on the page until removed.
var bSticky = false;
//Adds a notification to the page. By default, notifications appear for five seconds.
SP.UI.Notify.addNotification(strHtml, bSticky);
});
//The ID of the status to update.
var spstatus;
//this function Adds a status message to the Add-in page.
$('#btnAddStatus').click(function () {
//The title of the status message.
var strTitle = "SPTECHNET";
//The contents of the status message.
var strHtml = "New Status <b>massage</b>";
//Specifies whether the status message will appear at the beginning of the list.
var atBegining = true;
spstatus = SP.UI.Status.addStatus(strTitle, strHtml, atBegining);
//The color to set for the status message.
SP.UI.Status.setStatusPriColor(spstatus, "green");
});

$('#btnModifyStatus').click(function () {
//The new status message.
var strHtml = "Modified Status <b>massage</b>";
//Updates the specified status message.
SP.UI.Status.updateStatus(spstatus, strHtml);
//The color to set for the status message.
SP.UI.Status.setStatusPriColor(spstatus, "blue");
});

$('#btnStatusColour').click(function () {
var strColor = "red";
//The color to set for the status message.
SP.UI.Status.setStatusPriColor(spstatus, strColor);
});

$('#btnRemoveStatus').click(function () {
//Removes all status messages from the page.
SP.UI.Status.removeAllStatus(true);
});

$('#btnJQueryStatus').click(function () {
//Show JQuery status messages from the page.
$.notify("Access granted", "success");
$.notify("Warning: Self-destruct in 3.. 2..", "warn");
$('#txtName').notify("This field is required", "info");
$.notify("BOOM!", {
// whether to hide the notification on click
clickToHide: true,
// whether to auto-hide the notification
autoHide: false,
// if autoHide, hide after milliseconds
autoHideDelay: 5000,
// show the arrow pointing at the element
arrowShow: true,
// arrow size in pixels
arrowSize: 5,
// position defines the notification position though uses the defaults below
position: 'top right',
// default positions
elementPosition: 'top right',
globalPosition: 'top right',
// default style
style: 'bootstrap',
// default class (string or [string])
className: 'error',
// show animation
showAnimation: 'slideDown',
// show animation duration
showDuration: 400,
// hide animation
hideAnimation: 'slideUp',
// hide animation duration
hideDuration: 200,
// padding between element and notification
gap: 2
});
});
}

You can download complete source code from the below URL

zip_iconhttps://code.msdn.microsoft.com/Notification-and-Status-34bd280f

Hope you find this article helpful, check out my other articles too.
Like my Facebook page to get future articles notification
Let me know your Queries and feedback in comments