> For the complete documentation index, see [llms.txt](https://docs.wem.io/platform/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.wem.io/platform/wemreference/wem-widgets/wem-widget-structure.md).

# WEM Widget Structure

{% hint style="info" %}
Go to [this Forum Post](https://forum.wem.io/link?threadid=69) to find:\
[ExampleWidgetsLibrary.zip](https://my.wem.io/filestore/si/1026519/10/1049521/ExampleWidgetsLibrary.zip?etag=f2b4e5d216fb4f53a69a48c1afc05c27)\
Library with some working example widgets, so you can review and learn the code.

[BasicWEMWidgetExample.zip](https://my.wem.io/filestore/si/1026519/95/1049521/BasicWEMWidgetExample.zip?etag=a1d914bf75db23f0f699f53e02f0a9c7)\
Basic WEM Widget Example with explanation of the structure and the code.
{% endhint %}

### Widget Development Tab/Elements

* **Script**: the actual functionality that will be added to the interaction node/template/page where widget is added to the template;
* **Properties**: properties to be used by widget, parameters to be set on an instance of the widget; possible links to fields in data model;
* **View state**: fields that will be added to and accessible from view state;
* **Events**: definition of events and eventhandler scripts (refresh screen, execute flowchart, follow exit);
* **Resources**: files (scripts or images) to be included; these are files that will be included in the package and also in the published resources when projects using the widget are published. So files need to be as small as possible;
* **Styles**: **CSS** style definitions specific to the elements in the widget. **LESS** can also be used if you are familiar with it. Be smart and use unique identifiers and limited scope;
* **Editor script**: define the display of the widget (informative, not interactive) in the Modeler Template Editor when user places widget onto a template.

### Typical widget script outline

1. **`scriptreferences`**: referring to local or remote JavaScript files - **local files are preferred**, because remote files may become unavailable in future or may conflict with other widgets after updates - local files will keep all resources you need for the widget to work available and under control;
2. **`register inputs`**: to enable widget properties to be handled as input and linked to fields in the Data Model;
3. **`register events`**: to enable your defined events on the Events tab as operational events in the script;
4. **`script module`** block: JavaScript that will be added to the html once to be re-used;
5. **`startup script`** block: JavaScript that is executed just after html is rendered, to initialize an instance of a widget;
6. **`submitscript`** block: JavaScript that is executed on submit;
7. **`unloadscript`** block: JavaScript that will be invoked after the request/post gets new response from server but before the new HTML result is rendered, use to cleanup JavaScript instances;
8. **`Html`** (to present visible user interaction and presentation, also the hidden input elements to store and update values linked to fields in data model).

### Unique ID

A widget can be placed on a page more than once by actually placing it more than once or having it inside a repeating element. To distinguish between different instances of a widget, it needs a unique identifier within the html-DOM.

* A page-level unique id can be created using the function **`OutputId()`**.
* A specific unique id for instance of a property on page (useful for input fields): **`OutputId(@Property)`**.

### Linking input fields in Widget to WEM Data model

* add property of type Data Field;
* Enable option ‘Data field must be writable’;
* Register as input: `register input @DataField`;
* Add html input field (hidden or other), like:\
  &#x20;`<input type="hidden"` \
  &#x20;       `name="<?attr OutputId(@DataField) ?>"` \
  &#x20;       `id="<?attr OutputId(@DataField) ?>"` \
  &#x20;       `value="<?attr @DataField ?>" />`
* Update the value of this input-field linked to WEM Field using JavaScript in the widget-code.

### Events

1. Create an event (name and event script);
2. In Widget Script tab, add:\
   &#x20;`register event @EventName`;
3. In the JavaScript widget-code where this event should be triggered, add: \
   &#x20;`<?raw @EventName ?>`

Typical WEM-events are:

* `execute @Flowchart`
* `follow @Exit`
* `navigate @NavigationItem`

Typical example for an event, using properties:

* `@EventType`: \
  Dropdown options like “FollowExit”, “ExecuteFlowchart”, “NavigateTo”, “RefreshScreen”, “DoNothing”;
* `@Flowchart`: user can select a flowchart when configuring the widget;
* `@Exit`: user can select an exit when widget is on a template which has exits;

#### Eventhandler script:

```
if @EventType = "ExecuteFlowchart" 
    execute @Flowchart 
elseif @EventType = "FollowExit" 
    follow @Exit 
elseif @EventType = "NavigateTo" 
    navigate @NavigationItem 
end
```

Register event (only when it is not chosen as DoNothing):

```
if @EventType <> "DoNothing" 
    register event @EventName 
end
```

Trigger event:

```
function triggerEvent() {
    <?raw @EventName ?>
}
```

If an EventType is selected by user (like a FollowExit or ExecuteFlowchart) but there is no Exit specified to follow, or a Flowchart to Execute, there will be a Page Refresh.

### Editor script

Using the Editor Script, you can define the display of the Widget when a User places the Widget onto the Template Canvas in the WEM Template Editor.&#x20;

One good option would be to create an example with your widget, run it in Preview, make an image of the rendered result, add the image to the Resources (as PreviewImage) and use that Resource in this Editor Script:

```
var widgetPreview = utility.createElement("div");
widgetPreview.className = "widgetPreview";

var title = utility.createElement("div");
title.className = "widgetPreviewTitle";
title.appendChild(utility.createTextNode("Name Of Widget"));
widgetPreview.appendChild(title);

var previewImg = utility.createElement("img");
previewImg.src = resources.PreviewImage;
widgetPreview.appendChild(previewImg);

return widgetPreview;
```

The widgetPreview CSS classname is defined in the Styles tab, for example:

```
div.widgetPreview {
    border: 2px solid #dddddd;
    position: relative;
    width: 100%; 
    
    > div.widgetPreviewTitle {
    	background: #f8f8f8;
    	display: inline-block;
    	padding: 10px 2%;
    	width: 96%;
    }
    
    > img {
    	max-width: 100%;
    }
}
```

###


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.wem.io/platform/wemreference/wem-widgets/wem-widget-structure.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
