gramlot

Pre-alpha. First usable release planned for late 2026.

← Tutorial

textBox · Composition

Reuse with local scopes

Two identical panels keep independent values. Relative paths make the same recipe reusable under different datapaths.

Try both versions. Each result has its own datastore. Reload the page to reset.

Python

Built from Python
Python recipe
from gramlot.page import WebPage


class Page(WebPage):
    """Reuse a panel with independent relative data paths."""

    def main(self, root):
        container = root.div(datapath="example")
        self.text_panel(container, ".alpha", "Alpha")
        self.text_panel(container, ".beta", "Beta")

    def text_panel(self, parent, path, title):
        pane = parent.div(datapath=path, border="1px solid #dce3ee",
                          padding="12px", margin_bottom="12px")
        pane.data(".text", title)
        pane.textBox(value="^.text", lbl=title, updateOn="input",
                     lbl_position="TL", width="100%")
        pane.p("^.text")

JavaScript

Built in the browser
JavaScript recipe
function textPanel(parent, path, title) {
  const pane = parent.div({datapath: path, border: "1px solid #dce3ee",
    padding: "12px", margin_bottom: "12px"});
  pane.data(".text", title);
  pane.textBox({value: "^.text", lbl: title, updateOn: "input",
    lbl_position: "TL", width: "100%"});
  pane.p("^.text");
}

export function build(root) {
  const container = root.div({datapath: "example"});
  textPanel(container, ".alpha", "Alpha");
  textPanel(container, ".beta", "Beta");
}
Python builds the recipe before publication. JavaScript builds it in the browser. The same Gramlot runtime renders both. These examples need no application server.