# view\_widget.xml

This file lets developers create a form that is displayed as a GUI when a widget is created on a dashboard.

Its contents use Ubidots-mapped, XML-like tags that render as React elements. Because of this, it differs from traditional XML tags. Also, `view.xml` and `view_widget.xml` are implemented differently, so they support different tags.

For the available elements and usage details, see [Custom UI](/dashboards-and-widgets/custom-ui.md).

## Basic structure

Ubidots native widgets include two configuration tabs:

* Settings
* Appearance

<figure><img src="/files/O3u4ipPW7uTuTs6bt9FW" alt="" width="563"><figcaption></figcaption></figure>

You can implement the same layout in a widget plugin drawer with the `tabs` element in the `view_widget.xml` file. The following example defines three tabs: `Settings`, `Appearance`, and `Advanced`.

```xml
<form>
    <tabs selected="settings">
        <tab id="settings" padded="false" title="Settings">
            <addvariable
                id="settings.variable-picker"
                maxvariables="1"
                dividername="Add Variables"
                widgetbehavior="true"
            >
                <variablelabel/>
                <inputcombo
                    id="custom-label"
                    label="Custom name"
                    placeholder="Water level"
                    type="text"
                />
            </addvariable>
        </tab>
        <tab id="appearance" title="Appearance">
            <inputcombo 
                id="appearance.title" 
                type="text" 
                label="Widget title" 
                placeholder="Water level" 
            />
            <inputcombo
                id="appearance.subtitle"
                type="text"
                label="Widget subtitle"
                placeholder="Water level in the tank"
            />
            <inputcombo
                id="appearance.external-item-text"
                type="text"
                label="External item text"
                placeholder="External item"
            />
            <inputcombo
                id="appearance.external-item-url"
                type="text"
                label="External item URL"
                placeholder="http://example.com"
            />
        </tab>
        <tab id="advanced" title="Advanced">
            <inputcombo
                id="advanced.widget-id"
                type="text"
                label="Widget ID"
                placeholder="widget-1"
            />
            <inputcombo
                id="advanced.widget-class"
                type="text"
                label="Widget class"
                placeholder="widget-class"
            />
            <inputcombo
                id="advanced.widget-style"
                type="text"
                label="Widget style"
                placeholder="width: 100%;"
            />
        </tab>
    </tabs>
</form>
```

This configuration renders the following drawer:

| Settings tab                                                        | Appearance tab                                                      | Advanced tab                                                        |
| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- |
| <img src="/files/STjbxqMgdsxZaJcHMXeu" alt="" data-size="original"> | <img src="/files/EEU4Nwjk0eX0yNWYYiZ6" alt="" data-size="original"> | <img src="/files/0lxVcwr5htSIS2OwGW4t" alt="" data-size="original"> |

The number and names of tabs are not fixed. You can add and name tabs as needed beyond `settings` and `appearance`.

{% hint style="info" %}
To ensure `ubidots.getWidget().getSettings()` returns a structured object where child elements are nested under their respective tabs, use element IDs in this format:

```
parent-tab-id.child-element-id
```

{% endhint %}

## Tabs

Tabs help organize user input in the widget drawer and make the interface easier to use. Tabs have two attributes:

* **id:** Unique identifier for the tab element.
* **title:** Text displayed in the drawer to identify the tab.

Inside a tab, you can place any form element available in [Custom UI](/dashboards-and-widgets/custom-ui.md).

### **ID Naming Conventions**

**Using Parent-Referenced IDs**

This method explicitly associates each element with its parent tab. The resulting `xmlSettings` object keeps a structured hierarchy, with settings grouped under their respective tabs.

**Example XML:**

```xml
<tab id="settings" title="Settings">
    <inputcombo id="settings.title" type="text" label="Title"/>
    <inputcombo id="settings.subtitle" type="text" label="Subtitle"/>
</tab>

<tab id="appearance" title="Appearance">
    <inputcombo id="appearance.widget-title" type="text" label="Widget Title"/>
</tab>
```

**Resulting JSON (`ubidots.getWidget().getSettings()`):**

```json
{
   "xmlSettings": {
      "settings": {
         "title": "Title",
         "subtitle": "Subtitle"
      },
      "appearance": {
         "widget-title": "Widget Title"
      }
   }
}
```

This structure keeps settings grouped under their corresponding tab.

#### **Using Flat IDs (Without Parent Reference)**

If element IDs do not reference their parent tab, all elements are placed at the root of `xmlSettings`. This makes it harder to tell which tab they belong to.

**Example XML:**

```xml
<tab id="settings" title="Settings">
    <inputcombo id="title" type="text" label="Title"/>
    <inputcombo id="subtitle" type="text" label="Subtitle"/>
</tab>
<tab id="appearance" title="Appearance">
    <inputcombo id="widget-title" type="text" label="Widget Title"/>
</tab>
```

**Resulting JSON (`ubidots.getWidget().getSettings()`):**

```json
{
   "xmlSettings": {
      "title": "Title",
      "subtitle": "Subtitle",
      "widget-title" : "Widget Title"
   }
}
```

In this case, all child elements appear at the root level and lose their association with their parent tab.

**Best Practice**

To keep the configuration well structured, we strongly recommend following the `parent-tab-id.child-element-id` convention when defining IDs for elements inside tabs.

