S H A R E P O I N T C E N T E R

در این آموزش می‌خواهیم فرم شیرپوینت سفارشی با استفاده از SPFx (بدون فریم ورک جاوا اسکریپت) ایجاد کنیم.


پیش‌نیازهای سیستم:

  • Node .js
  • Npm package manager
  • Yeoman and gulp

محیط را نصب و راه اندازی کنید و سپس پروژه خود را ایجاد کنید.

  • پوشه پروژه ایجاد کنید

md TestForm

  • به پوشه پروژه بروید

cd TestForm

  • با اجرای Yeoman SharePoint Generator یک web part جدید ایجاد کنید

yo @microsoft/SharePoint

  • هنگامی که از شما خواسته شد، به صورت زیر انتخاب/پر کنید:

1

  • سپس yeoman کمی زمان نیاز دارد تا پروژه را (بسته به connection speed) راه اندازی کند.
  • هنگامی که پروژه با موفقیت راه اندازی شد، باید صفحه ای مشابه تصویر زیر مشاهده کنید:

2

  • اکنون می توانید از هر ویرایشگر کد دلخواه خود برای ویرایش کد webpart استفاده کنید. من ترجیح می دهم از Visual Studio Code برای این منظور استفاده کنم.
  • gulp dev certificate را نصب کنید (این کار فقط یک بار باید در سیستم شما انجام شود)

gulp trust-dev-cert

  • پس از نصب dev certificate، موارد زیر را برای راه اندازی یک local node server با نمونه ای از SharePoint workbench برای استقرار و پیش نمایش webpart اجرا کنید.

gulp serve

3

  • پس از آماده شدن workbench، روی دکمه Add کلیک کنید تا لیست webparts های موجود باز شود و web part خود را برای افزودن به صفحه انتخاب کنید.

4

  • اضافه کردن Webpart برای پیش نمایش صفحه

5

  • برای باز کردن webpart برای پیش‌نمایش مستقیم در SharePoint tenant، به این آدرس بروید:

https://<<Sharepoint site URL>>/_layouts/15/workbench.aspx

با این کار نمونه‌ای از SharePoint workbench مانند نمونه بالا باز می‌شود و می‌توانید webpart خود را در آنجا اضافه کنید تا مستقیماً با لیست‌ها و کتابخانه‌های شیرپوینت در ارتباط باشد. اما بر خلاف local workbench که هر بار که کد صفحه تغییر می کند به طور خودکار رفرش می شود (به خاطر داشته باشید که gulp serve باید در حال اجرا باشد)، SharePoint workbench باید به صورت دستی رفرش شود تا تغییرات مشاهده شوند.

6

  • بیایید سفارشی‌سازی webpart خود را شروع کنیم.

تست نیازمندی‌های Webpart:

  • فرم سفارشی
  • Textbox برای نام فعالیت
  • Date picker برای تاریخ فعالیت
  • People picker control برای انتخاب کاربر اختصاص داده شده با فعالیت
  • 2 dropdown برای انتخاب دسته و زیر دسته

سفارشی کردن webpart :

  • solution را با استفاده از Visual Studio Code باز کنید:
  • نمیخواهیم جزئیات ساختار solution و ... را بررسی کنیم. جزئیات در آن مورد را می توان اینجا یافت.
  • برای webpart ما از jQuery، Bootstrap (برای رابط کاربری) و sp-pnp.js برای تعامل با لیست های شیرپوینت استفاده خواهیم کرد.
  • sp-pnp.js را با استفاده از دستور زیر نصب کنید:

npm install sp-pnp-js –save

  • Jquery را با استفاده از دستور زیر نصب کنید:

npm install –save @types/jquery@3 -D

  • موارد زیر را نیز برای webpart نیاز داریم:
    • peoplepicker.js و سایر فایل های مورد نیاز از اینجا
    • Jquery-ui از اینجا
    • یک پوشه برای css و یک پوشه‌ی دیگر برای اسکریپت‌ها در آدرس src/webparts/testform ایجاد کنید و همه فایل‌های css و js را در پوشه‌های مربوطه کپی کنید.

7

هنگامی که پروژه برای توزیع ساخته می شود، این دایرکتوری‌ها و فایل‌ها به طور خودکار در lib تحت hierarchy مشابه کپی می شوند.

از قسمت config، config.json را باز کنید و موارد زیر را در externals attribute اضافه کنید:

