# Fields, lists and tabs

> Everything you do with HTML attributes alone: fields of every kind, computed texts, images, lists, tabs and what each role sees.

Page: https://docs.rpgdesk.com/en/fichas/campos/

rpgdesk.js connects the page’s `data-…` attributes by itself, including on elements that show up later (the items of a list, for example). A whole sheet can be made without JavaScript. The complete table is in [HTML attributes](https://docs.rpgdesk.com/en/referencia/atributos/).

The sheet below uses almost everything on this page: the portrait, the fields, the computed modifiers, the tabs, the inventory list and the GM tab. Switch the **Role** on the band in the corner to see what each person sees.

*Working example:* [Generic D20](https://docs.rpgdesk.com/exemplos/en/generic-d20.html)

## The document and paths

Each sheet has a **document**: its fields and their values, kept in the room. Each field has a **path**:

- `name`, `level`, `strength`: standalone fields;
- `attributes.strength`, `hp.current`, `hp.max`: fields inside a group, separated by periods.

The naming rules:

- **unaccented** letters, numbers and `_`, starting with a letter or `_`;
- case does not matter: `Strength` and `strength` are the same field;
- up to 64 characters per name and 12 levels of groups;
- names that start with `_rpgdesk` belong to RPG Desk.

The verifier flags a wrong name before installing. See [The verifier](https://docs.rpgdesk.com/en/referencia/verificador/).

## Fields: `data-field`

It goes on an `<input>`, `<textarea>` or `<select>`:

```html
<label>Name <input data-field="name"></label>
<label>Level <input type="number" data-field="level" min="1"></label>
<label><input type="checkbox" data-field="inspired"> Inspired</label>
<label>Alignment
  <select data-field="alignment">
    <option>Lawful</option>
    <option>Neutral</option>
    <option>Chaotic</option>
  </select>
</label>
<label><input type="radio" name="size" value="small" data-field="size"> Small</label>
<label><input type="radio" name="size" value="medium" data-field="size"> Medium</label>
<textarea data-field="background" placeholder="Background"></textarea>
```

| Field                                        | What it saves                                              |
| -------------------------------------------- | ---------------------------------------------------------- |
| text, `<textarea>`                           | the text                                                   |
| `type="number"`, `type="range"`              | a number (empty deletes the field)                         |
| `type="checkbox"`                            | true or false                                              |
| `type="radio"`                               | the checked one’s `value` (all with the same `data-field`) |
| `<select>`                                   | the chosen option’s `value`                                |
| `type="date"`, `type="time"`, `type="color"` | the value, as text                                         |

- Text and numbers save as the person types; choices save right away.
- What someone else writes shows up right away. If you are typing in the same field, their change shows up when you leave the field.
- Whoever cannot write sees the field locked (the `rd-readonly` class goes on the field). `data-readonly` locks the field for everyone: good for showing a computed value in a field.

## Texts: `data-text`

Shows a field’s value as text, in any element. It is the way to show a computed value:

```html
<p>Modifier: <b data-text="str_mod"></b></p>
```

The value of `str_mod` comes from JavaScript, with `doc.compute`: see [Computed fields](https://docs.rpgdesk.com/en/fichas/javascript/#computed-fields).

## Images: `data-image`

On an `<img>`, shows the image kept in the field. Clicking it opens RPG Desk’s image picker (from the computer or from the room’s images) for whoever can write:

```html
<img class="portrait" data-image="portrait" alt="Character portrait">
```

Without an image, a silhouette shows up; a `src` of your own on the `<img>` replaces the silhouette. The field keeps the file’s identifier, not the image.

## Lists: `data-list`

Inventory, spells, attacks: a list where each item has its own fields. The `<template>` inside it is the mold for each item:

```html
<ul data-list="inventory">
  <template>
    <li class="rd-row">
      <input class="rd-grow" data-field="name" placeholder="Item">
      <input type="number" data-field="qty" min="0">
      <button data-roll="1d6 + {qty}" data-label="{name}">Roll</button>
      <button data-list-remove>×</button>
    </li>
  </template>
</ul>
<button data-list-add="inventory">+ Item</button>
```

- Inside the `<template>`, paths belong **to the item**: `name` is the item’s name, and `{qty}`, its quantity.
- `data-list-add="inventory"` adds an empty item at the end.
- `data-list-remove`, inside the `<template>`, removes that item.
- A list can have another list inside each item.

To add pre-filled items, reorder or count the items, use JavaScript: see [Lists](https://docs.rpgdesk.com/en/fichas/javascript/#lists).

## Tabs: `data-tabs`

A sheet is a single page. To split it into parts, use tabs:

```html
<nav data-tabs="sheet">
  <button data-tab="main">Main</button>
  <button data-tab="spells">Spells</button>
</nav>
<section data-tab-panel="main">…</section>
<section data-tab-panel="spells">…</section>
```

- Only the chosen tab’s section shows up. The first tab starts open.
- The name in `data-tabs` (`"sheet"`) separates one group of tabs from another, if the page has more than one.
- The chosen tab is remembered while the sheet is open, even if it moves to another space.

## Who sees it: `data-role`

| Value                | Who sees the element                   |
| -------------------- | -------------------------------------- |
| `data-role="gm"`     | game masters only                      |
| `data-role="owner"`  | the sheet’s owner and the game masters |
| `data-role="player"` | players only                           |

> **data-role is just looks**
>
> `data-role` only hides the element on the screen: the data still reaches everyone. For a real secret (what players must not even receive), use [private parts](https://docs.rpgdesk.com/en/fichas/partes-privadas/).

## Elements created by JavaScript

rpgdesk.js connects by itself the elements that enter the page. If you build a piece of the page with `innerHTML` and it did not connect, call `RPGDesk.bind(element)`.
