Skip to content

Commit bbdbc54

Browse files
committed
Added custom dialog tutorial under extensions
1 parent 902af15 commit bbdbc54

10 files changed

+229
-7
lines changed

docs/spfx/extensions/guidance/using-custom-dialogs-with-spfx.md

Lines changed: 226 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
# Using Custom Dialogs with SharePoint Framework Extensions
22

3-
Introduction
3+
Custom dialogs are available from `@microsoft/sp-dialog`package and can be used within the context of SharePoint Framework Extensions or client-side web parts.
44

5-
Dialog is also avaialble for web parts.
5+
This tutorial demonstrates creation of a custom dialog and using that in the context of ListView Command Set extension.
66

77
> Notice that the SharePoint Framework dialog is currently in preview status and we are looking to collect feedback before it's officially released. Please provide us feedback by using the [sp-dev-docs repository Issue list](https://github.com/SharePoint/sp-dev-docs/issues).
88
9+
> Notice that debugging Custom ListView Sets in the SharePoint Online is currently only available from modern list experience in classic team sites hosted on dev tenant.
10+
11+
> End result of this tutorial is also available as source code at https://github.com/SharePoint/sp-dev-fx-extensions/tree/master/samples/react-command-dialog.
12+
913
## Setup your Environment
1014

1115
Before you can complete this guide you will need to ensure you have [setup your environment](https://dev.office.com/sharepoint/docs/spfx/set-up-your-development-environment) for development
@@ -44,17 +48,232 @@ The next set of prompts will ask for specific information about your extension:
4448
* Accept the default value of **DialogDemo** as your extension name and press **Enter**.
4549
* Accept the default value of **DialogDemo description** as your extension description and press **Enter**.
4650

47-
![Yeoman SharePoint generator prompts to create an extension solution](../../../../images/ext-com-yeoman-prompts.png)
51+
![Yeoman SharePoint generator prompts to create an extension solution](../../../../images/ext-com-dialog-yeoman-prompts.png)
4852

49-
At this point, Yeoman will install the required dependencies and scaffold the solution files along with the **HelloWorld** extension. This might take a few minutes.
53+
At this point, Yeoman will install the required dependencies and scaffold the solution files along with the *HelloWorld* extension. This might take a few minutes.
5054

5155
When the scaffold is complete, you should see the following message indicating a successful scaffold:
5256

53-
![SharePoint client-side solution scaffolded successfully](../../../../images/ext-com-yeoman-complete.png)
57+
![SharePoint client-side solution scaffolded successfully](../../../../images/ext-com-dialog-yeoman-complete.png)
5458

5559
For information about troubleshooting any errors, see [Known issues](../basics/known-issues).
5660

57-
Once the solution scaffolding is completed, type the following into the console to start Visual Studio Code.
61+
Once the scaffolding completes, open your project folder in your code editor. This article uses Visual Studio Code in the steps and screenshots but you can use any editor you prefer.
62+
63+
```
64+
code .
65+
```
66+
67+
![Initial Visual Studio Code structure after scaffolding](../../../../images/ext-com-dialog-vs-code-initial.png)
68+
69+
## Modify extension manifest based on requirements
70+
71+
In the extension manifest, configure extension to have only one button. In the code editor, open the **./src/extensions/dialogDemo/DialogDemoCommandSet.manifest.json** file. Replace the commands section with the following JSON:
72+
73+
```json
74+
{
75+
//...
76+
"commands": {
77+
"COMMAND_1": {
78+
"title": "Open Custom Dialog",
79+
"iconImageUrl": "icons/request.png"
80+
}
81+
}
82+
}
83+
84+
```
85+
86+
## Adding sp-dialog package to solution
87+
Return to the console and execute the following command to include the dialog API in our solution.
88+
89+
```
90+
npm install @microsoft/sp-dialog --save
91+
```
92+
93+
Since we are using the `--save` option, this dependency will be added to *package.json* file and would be automatically installed when `npm install` command is executed.
94+
95+
Return to Visual Studio Code (or your preferred editor).
96+
97+
## Creating your custom dialog
98+
Create a new file called **ColorPickerDialog.tsx** to **./src/extensions/dialogDemo/** folder.
99+
100+
Add following import statements on the start of the newly created file. We are creating our custom dialog using Office UI Fabric React components, so the implementation will be in React.
101+
102+
> Notice that currently DialogContent component is coming from `@microsoft/sp-dialog`, but will be included in Office UI Fabric React components soon, like mentioned in the code comments.
103+
104+
```ts
105+
import * as React from 'react';
106+
import * as ReactDOM from 'react-dom';
107+
import { BaseDialog, IDialogConfiguration } from '@microsoft/sp-dialog';
108+
import {
109+
autobind,
110+
ColorPicker,
111+
PrimaryButton,
112+
Button,
113+
DialogFooter
114+
// DialogContent <- This should be imported here for third parties
115+
} from 'office-ui-fabric-react';
116+
// Note: DialogContent is available in v2.32.0 of office-ui-fabric-react
117+
// As a workaround we're importing it from sp-dialog until the next version bump
118+
import { DialogContent } from '@microsoft/sp-dialog';
119+
```
120+
121+
Add following interface definition just below the import statements. This wil be used to bypass needed information and functions between the ListView Command Set extension and custom dialog.
122+
123+
```ts
124+
interface IColorPickerDialogContentProps {
125+
message: string;
126+
close: () => void;
127+
submit: (color: string) => void;
128+
defaultColor?: string;
129+
}
130+
```
131+
132+
Add following class just below the interface definition. This React class is responsible for rendering the UI experiences inside of the custom dialog. Notice that we use the Office UI Fabric React components for actual rendering and just bypass the needed properties.
133+
134+
```ts
135+
class ColorPickerDialogContent extends React.Component<IColorPickerDialogContentProps, {}> {
136+
private _pickedColor: string;
137+
138+
constructor(props) {
139+
super(props);
140+
// Default Color
141+
this._pickedColor = props.defaultColor || '#FFFFFF';
142+
}
143+
144+
public render(): JSX.Element {
145+
return <DialogContent
146+
title='Color Picker'
147+
subText={this.props.message}
148+
onDismiss={this.props.close}
149+
showCloseButton={true}
150+
>
151+
<ColorPicker color={this._pickedColor} onColorChanged={this._onColorChange} />
152+
<DialogFooter>
153+
<Button text='Cancel' title='Cancel' onClick={this.props.close} />
154+
<PrimaryButton text='OK' title='OK' onClick={() => { this.props.submit(this._pickedColor); }} />
155+
</DialogFooter>
156+
</DialogContent>;
157+
}
158+
159+
@autobind
160+
private _onColorChange(color: string): void {
161+
this._pickedColor = color;
162+
}
163+
}
164+
```
165+
Add following class definition for our custom dialog under the just added class code. This one is the actual custom dialog, which will be called from the button click and which is inherited from the **BaseDialog**.
166+
167+
```ts
168+
export default class ColorPickerDialog extends BaseDialog {
169+
public message: string;
170+
public colorCode: string;
171+
172+
public render(): void {
173+
ReactDOM.render(<ColorPickerDialogContent
174+
close={ this.close }
175+
message={ this.message }
176+
defaultColor={ this.colorCode }
177+
submit={ this._submit }
178+
/>, this.domElement);
179+
}
180+
181+
public getConfig(): IDialogConfiguration {
182+
return {
183+
isBlocking: false
184+
};
185+
}
58186

187+
@autobind
188+
private _submit(color: string): void {
189+
this.colorCode = color;
190+
this.close();
191+
}
192+
}
59193
```
60-
code .
194+
195+
## Associating custom dialog to button click
196+
To associate the custom dialog button to custom ListView Command Set, the code to initiate the dialog has to be added for the button click operation.
197+
198+
In the code editor, open the **DialogDemoCommandSet.ts** file from **./src/extensions/dialogDemo/** folder.
199+
200+
Add following import statements under the existing **strings** import. These are for using the just created custom dialog in the context of ListView Command Set.
201+
202+
```ts
203+
import { Dialog } from '@microsoft/sp-dialog';
204+
import ColorPickerDialog from './ColorPickerDialog';
205+
```
206+
207+
Add following **_colorCode** variable definition above **onInit** function in the **DialogDemoCommandSet** class. This is used to store teh color picker dialog result.
208+
209+
```ts
210+
private _colorCode: string;
211+
```
212+
213+
Update the **onExecute** function as follows. In this code we are doing following steps
214+
215+
* Initiate custom dialog
216+
* Bypass message for the dialog, which will be used as title
217+
* Bypass color code for the dialog with default value, if not yet set
218+
* Show the custom dialog
219+
* Receive and store return value from the dialog
220+
* Show received value in out-of-the-box dialog using `Dialog.alert()` function
221+
222+
```ts
223+
@override
224+
public onExecute(event: IListViewCommandSetExecuteEventParameters): void {
225+
switch (event.commandId) {
226+
case 'COMMAND_1':
227+
const dialog: ColorPickerDialog = new ColorPickerDialog();
228+
dialog.message = 'Pick a color:';
229+
// Use 'EEEEEE' as the default color for first usage
230+
dialog.colorCode = this._colorCode || '#EEEEEE';
231+
dialog.show().then(() => {
232+
this._colorCode = dialog.colorCode;
233+
Dialog.alert(`Picked color: ${dialog.colorCode}`);
234+
});
235+
break;
236+
default:
237+
throw new Error('Unknown command');
238+
}
239+
}
240+
```
241+
242+
## Testing custom dialog in your tenant
243+
Move to **DialogDemoCommandSet.manifest.json** file in **./src/extensions/dialogDemo/** folder and copy **id** value, which will be used in the debug query parameter.
244+
245+
Move to console side and execute following command. We use `--nobrowser` option, since local workbench cannot be currently used for debugging, so there's no reason to start that.
246+
247+
```sh
248+
gulp serve --nobrowser
249+
```
250+
251+
This will start bundling and will serve the resulting manifest from `localhost` address.
252+
253+
![Initial Visual Studio Code structure after scaffolding](../../../../images/ext-com-dialog-gulp-serve.png)
254+
255+
To test your extension, navigate to a site in your SharePoint Online tenant.
256+
257+
Move to an existing custom list in the site with some items or create a new list and add few items to it for testing purposes.
258+
259+
Append the following query string parameters to the URL. Notice that you will need to update the **id** to match your own extension identifier available from the **DialogDemoCommandSet.manifest.json** file:
260+
261+
```
262+
?loadSpfx=true&debugManifestsFile=https://localhost:4321/temp/manifests.js&customActions={"8701f44c-8c81-4e54-999d-62763e8f34d2":{"___location":"ClientSideExtension.ListViewCommandSet.CommandBar"}}
263+
```
264+
265+
Accept the loading of Debug Manifests by clicking **Load debug scripts** when prompted:
266+
267+
![Allow debug scripts warning](../../../../images/ext-com-dialog-debug-scripts.png)
268+
269+
Notice new button being visible in the toolbar of the list with test *Open Custom Dialog*.
270+
271+
![Allow debug scripts warning](../../../../images/ext-com-dialog-button-in-toolbar.png)
272+
273+
Click *Open Custom Dialog* button to see custom dialog rendered in the list view.
274+
275+
![Allow debug scripts warning](../../../../images/ext-com-dialog-visible-dialog.png)
276+
277+
Choose a color in the *Color Picker* and click **OK** to test how the code is returning selected value back to caller, which is then shown using out-of-the-box alert dialog.
278+
279+
![Out-of-the-box alert dialog](../../../../images/ext-com-dialog-oob-alert-dialog.png)
15.4 KB
Loading
21.6 KB
Loading

images/ext-com-dialog-gulp-serve.png

38.8 KB
Loading
3.69 KB
Loading
33.3 KB
Loading
56.2 KB
Loading
57.6 KB
Loading
55 KB
Loading

misc/SharePointDocumentationToc.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@
2929
<Item text="Build FieldCustomizer" url="spfx/extensions/get-started/building-simple-field-customizer" SEODescription="Building simple field customizer and associating that to SharePoint site." />
3030
<Item text="Build ListView Command Set" url="spfx/extensions/get-started/building-simple-cmdset-with-dialog-api" SEODescription="Build a ListView Command Set, which uses dialog API." />
3131
</Item>
32+
<Item text="Get started" url="spfx/extensions/get-started">
33+
<Item text="Using custom dialogs" url="spfx/extensions/guidance/using-custom-dialogs-with-spfx" SEODescription="Using Custom Dialogs with SharePoint Framework Extensions." />
34+
</Item>
3235
</Item>
3336
<Item text="Web parts" url="spfx/web-parts" SEODescription="">
3437
<Item text="Overview" url="spfx/web-parts/overview-client-side-web-parts" SEODescription="Develop SharePoint client-side web parts to provide a better customized experience for SharePoint."/>

0 commit comments

Comments
 (0)