"externals": {
"jquery": {
"path": "https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js",
"globalName": "jquery"
},
"bootstrap": {
"path": "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js",
"globalName": "bootstrap",
"globalDependencies": ["jquery"]
},
"appjs": {
"path": "lib/webparts/testForm/scripts/app.js",
"globalName": "appjs"
},
"sppeoplepicker": {
"path": "lib/webparts/testForm/scripts/sp.peoplepicker.js",
"globalName": "sppeoplepicker"
},
"jqueryui": {
"path": "lib/webparts/testForm/scripts/jquery-ui.js",
"globalName": "jqueryui"
}
}

8

  • اگر gulp serve در حال اجرا است، متوقف و مجدداً راه اندازی کنید زیرا هر تغییری در config.json نیاز به اجرای مجدد gulp serve دارد.
  • فایل TestFormWebPart.ts را از آدرس src/webparts/testForm باز کنید و خطوط زیر را برای وارد کردن وابستگی‌های مختلف اضافه کنید:

import { SPComponentLoader } from '@microsoft/sp-loader';
import pnp, { sp, Item, ItemAddResult, ItemUpdateResult, Web } from 'sp-pnp-js';
import * as $ from 'jquery';
require('bootstrap');
require('./css/jquery-ui.css');
let cssURL = "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css";
SPComponentLoader.loadCss(cssURL);
SPComponentLoader.loadScript("https://ajax.aspnetcdn.com/ajax/4.0/1/MicrosoftAjax.js");
require('appjs');
require('sppeoplepicker');
require('jqueryui');

  • همچنین در صورت نیاز، import کتابخانه sp-core را برای واکشی پارامترهای URL تغییر دهید:

import { UrlQueryParameterCollection, Version } from '@microsoft/sp-core-library';

  • متد render را با موارد زیر Overwrite کنید:

public render(): void {
this.domElement.innerHTML = `
<div id="container" class="container">

<div class="panel">
<div class="panel-body">
<div class="row">
<div class="col-lg-4 control-padding">
<label>Activity</label>
<input type='textbox' name='txtActivity' id='txtActivity' class="form-control" value="" placeholder="" >
</div>
<div class="col-lg-4 control-padding">
<label>Activity Performed By</label>

<div id="ppDefault"></div>
</div>
<div class="col-lg-4 control-padding">
<label>Activity Date</label>
<div class="input-group date" data-provide="datepicker">
<input type="text" class="form-control" id="txtDate" name="txtDate">
</div>
</div>
</div>

<div class="row">
<div class="col-lg-6 control-padding">
<label>Category</label>
<select name="ddlCategory" id="ddlCategory" class="form-control">

</select>
</div>
<div class="col-lg-6 control-padding">
<label>Sub Category</label>
<select name="ddlSubCategory" id="ddlSubCategory" class="form-control">

</select>
</div>
</div>

<div class="row">
<div class="col col-lg-12">
<button type="button" class="btn btn-primary buttons" id="btnSubmit">Save</button>
<button type="button" class="btn btn-default buttons" id="btnCancel">Cancel</button>
</div>
</div>

</div>
</div>`;

(<any>$("#txtDate")).datepicker(
{
changeMonth: true,
changeYear: true,
dateFormat: "mm/dd/yy"
}
);
(<any>$('#ppDefault')).spPeoplePicker({
minSearchTriggerLength: 2,
maximumEntitySuggestions: 10,
principalType: 1,
principalSource: 15,
searchPrefix: '',
searchSuffix: '',
displayResultCount: 6,
maxSelectedUsers: 1
});
this.AddEventListeners();
this.getCategoryData();

}

در متد render کد زیر datepicker control را مقداردهی اولیه می کند:

(<any>$("#txtDate")).datepicker(
{
changeMonth: true,
changeYear: true,
dateFormat: "mm/dd/yy"
}
);

و کد زیر people picker را مقداردهی اولیه می کند:

(<any>$('#ppDefault')).spPeoplePicker({
minSearchTriggerLength: 2,
maximumEntitySuggestions: 10,
principalType: 1,
principalSource: 15,
searchPrefix: '',
searchSuffix: '',
displayResultCount: 6,
maxSelectedUsers: 1
});

توجه داشته باشید که من قبل از مقداردهی اولیه هر دو کنترل از <any> استفاده کرده ام، زیرا در SPFx اگر بخواهیم کنترل‌ها را بدون <any> مقداردهی اولیه کنیم، با خطای "method not found" مواجه خواهیم شد.

  • برای افزودن event listeners به کنترل‌ها، متد AddEventListeners را پیاده‌سازی کنید:

