BPM, Workflow, and Case

 View Only

Using React to build a Checklist coach view [Part 1]

By Tamer Mohamed posted Mon March 15, 2021 11:33 PM

  
Introduction

Coach views can be rather simple control widgets or reusable fully functional subforms that can be embedded in coaches in a Client Side Human Service (CSHS).


In this two part blog, we will illustrate 2 possible approaches to use React to  build a coach view.

In part 1, we demonstrate the rather simple and quick approach by directly including React library as an embedded script in the generated coach view in the client side.
In part 2, we will show a more elaborate approach using a build system based on webpack in a manner that mimics using the familiar create-react-app. We will use these techniques to build a checklist control. 


Part 1: Embedding the library scripts directly in the coach view

Step 1: Download the required library files
 Start by downloading React and htm library as minified JavaScript files
https://unpkg.com/react@17/umd/react.production.min.js
https://unpkg.com/react-dom@17/umd/react-dom.production.min.js
https://unpkg.com/htm@3/dist/htm.js

“htm” is a small library (< 2k) that enables us to write jsx like code using html tagged templates.

This will result in faster code execution than using babel to transpile jsx to JavaScript in the browser.
The syntax difference between jsx and the templates used with htm is very minor.

 
Step 2: Create a new coach view

  1. Create a new process app either from the legacy ProcessCenter or from the newer WorkflowCenter landing page and let's call it "Checklist demo".
  2. Add the 3 files we just downloaded to the project "web file" category.
  3. Create a new “View” from the submenu User Interface. Let’s call it “Checklist”.
  4. In the variables tab, we will create 3 configurations options: title (String), choices (List of NameValuePair) and items (List of String). The bound data will be stored with the name “value”.
  5. In the behaviour tab, select the "Included Scripts" node and click the "+" button to add the 3 downloaded scripts. Make sure to select the script load style as “script tag".
  6. For simplicity , we will add all the code under the “load” event handler. Copy and paste the following code which renders a React component called “ChecklistComponent” inside the coach view and sets the bound data according to the user selections.

    Note that the first line in the code defines the tag for the template. For this blog, let’s just call it “jsx” to make it more distinctive. You can see that the code utilizes the React capability to generate html elements using array map function. Also note how the handler function is passed to the created checkboxes using React syntax “onClick” instead of “onclick”. The checkboxes are controlled because their “checked” value is derived from the state of the component.

    const jsx = htm.bind(React.createElement);
    
    const view = this;
    const titleStr = view.getOption("title");
    const choiceList = view.getOption("choices").items;
    const itemList = view.getOption("items").items;
    var boundData = view.context.binding && view.context.binding.get("value");
    
    function updateOutput(data) {
      if(boundData) {
        for(let i = 0; i < data.length; i++) {
          boundData.items[i] = data[i];
        }
        view.context.binding.set("value", boundData);
      }
    }
    
    function Checkbox(props) {
      return jsx`<input type="checkbox" ...${props}/>`;
    }
    
    function CheckListComponent({title, choices, items, initialData, onChange}) {
      const [data, setData] = React.useState(initialData || new Array(items.length));
      
      function handleChange(event) {
        const checkboxId = event.target.id.split("_");
        const newData = data.slice();
        newData[parseInt(checkboxId[0])] = event.target.checked ? checkboxId[1] : null;
        setData(newData);
        onChange(newData);
      }
      
      return jsx`
        <table>
          <thead>
           <tr>
            <th>${title}</th>
            ${choices.map(choice => jsx`
              <th key="${choice.value}">${choice.name}</th>
            `)}
           </tr>
          </thead>
          <tbody>
            ${items.map((item, k) => jsx`
              <tr key="${k}">
                <td>${item}</td>
                ${choices.map(choice => jsx`
                 <td key="${k}_${choice.value}">
                   <${Checkbox}
                     id="${k}_${choice.value}"
                     checked=${false || (data[k] && data[k]===choice.value)}
                     onClick=${handleChange}
                   />
                 </td>
                `)}        
              </tr>
            `)}
          </tbody>
        </table>
      `;
    }
    
    var domNode = document.createElement("div");
    view.context.element.appendChild(domNode);
    ReactDOM.render(
      jsx`
        <${CheckListComponent} 
          title=${titleStr}
          choices=${choiceList}
          items=${itemList}
          initialData=${boundData? boundData.items : null}
          onChange=${updateOutput}
        />
      `,
      domNode
    );
    ​
  7. To make things look a bit nice, we can also add some basic styling in the inline CSS section.
    table {
      font-family: arial, sans-serif;
      border-collapse: collapse;
      width: 100%;
    }
    
    td:first-child, th:first-child {
     text-align: left;
    }
    
    th {
     font-weight: bold;
    }
    
    td, th {
      border: 1px solid #dddddd;
      text-align: center;
      padding: 8px;
    }
    
    tr:nth-child(even) {
      background-color: #dddddd;
    }
    ​

    Step 3: Create a CSHS coach to test the new coach view
    1. Create a CSHS and let’s call it “test Checklist”.
    2. In the coach editor, search for “checklist” in the template and it should display the view we just created. Drag and drop into the layout, then in the configuration section, lets add some choices and some items.
    3. To test that the data is updated, we will create a variable in the coach variable list of type list of “String” and bind it to the view.
    4. We can then create a table view for the same variable to see it updated as we make the selections in the checklist. Bind the same variable to the table and bind the variable.currentItem to the text view contained within the table.
    5. Finally let's preview the CSHS and check the result.
      #coachview#checklist#React
    ​​​​​

    Permalink