---
# GENERATED FILE — do not edit.
# Source: `manage.py docs_generate` (djust 1.2.0).
# Edit the generator in docs_app/generator.py instead.
title: "JS command reference"
description: "Build browser interactions in Python: signatures, targeting, and examples."
level: reference
order: 20
section: reference
generated: true
---
Build a chain in Python and bind it to a template event. DOM operations run
in the browser; `push()` adds a server event to the chain.

## Build and bind a command

```python
from djust.js import JS

def mount(self, request, **kwargs):
    self.open_panel = JS.show("#panel").focus("#panel-title")
```

```html
<button dj-click="{{ open_panel }}">Open panel</button>
<section id="panel" style="display: none">
  <h2 id="panel-title" tabindex="-1">Details</h2>
</section>
```

## Targeting and chaining

For DOM commands, use one of `to=`, `inner=`, or `closest=` to select a target.
Without a target, the event's originating element is used. `push()` instead
accepts a server event and an optional component `target`.

Each operation returns a new chain, so an existing chain can be reused.
The Python builder uses `add_class()` and `set_attr()`; the direct browser
API uses `addClass()` and `setAttr()`. See the [JS commands guide](/guides/js-commands/)
for browser calls, transitions, and extensions.

## Commands

### `add_class`

Add one or more space-separated CSS class names to the target.

```text
JS.add_class(
    names: 'str',
    *,
    to: 'Optional[str]' = None,
    inner: 'Optional[str]' = None,
    closest: 'Optional[str]' = None,
) -> "'JSChain'"
```

### `dispatch`

Fire a `CustomEvent` with the given name on the target.

```text
JS.dispatch(
    event: 'str',
    *,
    to: 'Optional[str]' = None,
    inner: 'Optional[str]' = None,
    closest: 'Optional[str]' = None,
    detail: 'Optional[Dict[str, Any]]' = None,
    bubbles: 'bool' = True,
) -> "'JSChain'"
```

### `ext`

Dynamic factory for user-registered custom commands (ADR-025).

`chain.ext.scroll_to(to="#top", smooth=True)` appends the op
`["ext.scroll_to", {"to": "#top", "smooth": true}]`. The command
implementation is registered client-side via
`window.djust.commands.register('scroll_to', fn)`; an op whose
name was never registered fails on first invocation with a DEBUG
error overlay (and `console.error` in production).

Built-in names are blocked (`JS.ext.show` raises
`AttributeError`) — use the strictly-typed built-in instead.

### `focus`

Move keyboard focus to the target element.

```text
JS.focus(
    to: 'Optional[str]' = None,
    *,
    inner: 'Optional[str]' = None,
    closest: 'Optional[str]' = None,
) -> "'JSChain'"
```

### `hide`

Set the target element's display to `none`.

```text
JS.hide(
    to: 'Optional[str]' = None,
    *,
    inner: 'Optional[str]' = None,
    closest: 'Optional[str]' = None,
    transition: 'Optional[str]' = None,
    time: 'Optional[int]' = None,
) -> "'JSChain'"
```

### `push`

Send a server event as part of a JS command chain.

This is the bridge between client-only JS Commands (fast, local)
and server round-trips — use it when you need to mix
"optimistically close the modal, then tell the server the user
saved the form" in a single click handler.

`page_loading=True` shows the navigation-level loading bar
(`dj-page-loading` elements) while the event is in flight.

```text
JS.push(
    event: 'str',
    *,
    value: 'Optional[Dict[str, Any]]' = None,
    target: 'Optional[str]' = None,
    page_loading: 'bool' = False,
) -> "'JSChain'"
```

### `remove_attr`

Remove an HTML attribute from the target element.

```text
JS.remove_attr(
    name: 'str',
    *,
    to: 'Optional[str]' = None,
    inner: 'Optional[str]' = None,
    closest: 'Optional[str]' = None,
) -> "'JSChain'"
```

### `remove_class`

Remove one or more space-separated CSS class names from the target.

```text
JS.remove_class(
    names: 'str',
    *,
    to: 'Optional[str]' = None,
    inner: 'Optional[str]' = None,
    closest: 'Optional[str]' = None,
) -> "'JSChain'"
```

### `set_attr`

Set an HTML attribute on the target element.

```text
JS.set_attr(
    name: 'str',
    value: 'str',
    *,
    to: 'Optional[str]' = None,
    inner: 'Optional[str]' = None,
    closest: 'Optional[str]' = None,
) -> "'JSChain'"
```

### `show`

Set the target element's display to `display` (default `block`).

```text
JS.show(
    to: 'Optional[str]' = None,
    *,
    inner: 'Optional[str]' = None,
    closest: 'Optional[str]' = None,
    display: 'Optional[str]' = None,
    transition: 'Optional[str]' = None,
    time: 'Optional[int]' = None,
) -> "'JSChain'"
```

### `toggle`

Toggle the target element between hidden and shown.

```text
JS.toggle(
    to: 'Optional[str]' = None,
    *,
    inner: 'Optional[str]' = None,
    closest: 'Optional[str]' = None,
    display: 'Optional[str]' = None,
) -> "'JSChain'"
```

### `transition`

Apply `names` as CSS classes for `time` ms, then remove them.

Used to trigger CSS transitions — e.g.
`JS.transition("fade-in", time=300)` adds the `fade-in` class,
waits 300 ms for the animation, then removes it again.

```text
JS.transition(
    names: 'str',
    *,
    to: 'Optional[str]' = None,
    inner: 'Optional[str]' = None,
    closest: 'Optional[str]' = None,
    time: 'int' = 200,
) -> "'JSChain'"
```
