Create a custom in-panel widget

This tutorial walks you through the steps to create a basic custom widget. All required folders and files are included in the CustomWidgetTemplate folder so you can focus on writing the code.

To preview the final result of the custom widget, type http://[your host]/webappviewer/?config=sample-configs/config-demo.json in the browser. When the app starts, click the first icon (shown below highlighted in a green square).

Custom widget
  1. Rename the CustomWidgetTemplate folder.
    1. Go to the \\widgets\samplewidgets folder.
    2. Make a copy of the CustomWidgetTemplate folder in the same directory.
    3. Rename the copied folder MyWidget.

    MyWidget folder

  2. Open Widget.js in the MyWidget folder and set the baseClass name to jimu-widget-mywidget.
  3. Note:

    mywidget is the custom widget name.

    define(['dojo/_base/declare', 'jimu/BaseWidget'],
    function(declare, BaseWidget) {
      //To create a widget, you need to derive from BaseWidget.
      return declare([BaseWidget], {
        // Custom widget code goes here 
        baseClass: 'jimu-widget-mywidget'
      });
    });
    Caution:

    If you add other properties after the line baseClass: 'jimu-widget-mywidget', you must add a comma at the end of this line.

  4. Define the widget's UI.

    The widget's UI is defined in an HTML template.

    1. Open the Widget.html file.
    2. Copy and paste the following code into the Widget.html file:

      <div>
          <div>This is my widget.</div>
      </div>

    3. Save the file.
  5. Add the widget to the app configuration file.
    1. Open the config-demo.json file in the stemapp/sample-configs folder.
    2. Find widgetPool > widgets and add a new widget element using the following code:

      {
        "label": "MyWidget",
        "uri": "widgets/samplewidgets/MyWidget/Widget"
      }

    3. Save the file.
  6. To test the widget, start the app through http://[your host name:3344]/webappviewer/?config=sample-configs/config-demo.json and click the icon.

    The widget appears similar to the following:

    Nonconfigurable MyWidget

  7. Make the widget configurable.
    1. Open the config.json file in the MyWidget folder.
    2. Add the following JSON-structured text to pass the config to the widget:
      {
          "configText":"abcdefg"
      }
    3. Open the Widget.html file and replace the contents with the following:
      <div>
          <div>This is my widget.</div>
          <div>This is configurable.[${config.configText}]</div>
      </div>
    4. Start the same app again and click the icon.

      Now the widget looks like the following. The ${config.configText} marker in the template is automatically substituted with the values in the config.json file.

      Configurable MyWidget

  8. Make the widget user-friendly.

    On the HTML page, a CSS file is used to lay out the page, making it user-friendly.

    1. Open the css/style.css file in the MyWidget folder and add the following code:

      .jimu-widget-mywidget div:first-child{
        color: red;
      }

    2. Start the same app again and click the icon.

      The widget now resembles the following:

      http://[your host name:3344]/webappviewer/?config=sample-configs/config-demo.json

      Style the widget

  9. Access a map.
    1. Open the Widget.js file, comment out the startup function, and replace it with the following lines of code:

      The widget's map property is a type of esri.map from ArcGIS API for JavaScript, which can be retrieved through this.map in the startup function.

      startup: function() {
            this.inherited(arguments);
            this.mapIdNode.innerHTML = 'map id is:' + this.map.id;
          },
    2. Modify the Widget.html template to display the map ID property.
      <div>
          <div>This is my widget</div>
          <div>This is configurable.[${config.configText}]</div>
          <div data-dojo-attach-point="mapIdNode"></div>
          
      </div>
    3. Restart the app and click the icon.

      The widget now resembles the following:

      http://[your host name:3344]/webappviewer/?config=sample-configs/config-demo.json

      Map ID

    If you don't want to localize the widget, proceed to step 10.

  10. Add i18n support.

    Currently, the widget contains two English strings: "This is my widget" and "This is configurable". Using the Chinese language as an example to localize the UI, the following steps are needed:

    1. Open the nls/strings.js file in the MyWidget folder.

      Replace the contents with the following lines:

      define({
          root:{
              label1: "This is my widget.",
              label2: "This is configurable."
          },
          "zh-cn": true    
      });
    2. Create a subfolder named zh-cn under the nls folder.
      zh-cn folder
    3. Copy the nls/strings.js file into the zh-cn folder.
    4. Open the zh-cn/strings.js file and replace the contents with the following lines:
      define({
          label1 : "我的widget。",
          label2 : "这里可以配置。"
      });
    5. Save the file.
    6. Open the Widget.html file and replace the hard-coded English strings with markers.
      <div>
          <div>${nls.label1}</div>
      	   <div>${nls.label2}[${config.configText}]</div>
          <div data-dojo-attach-point="mapIdNode"></div>
      </div>
    7. Save the file.
    8. Reload the app, and change the browser's locale configuration to view the changes.
      http://[your host name]:3344/webappviewer/?config=sample-configs/config-demo.json
  11. Deploy the widget.
    1. Open the manifest.json file in the MyWidget folder and change the properties accordingly, such as widget type, name, locale, and so on. See Widget manifest for more information.
    2. Copy the MyWidget folder into the \stemapp\widgets folder.
    3. Restart node.js and go to http://[your host name:3344]/webappbuilder.

      You will see MyWidget in the widget pool when you click Click here to add widget in the builder.

    Note:

    The custom widget should always deploy to the stemapp\widgets folder.

Your browser is no longer supported. Please upgrade your browser for the best experience. See our browser deprecation post for more details.