## 'Add Variables' element

Ubidots native widgets let users select the target variables for the widget and choose the **widget behavior** — static or dynamic.

<figure><img src="/files/0sx6HrsX6WT5Fe9tssKD" alt="" width="563"><figcaption></figcaption></figure>

You can implement the same behavior with the `addvariable` element in the `view_widget.xml` file.\
\
For example, to replicate the Metric widget UI shown above, you can use the following `view_widget.xml`:

```xml
<form>
    <addvariable
        id="variables"
        maxvariables="1"
        dividername="ADD VARIABLES"
    >
        <variablelabel
            label="Variable label"
            description=""
        />
        <inputcombo
            type='dropdown.list'
            id='aggregationMethod'
            label="Aggregation method"
            description=""
            placeholder='Last value'
        >
            <menu>
                <item id='last_value'>Last value</item>
                <item id='average'>Average</item>
                <item id='minimum'>Minimum</item>
                <item id='maximum'>Maximum</item>
                <item id='sum'>Sum</item>
                <item id='count'>Count</item>
            </menu>
        </inputcombo>
        <inputcombo
            type="span"
            id="span"
            label="Span"
            description=""
        />

    </addvariable>
</form>
```

Inside the `addvariable` tag, you can use any element described in [Custom UI](/dashboards-and-widgets/custom-ui.md).

### addvariable tag

This element renders the full modal used to add variables. It has the following attributes:

<table><thead><tr><th width="173">Attribute</th><th width="122">Mandatory</th><th>Description</th></tr></thead><tbody><tr><td><code>id</code></td><td>Yes</td><td>Unique identifier used internally. Do not modify its default value.</td></tr><tr><td><code>maxvariables</code></td><td>Yes</td><td>Maximum number of variables that can be added.</td></tr><tr><td><code>dividername</code></td><td>Yes</td><td>Divider label displayed in the UI.</td></tr></tbody></table>

### variablelabel tag

This element displays a label and description inside a container to provide additional context.

<table><thead><tr><th width="166">Attribute</th><th width="134">Mandatory</th><th>Description</th></tr></thead><tbody><tr><td>label</td><td>Yes</td><td>Message displayed when selecting a variable.</td></tr><tr><td>description</td><td>No</td><td>Message displayed below the label.</td></tr></tbody></table>

<figure><img src="/files/kfMVEBSYVMBG0xmcvuM7" alt="" width="563"><figcaption></figcaption></figure>

If you change the `label` attribute from `Variable label` to `Variables`, that message will be displayed instead.

## Adding variables' Aggregation methods

If your plugin widget requires the variable's aggregation method, you can use an `inputcombo` of type `dropdown.list` as shown above. For it to work correctly, the `id` attribute must be `aggregationMethod`.

## Adding variable's time-span

If your plugin widget requires a time span for the variable's data, you can use an `inputcombo` of type `span` as shown above. For it to work correctly, the `id` attribute must be `span`.

## Accessing \`view\_widget.xml\` data from the Widget's script

You can access `view_widget.xml` elements from `widget.js` by using the input combo `id` attribute.

For example, suppose your widget uses the following `view_widget.xml` file:

```xml
<form>

    <inputcombo 
        id="device_label" 
        type="text" 
        label="Device label" 
        description="Device's label to which send the data" 
        placeholder="" 
    />
    <inputcombo 
        id="title" 
        type="text" 
        label="Chart's title" 
        description="Chart's title" 
        placeholder="" 
    />
    <addvariable
        id="variables"
        maxvariables="1"
        dividername="ADD VARIABLES"
    >
        <variablelabel
            label="Variable label"
            description=""
        />
        <inputcombo
            type='dropdown.list'
            id='aggregation_method'
            label="Aggregation method"
            description=""
            placeholder='Last value'
        >
            <menu>
                <item id='last_value'>Last value</item>
                <item id='average'>Average</item>
                <item id='minimum'>Minimum</item>
                <item id='maximum'>Maximum</item>
                <item id='sum'>Sum</item>
                <item id='count'>Count</item>
            </menu>
        </inputcombo>
        <inputcombo
            type="span"
            id="span"
            label="Span"
            description=""
        />
    </addvariable>
</form>
```

You can access this data as follows:

```javascript
const settings = ubidots.getWidget().getSettings()["xmlSettings"];
```

Then `settings` will look like this:

```json
{
   "title":"my chart",
   "variables":[
      {
         "span":"inherit",
         "color":{
            "a":1,
            "b":62,
            "g":131,
            "r":131
         },
         "label":"variable-cron",
         "variableColor":{
            "a":1,
            "b":62,
            "g":131,
            "r":131
         },
         "aggregationMethod":"last_value"
      }
   ],
   "device_label":"my device",
   "widgetBehavior":"inherit"
}
```

This object contains, at the root level, the keys that correspond to each `view_widget.xml` element `id`.

In the example above, two input combos use the IDs `device_label` and `title`. Those keys appear in the `settings` object. The `variables` key is always a list that contains the selected variables.

You can also access the widget endpoint like this:

```javascript
const url = ubidots.getWidget().getSettings()["function_url"]
```


---

# Agent Instructions: 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:

```
GET https://dev.ubidots.com/plugins/plugins-development/view_widget.xml.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