private AddEventListeners(): any {
document.getElementById('btnSubmit').addEventListener('click', () => this.SubmitData());
document.getElementById('btnCancel').addEventListener('click', () => this.CancelForm());
document.getElementById('ddlSysWorked').addEventListener('change', () => this.PopulateSubCategory());
}

  • متد getCategoryData را برای پر کردن category dropdown از لیست اصلی پیاده سازی کنید.

private _getCategoryData(): any {
return pnp.sp.web.lists.getByTitle("Category").items.select("Category").getAll().then((response) => {
return response;
});
}

private getCategoryData(): any {
this._getCategoryData()
.then((response) => {
this._renderCategoryList(response);
});
}

private _renderCategoryList(items: any): void {

let html: string = '';
html += `<option value="Select Category" selected>Select Category</option>`;
items.forEach((item: any) => {
html += `
<option value="${item.Category}">${item.Category}</option>`;
});
const listContainer1: Element = this.domElement.querySelector('#ddlCategory');
listContainer1.innerHTML = html;
}

  • در change event of category باید subcategory dropdown control را با مقادیر لازم از لیست اصلی پر کنید. برای فراخوانی متد ()PopulateSubCategory، change listener را در category dropdown اضافه کرد.

public PopulateSubCategory() {
this.getSubCategoryData($("#ddlCategory").val().toString());
}

private _getSubCategoryData(category): any {
return pnp.sp.web.lists.getByTitle("SubCategory").items.select("SubCategory").filter("Category eq '" + category + "'").getAll().then((response) => {
return response;
});
}

private getSubCategoryData(category): any {
this._getSubCategoryData(category)
.then((response) => {
this._renderSubCategoryList(response);
});
}

private _renderSubCategoryList(items: any): void {

let html: string = '';
html += `<option value="Select Sub Category" selected>Select Sub Category</option>`;
items.forEach((item: any) => {
html += `
<option value="${item.SubCategory}">${item.SubCategory}</option>`;
});
const listContainer1: Element = this.domElement.querySelector('#ddlSubCategory');
listContainer1.innerHTML = html;
}

 

  • اکنون که فرم ایجاد شده و با کنترل‌ها مقداردهی اولیه شده است، باید عملکردهای ارسال(Submit) و لغو(Cancel) را اجرا کنید.
  • برای پیاده سازی Cancel، URL را از جایی که این صفحه باز شده است می خوانیم، Source attribute را جستجو می کنیم و صفحه را به آنجا هدایت می کنیم.

private CancelForm() {
window.location.href = this.GetQueryStringByParameter("Source");
}

private GetQueryStringByParameter(name) {
name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
results = regex.exec(location.search);
return results == null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
}

  • در نهایت، اجازه دهید عملکرد Submit را پیاده سازی کنیم و داده‌ها را در لیست شیرپوینت ذخیره کنیم.

private SubmitData(){
var userinfo = (<any>$('#ppDefault')).spPeoplePicker('get');
var userId;
var userDetails = this.GetUserId(userinfo[0].email.toString());
console.log(JSON.stringify(userDetails));
userId = userDetails.d.Id;

pnp.sp.web.lists.getByTitle('RigActiveList_Job_Cards_Area').items.add({
Title: "Test",
Activity: $("#txtActivity").val().toString(),
Activity_Date: $("#txtDate").val().toString(),
Activity_ById : userId,
Category: $("#ddlCategory").val().toString(),
SubCategory: $("#ddlSubCategory").val().toString(),
});
}
private GetUserId(userName) {
var siteUrl = this.context.pageContext.web.absoluteUrl;

var call = $.ajax({
url: siteUrl + "/_api/web/siteusers/getbyloginname(@v)?@v=%27i:0%23.f|membership|" + userName + "%27",
method: "GET",
headers: { "Accept": "application/json; odata=verbose" },
async: false,
dataType: 'json'
}).responseJSON;
return call;
}

توجه داشته باشید که ما از یک روش GetUSerID جداگانه استفاده کرده ایم. sp.peoplepicker.js control یک شی userinfo را برمی گرداند و شناسه کاربر انتخاب شده را برنمی‌گرداند. اما برای ذخیره کاربر به عنوان یک شخص یا شی گروه در لیست شیرپوینت، به شناسه نیاز داریم. بنابراین شی userinfo را به متد GetUserId ارسال می کنیم و شناسه را برای ذخیره به لیست شیرپوینت برمی گردانیم.

این طرح نهایی فرم است:

9

به این ترتیب توانستیم اولین SPFx webpart خود را راه‌اندازی و اجرا کنیم.

مطالب مرتبط

ارسال دیدگاه

آخرین نوشته ها