Within this series of posts I will go through the following steps:

 

In my past view posts I’ve looked atcreating an SPFx web part that displays a form for users to fill in. This post will describe the creation of the actual form.

I’m going to have a look at forms that can handle the following types of data:

  • Text Fields
  • Date Fields
  • People Fields
  • Drop down fields

SharePoint offers quite a few more field types, but for now I’m only looking at the above fields.

As an end result I want to get a form that looks a bit like this:

So first things first I’m going to create some files within my project. starting with a new folder so that I can keep all my forms related work separate. I called this folder Controls.

Within this folder I added a file called forms.ts. This file will contain a class that holds the code for my form.

Then I’m creating a file called formControl.ts, which will hold the parent class for all other controls.

Then for the TextControl, DateControl and DropDown control I’m adding a separate typescript file for each. Finally the PeopleDropdown will be added. The PeopleDropdown (or people picker) will be inheriting some code from the basic drop down class.

For now I’m goiong to ignore the styling files (form.module.scss and form.module.scss.ts). Although not unimportant I will not look at these for now as it would make the base form solution harder to describe.

So now all my files exist. Time to get some coding done.

Form.ts

I’m going to start with creating a form class

export default class Form {

}

Then I’m adding a private variable that will hold information about all the controls on the form by adding the following line inside the form class:

private _controls: FormControl[] = [];

Further down this post I will describe the FromControl class.

There are a few methods that we will need to create:

  • addControl
  • render
  • closeForm

addControl

To add a control to the form all we need to do is take a control and add it to the form.

public addControl(control: FormControl) {
this._controls[this._controls.length] = control;
}

Nice and easy. This means that within our web part class all we need to do is create a new form object and then add the controls and the render method of the form can then display each of the controls on the form.

render

As each of the controls will its own way of rendering itself the render method of the form can remain quite simple. All we would need to display s the form’s html and then call a render function for each control. For each control to find it’s location on the form however we would need to tell the control where its location is. Do do this we will use a placeholder name for the control. As found later in this post each Control has a PlaceHolder property.

So the render of the form will just render placeholders for now.

public render() {
let html = `< div class="${styles.bidEditFormOverlay}" id="${this.cssId}">
< div class="${styles.bidEditForm}" id="${this.cssId}">
< div class="${styles.savebutton}" id="bidEditFormSave">Save< /div>
< div class="${styles.bidEditFormTitle}">${this.formTitle}

<span id="bidEditFormClose" class="${styles.bidEditFormClose}">< /span>< /div>`;

<strong>    this._controls.forEach((control: FormControl) => {</strong>
<strong>             if (this.placeHolder[0] == '.') {</strong>
<strong>                   let className = control.placeHolder.replace('.', '');</strong>
<strong>                   html += `</strong>
<div id="${this.cssId}" class="${className}">loading ${control.placeHolder}</div>
`;
<strong>              } else {</strong>
<strong>                  let id = control.placeHolder.replace('#', '');</strong>
<strong>                   html += `</strong>
<div id="${id} ${this.cssId}">loading ${control.placeHolder}</div>
`;
<strong>             }</strong>
<strong>     });</strong>

html += ` < /div>
< /div>`;

const formContainer: Element = document.querySelector(this.placeHolder);
formContainer.innerHTML = html;

}

The above will result in a from that just has placeholders, but of course we want our controls to appear rather than the placeholder text saying "Loading …".

To do this the following 3 lines are needed at the end of my form's render method:

this._controls.forEach((control: FormControl) => {
control.render();
});

That's it. My form is rendering, however I can't close my form yet.

Like described in my <a href="https://veenstra.me.uk/2017/06/06/office-365-sharepoint-spfx-creating-a-clickable-zone/">Create a clickable Zone post</a> I'm adding another event to my form:

var Form: Element = document.querySelector(`#bidEditFormClose`);

Form.addEventListener('click', (evt: Event) => {
this.closeForm();
}, false);

Ok, that is the form created. Next step is creating the different controls, which will be in part 2 of this series of posts

 

I have based this series of posts on some of the work I’ve done for my customers at Triad Group Plc. At Triad we have been looking at the new SharePoint framework since the early releases. If you would like to help us getting you started with SPFx then please feel free to contact me below.

Advertisements