Loading
Salesforce now sends email only from verified domains. Read More
Visual Studio Code Based Modeler for Consumer Goods Cloud
Table of Contents
Select Filters

          No results
          No results
          Here are some search tips

          Check the spelling of your keywords.
          Use more general search terms.
          Select fewer filters to broaden your search.

          Search all of Salesforce Help
          Runtime Changes and Interactions

          Runtime Changes and Interactions

          The communication between a UI contract and a UIPluginV2 happens using Bindings and Events.

          Required Editions

          Available in: Enterprise, Performance, and Unlimited Editions that have Consumer Goods Cloud enabled

          Properties to fetch bindings or framework functions such as FWThrowEvent aren’t available in this plugin. To solve this issue, an instance of JS (JavaScript) object PluginManager is added to a hidden script tag in all plugins. The JS object facilitates the communication between UIPluginV2 and the application framework.

          Here’s a run-time representation of UIPluginV2

          Runtime representation of a UIPluginV2
          Bindings
          A PluginManager contains Bindings as attributes. For two-way bindings, updating this attribute updates the corresponding binding in a contract, whereas updating a one-way binding attribute doesn't do so.

          For example, if a binding is named Title, then you can fetch it by PluginManager.Title.

          <UIDescription name="FWUIPluginV2::ShowPluginUI" schemaVersion="0.0.0.5">
            <Page pagePattern="SingleSectionPage">
              <PageHeader>
                <Bindings>
                  <Resource target="title" type="Label" id="TitleId" defaultLabel="UIPluginV2" bindingMode="ONE_TIME" />
                </Bindings>
              </PageHeader>
              <Section sectionName="masterSection" sectionPattern="SingleAreaSection">
                <Area areaName="mainArea" areaPattern="SingleElementArea">
                  <UIPluginV2 name="MyTestUIPluginV2">
                    <Bindings>
                      <Binding target="Title" type="Text" id="NewTitleId" binding="ProcessContext::testPlugin.title" defaultLabel="SenderTitle" bindingMode="TWO_WAY" />
                    </Bindings>
                  </UIPluginV2>
                </Area>
              </Section>
            </Page>
          </UIDescription>

          Similarly, PluginManager.Title = "Name" updates the corresponding binding.

          <UIPluginV2 name="MyTestUIPluginV2" mainComponent="main">
              <Interface>
                  <Property id="Title" />
              </Interface>
           
              <Libraries/>
           
              <UIComponentHTML name="TestHTML">
                  <![CDATA[
                      <p id="titleText">Default Title</p>
                      <label for="titleId">Change Title by Bindings</label><br><br>
                      <input type="text" id="titleId" name="ChangeTitleUsingBindings"><br><br><br>
                  ]]>
              </UIComponentHTML>
           
              <UIComponentCSS name="TestCSS">
                  <![CDATA[
                      .buttonClass {
                          min-width: 50px;
                          min-height:50px
                      }
                  ]]>
              </UIComponentCSS>
           
              <UIComponentJS name="TestJS">
                  <![CDATA[
                      document.body.addEventListener('input', function (e) {
                          if(e.target.id === "titleId") {
                              // Whenever input changes, the two-way binding Title would change and thereby changing "ProcessContext::testPlugin.title"
                              PluginManager.Title=event.target.value;
                          }
                      });
                  ]]>
              </UIComponentJS>
           
          </UIPluginV2>
          Events
          PluginManager contains a method, throwEvent to call the corresponding action defined in the contract. The throwEvent method accepts two attributes, eventName and eventParams.

          For example, PluginManager.throwEvent("updateReceiverTitle",{id : "00x"});

          Parameters used for Events: PluginManager.throwEvent(name, params)

          • name must be of type string and be the same name as in UI contract.
          • params must be of type object and all of its attributes must be declared in the contract.

          Here’s a sample UIDescription and UI contract.

          <UIDescription name="FWUIPluginV2::ShowPluginUI" schemaVersion="0.0.0.5">
            <Page pagePattern="SingleSectionPage">
              <PageHeader>
                <Bindings>
                  <Resource target="title" type="Label" id="TitleId" defaultLabel="UIPluginV2" bindingMode="ONE_TIME" />
                </Bindings>
              </PageHeader>
              <Section sectionName="masterSection" sectionPattern="SingleAreaSection">
                <Area areaName="mainArea" areaPattern="SingleElementArea">
                  <UIPluginV2 name="MyTestUIPluginV2">
                    <Bindings>
                      <Binding target="Title" type="Text" id="NewTitleId" binding="ProcessContext::testPlugin.title" defaultLabel="SenderTitle" bindingMode="TWO_WAY" />
                    </Bindings>
                    <Events>
                      <CustomPluginEvent name="updateReceiverTitle" event="updateReceiverTitleEvent">
                        <Params>
                          <Param name="title" value=".title" />
                        </Params>
                      </CustomPluginEvent>
                    </Events>
                  </UIPluginV2>
                </Area>
              </Section>
            </Page>
          </UIDescription>
          <UIPluginV2 name="MyTestUIPluginV2" mainComponent="main">
              <Interface>
                  <Property id="Title" />
                  <Events>
                     <Event name="updateReceiverTitle" />
                  </Events>
              </Interface>
           
              <Libraries/>
           
              <UIComponentHTML name="TestHTML">
                  <![CDATA[
                      <p id="titleText">Default Title</p>
                      <label for="titleId">Change Title by Events</label><br><br>
                      <input type="text" id="titleId" name="ChangeTitleUsingEvents"><br><br><br>
                  ]]>
              </UIComponentHTML>
           
           
              <UIComponentCSS name="TestCSS">
                  <![CDATA[
                      .buttonClass {
                          min-width: 50px;
                          min-height:50px
                      }
                  ]]>
              </UIComponentCSS>
           
              <UIComponentJS name="TestJS">
                  <![CDATA[
                      document.body.addEventListener('input', function (e) {
                          if(e.target.id === "titleId") {
                              // Whenever input changes, this event would be fired and corresponding logic in contract would be triggered
                              PluginManager.throwEvent("updateReceiverTitle",{
                                  title : event.target.value
                              });
                          }
                      });
                  ]]>
              </UIComponentJS>
          </UIPluginV2>

          The lifecycle of a UIPluginV2 includes:

          • ConnectCallback
          • RenderCallback
          • DisconnectCallback
          • Debugging UI plugin code
          ConnectCallback

          When the UI plugin is loaded and PluginManager is available, the system invokes the connectCallback method. You can use this method to initialize the plugin.

          For example, if the UI required a resource binding, Title, you can use this callback to update the UI during initialization.

          <UIDescription name="FWUIPluginV2::ShowPluginUI" schemaVersion="0.0.0.5">
            <Page pagePattern="SingleSectionPage">
              <PageHeader>
                <Bindings>
                  <Resource target="title" type="Label" id="TitleId" defaultLabel="UIPluginV2" bindingMode="ONE_WAY" />
                </Bindings>
              </PageHeader>
              <Section sectionName="masterSection" sectionPattern="SingleAreaSection">
                <Area areaName="mainArea" areaPattern="SingleElementArea">
                  <UIPluginV2 name="MyTestUIPluginV2">
                    <Bindings>
                      <Resource target="Title" type="Label" id="TitleId" defaultLabel="UIPluginV2" bindingMode="ONE_WAY" />
                    </Bindings>
                 </UIPluginV2>
                </Area>
              </Section>
            </Page>
          </UIDescription>
          <UIPluginV2 name="MyTestUIPluginV2" mainComponent="main">
              <Interface>
                  <Property id="Title" />
                  <Property id="SubTitle" />
              </Interface>
           
              <Libraries/>
           
              <UIComponentHTML name="TestHTML">
                  <![CDATA[
                      <p id="titleText">Default Title</p>
                  ]]>
              </UIComponentHTML>
           
              <UIComponentCSS name="TestCSS">
                  <![CDATA[
                      .buttonClass {
                          min-width: 50px;
                          min-height:50px
                      }
                  ]]>
              </UIComponentCSS>
           
              <UIComponentJS name="TestJS">
                  <![CDATA[
                      function connectCallback() {
                          document.getElementById('titleText').innerHTML = PluginManager.Title;
                          // Some initialization tasks
                      }
                  ]]>
              </UIComponentJS>
          </UIPluginV2>
          RenderCallback

          The system calls this method whenever the parent component is re-rendered. You can use this callback as a listener to any binding updates or orientation changes.

          For example, if changes in SubTitle binding are required in the UI, you can use this callback to update the UI for every change.

          <UIDescription name="FWUIPluginV2::ShowPluginUI" schemaVersion="0.0.0.5">
            <Page pagePattern="SingleSectionPage">
              <PageHeader>
                <Bindings>
                  <Resource target="title" type="Label" id="TitleId" defaultLabel="UIPluginV2" bindingMode="ONE_WAY" />
                </Bindings>
              </PageHeader>
              <Section sectionName="masterSection" sectionPattern="SingleAreaSection">
                <Area areaName="mainArea" areaPattern="SingleElementArea">
                  <UIPluginV2 name="MyTestUIPluginV2">
                    <Bindings>
                      <Resource target="title" type="Label" id="TitleId" defaultLabel="UIPluginV2" bindingMode="ONE_WAY" />
                      <Binding target="SubTitle" type="Text" id="SubTitleId" binding="ProcessContext::testPlugin.subTitle" defaultLabel="SenderSubTitle" bindingMode="TWO_WAY" />
                    </Bindings>
                 </UIPluginV2>
                </Area>
              </Section>
            </Page>
          </UIDescription>
          <UIPluginV2 name="MyTestUIPluginV2" mainComponent="main">
              <Interface>
                  <Property id="Title" />
                  <Property id="SubTitle" />
              </Interface>
           
              <Libraries/>
           
              <UIComponentHTML name="TestHTML">
                  <![CDATA[
                      <p> Sender </p>
                      <p id="titleText">Default Title</p>
                      <p id="subTitleText">Default SubTitle</p>
                  ]]>
              </UIComponentHTML>
           
              <UIComponentCSS name="TestCSS">
                  <![CDATA[
                      .buttonClass {
                          min-width: 50px;
                          min-height:50px
                      }
                  ]]>
              </UIComponentCSS>
           
              <UIComponentJS name="TestJS">
                  <![CDATA[
                      function connectCallback() {
                          document.getElementById('titleText').innerHTML = PluginManager.Title;
                          // Some initialization tasks
                      }
                      function renderCallback() {
                          // Whenever binding of SubTitle changes, renderCallback is triggered and UI will be updated
                          document.getElementById('subTitleText').innerHTML = PluginManager.SubTitle;
                      }
                  ]]>
              </UIComponentJS>
          </UIPluginV2>
          DisconnectCallback

          You can use this callback method to clean up the plugin just before unmounting. For example, if a plugin is on a UI screen that contains a page header with a Back button, then this method is invoked when you click Back.

          Limitations of the DisconnectCallback method are:

          • If you use this callback method with throwEvents or to update any bindings of the current UI process, such requests are ignored.
          • These callbacks time out and therefore can't contain any async calls or large processes.
          • If there are multiple plugins in the current screen to unmount, the system calls the disconnectCallback method for all the plugins in no specific order. Also, the time-out is applied on all these callbacks.
          <UIComponentJS name="TestJS">
                  <![CDATA[
                      this.timeoutID = setTimeout(() => {}, 1000);
                      function disconnectCallback() {
                          // Clean up any open processes
                          clearTimeout(this.timeoutId);
                      }
                  ]]>
          </UIComponentJS>
          Debugging UI plugin code
          The source URL of JS code in UIPlugin is mapped to UIPluginV2_PluginName. This name can be used in dev tools to debug the plugin code. For example, for a UIPlugin named TestUIPlugin, search UIPluginV2_TestUIPlugin to get the JS code.
           
          Loading
          Salesforce Help | Article