Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
[This topic is pre-release documentation and is subject to change.]
In this tutorial, you'll build a code component that uses custom events and test it using both canvas and model-driven apps. Learn more about the custom events preview.
Goal
The steps in this tutorial guide you to create a code component with two buttons which raise different events for the hosting application can react to. You'll define two events: customEvent1
and customEvent2
. Then, the code component exposes two buttons that cause these events to occur.
Canvas App
The canvas app uses Power Fx expressions on these events to toggle the visible and display mode properties of a control:
Model-driven App
The model-driven app uses client-side JavaScript to show an alert when the respective events occur.
Prerequisites
You should already know how to:
- Create and build a code component
- Package a code component
- Add code components to a model-driven app
- Add components to a canvas app
Create a new Control
Create a new component using this command:
pac pcf init -n EventSample -ns SampleNamespace -t field -fw react -npm
Edit the manifest to add the new events
<property name="sampleProperty"
display-name-key="Property_Display_Key"
description-key="Property_Desc_Key"
of-type="SingleLine.Text"
usage="bound"
required="true" />
<resources>
<code path="index.ts"
order="1"/>
<platform-library name="React"
version="16.8.6" />
<platform-library name="Fluent"
version="8.29.0" />
<css path="css/SampleEventPCF.css" order="1" />
<resx path="strings/SampleEventPCF.1033.resx" version="1.0.0" />
</resources>
Define events
In the EventSample\HelloWorld.tsx
control file, define two events in the interface and bind the events to two different buttons. Also update the import to include DefaultButton
as the following changes show.
import * as React from 'react';
import { Label } from '@fluentui/react';
export interface IHelloWorldProps {
name?: string;
}
export class HelloWorld extends React.Component<IHelloWorldProps> {
public render(): React.ReactNode {
return (
<Label>
{this.props.name}
</Label>
)
}
}
Modify updateview
method
In EventSample\Index.ts
, modify the updateView method to add handlers for the two button events. These handlers add the two events defined in the manifest to the events in the context passed to the control.
public updateView(context: ComponentFramework.Context<IInputs>): React.ReactElement {
const props: IHelloWorldProps = { name: 'Hello, World!' };
return React.createElement(
HelloWorld, props
);
}
Build and package
As usual, you need to complete these steps to use this control:
Use in a canvas app
To use this control in a canvas app, you need to:
Add a new control. This example uses a text control.
Add two global variables to the app:
isVisible
andcanEdit
.Set
canEdit
to theDisplayMode
property of the text control.Set
isVisible
to theVisible
property of the text control.Set custom actions on the new custom control to update the
isVisible
andcanEdit
variables when the buttons are clicked.Event Power FX expression customEvent1 If(isVisible, Set (isVisible, false), Set (isVisible, true))
customEvent2 If(canEdit = DisplayMode.Edit, Set(canEdit, DisplayMode.Disabled), Set (canEdit, DisplayMode.Edit))
Test the canvas app
Press Trigger event 1.
Expected: The text control toggles between visible and hidden
Press Trigger event 2.
Expected: The text control toggles between editable and read only.
Use in a model-driven app
Note
These steps refer to instructions described in Walkthrough: Write your first client script.
Create a new JavaScript web resource to run on the
onLoad
event of a form. This script binds two event handlers to the new events for the controls on load of the form./* eslint-disable */ "use strict"; var MyScriptsNameSpace = window.MyScriptsNameSpace || {}; (function () { const controlName1 = "cr116_personid"; this.onLoad = function (executionContext) { const formContext = executionContext.getFormContext(); const sampleControl1 = formContext.getControl(controlName1); sampleControl1.addEventHandler("customEvent1", this.onSampleControl1CustomEvent1); sampleControl1.addEventHandler("customEvent2", this.onSampleControl1CustomEvent2); }; this.onSampleControl1CustomEvent1 = function (params) { alert(`SampleControl1 Custom Event 1`); }.bind(this); this.onSampleControl1CustomEvent2 = function (params) { alert(`SampleControl1 Custom Event 2`); }.bind(this); }).call(MyScriptsNameSpace);
Complete the following steps as you normally do:
Configure the On Load event as shown in the following image:
Test your app.
When you navigate to the form and press Trigger event 1, an alert displays
SampleControl1 Custom Event 1
. When you press Trigger event 2, an alert displaysSampleControl1 Custom Event 2
.
Passing payload in events
As described in Defining an event for model-driven apps, you can pass payload in events in model-driven apps. You can modify this example in the following way to see how this works.
Pass payload with event
Change the EventSample\index.ts
so that the events pass a message payload and in the second event also pass a callback function that changes an internal variable
public updateView(context: ComponentFramework.Context<IInputs>): React.ReactElement {
const props: IHelloWorldProps = {
onCustomEvent1: ()=> {
context.events.customEvent1()
},
onCustomEvent2: () => {
context.events.customEvent2()
}
};
return React.createElement(
HelloWorld, props
);
}
Then:
Add another field to the form used before and also set that to use the new component.
Use the payload in the event handler
Update the onLoad
function to set the event handlers on the custom controls to react to events from both controls and also to make use of the parameters being passed
/* eslint-disable */
"use strict";
var MyScriptsNameSpace = window.MyScriptsNameSpace || {};
(function () {
const controlName1 = "cr116_personid";
this.onLoad = function (executionContext) {
const formContext = executionContext.getFormContext();
const sampleControl1 = formContext.getControl(controlName1);
sampleControl1.addEventHandler("customEvent1", this.onSampleControl1CustomEvent1);
sampleControl1.addEventHandler("customEvent2", this.onSampleControl1CustomEvent2);
};
this.onSampleControl1CustomEvent1 = function (params) {
alert(`SampleControl1 Custom Event 1`);
}.bind(this);
this.onSampleControl1CustomEvent2 = function (params) {
alert(`SampleControl1 Custom Event 2`);
}.bind(this);
}).call(MyScriptsNameSpace);
Test the model-driven app
Navigate to the form.
Press Trigger event 1 on the first field.
Expected: A pop-up displays SampleControl1 Custom Event 1: Hello from event 1 on the first field.
Press Trigger event 2 on the first field.
Expected: A pop-up displays SampleControl1 Custom Event 2: Hello from event 2 on the first field followed by an alert from the first control that says Event 2 default NOT prevented
Press Trigger event 1 on the second field.
Expected: A pop-up displays SampleControl2 Custom Event 1: Hello from event 1 on the second field.
Press Trigger event 2 on the second field.
Expected: A pop-up displays SampleControl2 Custom Event 2: Hello from event 2 on the second field followed by an alert from the second control that says Event 2 default prevented