Creating JavaScript Form Controls (Advanced)
  • 12 Aug 2022
  • 3 Minutes to read
  • Dark
    Light

Creating JavaScript Form Controls (Advanced)

  • Dark
    Light

Overview

Users have the ability to create their own Form Controls using Javascript. This allows users to incorporate pre-built Form controls with custom controls that can have input and outputs to better address their business needs.  

For more examples regarding JavaScript Form Controls, visit Sample JS Form Controls, JS Control Seed, and Example JS Control.

Example

In this example, the control will consist of the main button that will increase the click count and a reset button that sets the click count back to zero. The control will output the current click count (since the reset button was clicked) and the total click count (which isn't affected by the reset button). This control will also have two inputs: the ability to set the text on the main button and provide a starting count.

Creating the Control

  1. In a text editor, paste in the below code. Save the file as MyJsResetControl.js, and it's ready to be added as a new Form Control.
    function MyResetButtonControl() { };
    
      MyResetButtonControl.prototype.initialize = function(host, component) {
        // Keep track of the host; we'll need it later.
        this.host = host;
        // Initialize our count data:
        this.currentCount = 0;
        this.totalCount = 0;
        // This one is important when we have input data. See 'consumeData' for details.
        this.lastConsumed = null;
    
        // We're going to put both buttons in a div, then append the div to the host:
        var control = document.createElement('div');
    
        var button = document.createElement('button');
        button.classList.add('myControlButton');
        button.type = 'button';
        button.textContent = 'Click me';
    
        var thisControl = this; // To avoid 'this' problems inside the onclick event.
    
        button.onclick = function(e){
          thisControl.currentCount++;
          thisControl.totalCount++;
        };
    
        control.appendChild(button);
    
        var resetButton = document.createElement('button');
        resetButton.classList.add('myControlButton');
        resetButton.type = 'button';
        resetButton.textContent = 'Reset';
    
        resetButton.onclick = function(e){
          if(thisControl.currentCount > 0){
            thisControl.currentCount = 0;
          }
        };
    
        control.appendChild(resetButton);
    
        host.append(control);
    
        // The two buttons appear too close together unless we add some css:
        var style = document.createElement('style');
        style.type = 'text/css';
        style.innerHTML = '.myControlButton{ margin: 5px; }';
        document.head.appendChild(style);
      };
      
      MyResetButtonControl.prototype.resize = function(height, width) {
        if (this.host && height && width && (height > 0) && (width > 0)) {
          this.host.css({ width: width, height: height });
        }
      };
      
      MyResetButtonControl.prototype.setValue = function(data) {
        // The lastConsumed variable, declared in 'initialize', is used to track changes in
        //   input data. If data exists, we make sure it has changed since last time:
        if(data && JSON.stringify(data) !== JSON.stringify(this.lastConsumed)){
          // Proceed only if the data is different than last time:
          this.lastConsumed = data;
          // Here, we treat StartingCount as optional, by using a value of 0 if no value
          //   was given:
          var startingCount = data.StartingCount || 0;
          this.currentCount = startingCount;
          this.totalCount = startingCount;
          // We've decided that ButtonText should also be an optional input,
          // so check whether it exists before using it. (If the ButtonText input is
          // set to Ignore, we'll keep the default button text, 'Click me'.)
          if(data.ButtonText){
            // Use JQuery's find function to find the first button on our control:
            this.host.find('button')[0].textContent = data.ButtonText;
          }
        }
      };
      
      MyResetButtonControl.prototype.getValue = function() {
        return {
          CurrentClickCount: this.currentCount,
          TotalClickCount: this.totalCount
        };
      };
  2. In a Designer Project, click CREATE FORM from the Global Action Bar. Click JavaScript Control and select Add Data Control.
  3. Enter a name for the Control and change the Control Type to Data. Under Input Data, click ADD.

  4. Enter "ButtonText" in the Name field. Click PICK under the Type field and select String. Click OK. Add another Input Data as StartingCount as an Int32.

  5. Click the Different Output Data checkbox to set it to true. Click ADD and add CurrentClickCount(Int32) and TotalClickCount(Int32).

  6. Type "MyResetButtonControl" for the JS Class Name.
    Under the 'Runtime Information', the 'JS Class Name' must match the class name in the JavaScript file. If they do not match, the JS control will not function in the form.
  7. Drag and drop the JS file into the JS File section. Click SAVE CONTROL.

Use the Control in a Form

  1. In a Designer Project, click CREATE FLOW and select Flow to create a Flow.
  2. Attach a Show Form step to the Start step. Click PICK OR CREATE FORM and create a Form
  3. In the Toolbox panel, drag a Button component (Submitonto the Form. Expand JS Controls >[Current Folder] drag the Reset Button Control to the Form. Click Save and close the Form Designer.

  4. On the Properties panel, enter Constant mapping values for Button Text and Starting Count. Connect the Done path to the End step. Click Save to save changes to the Flow.

Debug

  1. Click Debug on the top action panel. 
  2. Click the Click Here button multiple times and click Submit. 
  3. Select the Show Form step, Execution 1, and View Output Data. The output from the Form will include the CurrentClickCount and TotalClickCount.

For further information on Forms, visit the Decisions Forum.

Was this article helpful?