Within this series of posts I will go through the following steps:
- Displaying SharePoint data in the SPFx web part
- Creating a clickable zone within the web part
- Creating a form in an SPFx web part
- Displaying status update within the SPFx Web part
- Saving data from a form to SharePoint
- Updating fields within SharePoint (including choice, people, date and text fields)
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 going 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 https://sharepains.com/2017/06/06/office-365-sharepoint-spfx-creating-a-clickable-zone 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. 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.
First of all, I would like to thank you for this series! I really learned a lot from your posts about this topic and it was awesome to have followed you during this tutorial, I really learned a lot today!
Here is a feedback if you don’t mind me saying, I really tried to reproduce this code on my own and I think some instructions or code is missing from Step 1 to Step 2, I really tried to piece everything together but I can’t put all together, and I tried many times but I’m still new to this and I can’t get this around my head, Would you consider sharing the source code? I really wanted to learn this.
Again, thank you very much for the help!
Thank you for your comment. I’m glad that my posts have been helpful. Unfortunately I can’t share the full code as it was related to customer work, hence I couldn’t include a download the full code link. I am however happy to help you make things work. How far did you get things to work? Did yo manage to get the classes for Forms and Fields to work?