@loadbare/app 0.12.0 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/build/assemble.d.ts.map +1 -1
- package/dist/build/assemble.js +87 -1
- package/dist/build/assemble.js.map +1 -1
- package/dist/build/cli.js +2 -1
- package/dist/build/cli.js.map +1 -1
- package/dist/build/elements.d.ts +9 -1
- package/dist/build/elements.d.ts.map +1 -1
- package/dist/build/elements.js +50 -0
- package/dist/build/elements.js.map +1 -1
- package/dist/build/origins.d.ts +2 -0
- package/dist/build/origins.d.ts.map +1 -1
- package/dist/build/origins.js +1 -1
- package/dist/build/origins.js.map +1 -1
- package/dist/core/lb-constants.d.ts +34 -1
- package/dist/core/lb-constants.d.ts.map +1 -1
- package/dist/core/lb-constants.js +105 -0
- package/dist/core/lb-constants.js.map +1 -1
- package/dist/core/lb-types.d.ts +74 -18
- package/dist/core/lb-types.d.ts.map +1 -1
- package/dist/core/lb-types.js +74 -11
- package/dist/core/lb-types.js.map +1 -1
- package/dist/hub/lb-apply.d.ts +57 -18
- package/dist/hub/lb-apply.d.ts.map +1 -1
- package/dist/hub/lb-apply.js +661 -63
- package/dist/hub/lb-apply.js.map +1 -1
- package/dist/hub/lb-hub.browser.d.ts.map +1 -1
- package/dist/hub/lb-hub.browser.js +400 -33
- package/dist/hub/lb-hub.browser.js.map +1 -1
- package/dist/server/lb-express.d.ts +19 -7
- package/dist/server/lb-express.d.ts.map +1 -1
- package/dist/server/lb-express.js +62 -26
- package/dist/server/lb-express.js.map +1 -1
- package/dist/server/lb-server.d.ts +80 -11
- package/dist/server/lb-server.d.ts.map +1 -1
- package/dist/server/lb-server.js +185 -33
- package/dist/server/lb-server.js.map +1 -1
- package/docs/TECHREF-1.0.md +584 -111
- package/docs/comparison.md +17 -13
- package/docs/possible-ideas.md +308 -0
- package/docs/reference/chrome.md +7 -1
- package/docs/reference/custom-elements.md +134 -39
- package/docs/reference/data-binding.md +405 -17
- package/docs/reference/page-files.md +101 -19
- package/docs/reference/server.md +24 -0
- package/docs/reference/widgets.md +118 -25
- package/docs/roadmap.md +17 -6
- package/docs/testing.md +21 -10
- package/package.json +2 -3
- package/skills/loadbare-app/SKILL.md +92 -30
- package/skills/loadbare-app/references/TECHREF-1.0.md +584 -111
- package/skills/loadbare-app/references/chrome.md +7 -1
- package/skills/loadbare-app/references/custom-elements.md +134 -39
- package/skills/loadbare-app/references/data-binding.md +405 -17
- package/skills/loadbare-app/references/page-files.md +101 -19
- package/skills/loadbare-app/references/server.md +24 -0
- package/skills/loadbare-app/references/widgets.md +118 -25
|
@@ -48,7 +48,8 @@ page touches that page's files.
|
|
|
48
48
|
## HTML
|
|
49
49
|
|
|
50
50
|
Write the page as a fragment. The fragment lands in `<main>`, which
|
|
51
|
-
[chrome.html](./chrome.md) supplies.
|
|
51
|
+
[chrome.html](./chrome.md) supplies. A page carries no `<main>` and no
|
|
52
|
+
`<lb-hub>` of its own; the builder rejects one that does.
|
|
52
53
|
|
|
53
54
|
```html
|
|
54
55
|
<!-- src/pages/about.page.html -->
|
|
@@ -89,14 +90,18 @@ export const queries: Queries = {
|
|
|
89
90
|
page: "directory",
|
|
90
91
|
count: String(await ctx.db.visitCount()),
|
|
91
92
|
})),
|
|
92
|
-
directory: rows("id", (ctx) => ctx.db.directory()),
|
|
93
|
+
directory: rows("id", (ctx) => ctx.db.directory(), { order: "name" }),
|
|
93
94
|
};
|
|
94
95
|
```
|
|
95
96
|
|
|
96
|
-
| Declared with
|
|
97
|
-
|
|
98
|
-
| `row(key, run)`
|
|
99
|
-
| `rows(key, run)` | All its rows, an array of objects
|
|
97
|
+
| Declared with | Answers with |
|
|
98
|
+
|----------------------------|-------------------------------------------|
|
|
99
|
+
| `row(key, run)` | One row, an object |
|
|
100
|
+
| `rows(key, run, options)` | All its rows, an array of objects |
|
|
101
|
+
|
|
102
|
+
`options` are a `rows` query's order: `order`, the columns the hub places
|
|
103
|
+
its rows by, and `serverSortedByUrl`, set when the query reads the user's
|
|
104
|
+
order parm itself. See [Order](./data-binding.md#order).
|
|
100
105
|
|
|
101
106
|
`key` names the column that identifies a row. Give every row that column,
|
|
102
107
|
including a `row` query's: an aggregate row answers with a constant key. The
|
|
@@ -109,8 +114,8 @@ page that needs the same data as one row and as a set declares two queries.
|
|
|
109
114
|
The hub hands each value to the browser untouched, so what a number, a date
|
|
110
115
|
or a null looks like is decided here, in the query.
|
|
111
116
|
|
|
112
|
-
Return the full answer every time
|
|
113
|
-
|
|
117
|
+
Return the full answer every time. With no `order`, the rows show in the
|
|
118
|
+
order they are returned. Sending only what changed is a request's job — see
|
|
114
119
|
[refresh and patch](#refresh-and-patch).
|
|
115
120
|
|
|
116
121
|
## Requests
|
|
@@ -120,7 +125,7 @@ optional:
|
|
|
120
125
|
|
|
121
126
|
| Key | Runs |
|
|
122
127
|
|---------------|--------------------------------------------------------|
|
|
123
|
-
| `onPageEnter` | Before the page's queries, when the page loads
|
|
128
|
+
| `onPageEnter` | Before the page's queries, when the page loads; may move the URL |
|
|
124
129
|
| `handlers` | The page's declared requests, by request name |
|
|
125
130
|
| `crud` | The requests Loadbare provides, by query name |
|
|
126
131
|
|
|
@@ -132,10 +137,14 @@ name:
|
|
|
132
137
|
| `name` | The request name, from `lb-request` |
|
|
133
138
|
| `query` | The query the request is for |
|
|
134
139
|
| `key` | The key of the row the request is for |
|
|
140
|
+
| `keys` | The keys of the rows selected, in place of `key` |
|
|
141
|
+
| `rows` | A form's nested rows, by query: each `key` and `values` |
|
|
135
142
|
| `values` | The gathered control values, by column |
|
|
136
143
|
|
|
137
144
|
The hub sends `query`, `key` and `values` when it finds them; see
|
|
138
|
-
[Gathering](./data-binding.md#gathering).
|
|
145
|
+
[Gathering](./data-binding.md#gathering). It sends `keys` for a request that
|
|
146
|
+
acts on the rows the user selected; see
|
|
147
|
+
[Selecting rows](./data-binding.md#selecting-rows).
|
|
139
148
|
|
|
140
149
|
### onPageEnter
|
|
141
150
|
|
|
@@ -150,6 +159,12 @@ export const requests: Requests = {
|
|
|
150
159
|
|
|
151
160
|
Declare no refresh set here. The page's queries run afterward.
|
|
152
161
|
|
|
162
|
+
It may return `url()` instead, to move the page to other query parms before
|
|
163
|
+
anything shows, as restoring the filters and order the user last had does.
|
|
164
|
+
The page loads there in the same round trip, and that load does not follow
|
|
165
|
+
`onPageEnter` again. A `url()` leading to the parms already in hand is
|
|
166
|
+
ignored. See [Moving the URL](#moving-the-url).
|
|
167
|
+
|
|
153
168
|
### handlers
|
|
154
169
|
|
|
155
170
|
Declare a request under the name the HTML gives `lb-request`. Pair what it
|
|
@@ -180,10 +195,34 @@ the query they operate on:
|
|
|
180
195
|
|
|
181
196
|
| Request name | Runs | `run` receives |
|
|
182
197
|
|-----------------|-------------|------------------|
|
|
183
|
-
| `lb-row-insert` | `rowInsert` | `query`, `values` |
|
|
184
|
-
| `lb-row-update` | `rowUpdate` | `query`, `key`, `values` |
|
|
198
|
+
| `lb-row-insert` | `rowInsert` | `query`, `values`, and `rows` from a form |
|
|
199
|
+
| `lb-row-update` | `rowUpdate` | `query`, `key`, `values`, and `rows` from a form |
|
|
185
200
|
| `lb-row-delete` | `rowDelete` | `query`, `key` |
|
|
186
201
|
|
|
202
|
+
An `lb-row-update` or `lb-row-delete` carrying `keys` runs `rowUpdate` or
|
|
203
|
+
`rowDelete` once for each key, with that key, so a handler written for one
|
|
204
|
+
row serves several. The patches the runs return are laid together, and the
|
|
205
|
+
refresh set runs once. A `url()` returned for one of several rows is
|
|
206
|
+
reported and ignored. A declared request receives `keys` as it is.
|
|
207
|
+
|
|
208
|
+
`rows` holds the rows of a query nested in the form the request came from,
|
|
209
|
+
by query name, each with its `key` and the `values` of its own controls; see
|
|
210
|
+
[A form over a set of rows](./data-binding.md#a-form-over-a-set-of-rows).
|
|
211
|
+
The handler writes the master and its details together, deciding what each
|
|
212
|
+
row's values mean, such as an empty amount being no row at all:
|
|
213
|
+
|
|
214
|
+
```ts
|
|
215
|
+
rowInsert: {
|
|
216
|
+
run: async (ctx, { values, rows }) => {
|
|
217
|
+
const id = await ctx.db.insertPaycheck(values);
|
|
218
|
+
for (const { key, values: row } of rows?.deduction_types ?? []) {
|
|
219
|
+
if (row.amount !== "") await ctx.db.insertDeduction(id, key, row.amount);
|
|
220
|
+
}
|
|
221
|
+
},
|
|
222
|
+
refresh: ["paychecks"],
|
|
223
|
+
},
|
|
224
|
+
```
|
|
225
|
+
|
|
187
226
|
```ts
|
|
188
227
|
// src/pages/directory.requests.ts
|
|
189
228
|
import { patch, type Requests } from "@loadbare/app/server";
|
|
@@ -240,16 +279,14 @@ queries:
|
|
|
240
279
|
|
|
241
280
|
Return a patch for a change the request knows the extent of — one row added,
|
|
242
281
|
one row dropped, one row edited — and leave `refresh` empty. A refreshed
|
|
243
|
-
`rows` query sends every row
|
|
244
|
-
each element and takes focus from the control the user is in.
|
|
282
|
+
`rows` query sends every row to say what one row could.
|
|
245
283
|
|
|
246
284
|
A change that seems to need a refresh usually has a patch:
|
|
247
285
|
|
|
248
|
-
- A
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
[`lb-table`](./widgets.md#lb-table) does by `data-sort`.
|
|
286
|
+
- A row whose position changes: the hub places it by the query's
|
|
287
|
+
[order](./data-binding.md#order).
|
|
288
|
+
- A group that appears or goes: the hub makes a group with its first row
|
|
289
|
+
and removes it with its last, so no row stands in for an empty one.
|
|
253
290
|
- A row whose other columns change with the edit: re-read the row and patch
|
|
254
291
|
it.
|
|
255
292
|
- Rows the database removes with a deleted one: select their keys before the
|
|
@@ -324,3 +361,48 @@ Post/Redirect/Get without the redirect. The refresh set does not run, and
|
|
|
324
361
|
nothing else `run` returned is sent, since both answered for the URL the page
|
|
325
362
|
left. The loaded page reads the new parms through `contextFor`; see
|
|
326
363
|
[the Express server](./server.md#database-layer).
|
|
364
|
+
|
|
365
|
+
### Refusing a request
|
|
366
|
+
|
|
367
|
+
A handler refuses a request by throwing `refusal()`, with words written for
|
|
368
|
+
the user:
|
|
369
|
+
|
|
370
|
+
```ts
|
|
371
|
+
import { refusal, type Requests } from "@loadbare/app/server";
|
|
372
|
+
|
|
373
|
+
export const requests: Requests = {
|
|
374
|
+
handlers: {
|
|
375
|
+
enterPaycheck: {
|
|
376
|
+
run: async (ctx, { values }) => {
|
|
377
|
+
if (Number(values!.amount) <= 0) {
|
|
378
|
+
throw refusal({ amount: "Must be more than zero" });
|
|
379
|
+
}
|
|
380
|
+
const overlap = await ctx.db.overlappingSeries(values!);
|
|
381
|
+
if (overlap) {
|
|
382
|
+
throw refusal(
|
|
383
|
+
`That series already has paychecks from ${overlap.from} through ${overlap.to}.`,
|
|
384
|
+
);
|
|
385
|
+
}
|
|
386
|
+
await ctx.db.enterPaycheck(values!);
|
|
387
|
+
},
|
|
388
|
+
refresh: ["paychecks"],
|
|
389
|
+
},
|
|
390
|
+
},
|
|
391
|
+
};
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
| Call | The browser shows |
|
|
395
|
+
|----------------------------------|--------------------------------------------|
|
|
396
|
+
| `refusal("message")` | The message, for the request as a whole |
|
|
397
|
+
| `refusal({ column: "message" })` | Each message on the control for its column |
|
|
398
|
+
| `refusal("message", { ... })` | Both |
|
|
399
|
+
|
|
400
|
+
Throw it, from the handler or from anything the handler calls, and whatever
|
|
401
|
+
the application has open rolls back as for any throw. A column names a
|
|
402
|
+
control the request gathered. See [Refusals](./data-binding.md#refusals)
|
|
403
|
+
for how the browser shows them.
|
|
404
|
+
|
|
405
|
+
A refusal is the only error whose words reach the browser. Anything else a
|
|
406
|
+
handler throws is a failure, answered with nothing in it, so a stack or a
|
|
407
|
+
database message never reaches a page.
|
|
408
|
+
|
|
@@ -72,6 +72,26 @@ path, so the application cannot be hosted under a subpath such as
|
|
|
72
72
|
whole path space through unchanged.
|
|
73
73
|
|
|
74
74
|
Leave `express.json()` to `hubRoutes`, which mounts it on its own routes.
|
|
75
|
+
Pass its options through `hubRoutes` instead.
|
|
76
|
+
|
|
77
|
+
## Options
|
|
78
|
+
|
|
79
|
+
`hubRoutes` takes an optional third argument, an object with one key per
|
|
80
|
+
concern:
|
|
81
|
+
|
|
82
|
+
| Option | Description |
|
|
83
|
+
|--------|----------------------------------------------------------|
|
|
84
|
+
| `json` | Options for `express.json()`, passed to it unchanged |
|
|
85
|
+
|
|
86
|
+
A request body over 100 KB, the `express.json()` default, is refused with a
|
|
87
|
+
413 before any handler runs, and the server log names the option that raises
|
|
88
|
+
it. Raise it for an application whose pages send a file's text as a value:
|
|
89
|
+
|
|
90
|
+
```ts
|
|
91
|
+
app.use(hubRoutes(hub, contextFor, { json: { limit: "5mb" } }));
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
The limit covers every page's requests.
|
|
75
95
|
|
|
76
96
|
## Running the server
|
|
77
97
|
|
|
@@ -91,6 +111,10 @@ TypeScript types itself. `dist/pages.ts` imports each `.requests.ts` and
|
|
|
91
111
|
`.queries.ts` file by its full name, extension included, because Node looks
|
|
92
112
|
for exactly the path an import names.
|
|
93
113
|
|
|
114
|
+
The `hub` it exports comes from `createHub`, the only implementation of
|
|
115
|
+
the `Hub` interface. That interface may gain members in any release, so an
|
|
116
|
+
application never implements it.
|
|
117
|
+
|
|
94
118
|
Enable `allowImportingTsExtensions` in the application's `tsconfig.json`
|
|
95
119
|
when `tsc` type-checks the server. Without it, `tsc` rejects the `.ts`
|
|
96
120
|
extensions in `dist/pages.ts`:
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# The Basic Widget Library
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
`lb-unknown-page
|
|
3
|
+
Eleven widgets: `lb-input`, `lb-select`, `lb-options`, `lb-picker`,
|
|
4
|
+
`lb-table`, `lb-unknown-page`, `lb-confirm`, `lb-form`, `lb-insert-dialog`,
|
|
5
|
+
`lb-master` and `lb-checkbox`. Every one of them is an ordinary custom element, written
|
|
5
6
|
against the contracts in [Custom Elements](./custom-elements.md#html) for its
|
|
6
7
|
definition and [Custom Elements](./custom-elements.md#code) for its class.
|
|
7
8
|
|
|
@@ -25,7 +26,9 @@ for where a listed package sits in the cascade.
|
|
|
25
26
|
`lb-input`, `lb-select`, `lb-options` and `lb-picker` are controls:
|
|
26
27
|
form-associated custom elements with a `value` property that fire `change`.
|
|
27
28
|
Each carries `lb-column` and `lb-request` itself, the way an `<input>` does;
|
|
28
|
-
see [Being a control](./custom-elements.md#being-a-control).
|
|
29
|
+
see [Being a control](./custom-elements.md#being-a-control). Each passes a
|
|
30
|
+
refusal's message for its column to the native control inside it; see
|
|
31
|
+
[Refusals](./data-binding.md#refusals).
|
|
29
32
|
|
|
30
33
|
## `lb-input`
|
|
31
34
|
|
|
@@ -43,6 +46,7 @@ write the same edit twice.
|
|
|
43
46
|
| Parameter | Fills |
|
|
44
47
|
|----------------|----------------------------------|
|
|
45
48
|
| `exp-label` | The visible `<label>` text |
|
|
49
|
+
| `exp-type` | The input's `type`, `text` when absent |
|
|
46
50
|
| `exp-readonly` | The input's `readonly` attribute |
|
|
47
51
|
|
|
48
52
|
## `lb-select`
|
|
@@ -67,9 +71,7 @@ writes the row template inside the widget:
|
|
|
67
71
|
|
|
68
72
|
```html
|
|
69
73
|
<lb-options lb-query="statuses" lb-column="status" lb-request="lb-row-update" exp-label="Status">
|
|
70
|
-
<template
|
|
71
|
-
<option lb-column="label"></option>
|
|
72
|
-
</template>
|
|
74
|
+
<template><option lb-column="label"></option></template>
|
|
73
75
|
</lb-options>
|
|
74
76
|
```
|
|
75
77
|
|
|
@@ -79,9 +81,15 @@ writes the row template inside the widget:
|
|
|
79
81
|
|
|
80
82
|
- Each option's `value` is its row's key, the `lb-key-value` the hub stamps
|
|
81
83
|
on the live row, so the widget holds a key and shows a label.
|
|
82
|
-
-
|
|
83
|
-
|
|
84
|
-
|
|
84
|
+
- A group template holding an `<optgroup>` puts the options in groups, one
|
|
85
|
+
per run of the query's order's leading term. The widget labels each
|
|
86
|
+
`<optgroup>` from the `lb-group-value` the hub stamps on it:
|
|
87
|
+
|
|
88
|
+
```html
|
|
89
|
+
<template lb-group>
|
|
90
|
+
<optgroup><template><option lb-column="label"></option></template></optgroup>
|
|
91
|
+
</template>
|
|
92
|
+
```
|
|
85
93
|
- Its `value` selects the option with that key, including an option that
|
|
86
94
|
arrives after the value did.
|
|
87
95
|
|
|
@@ -100,7 +108,6 @@ one option showing one column:
|
|
|
100
108
|
lb-request="lb-row-update"
|
|
101
109
|
exp-label="Status"
|
|
102
110
|
exp-column="label"
|
|
103
|
-
exp-group="category"
|
|
104
111
|
></lb-picker>
|
|
105
112
|
```
|
|
106
113
|
|
|
@@ -108,10 +115,9 @@ one option showing one column:
|
|
|
108
115
|
|--------------|-----------------------------------------|
|
|
109
116
|
| `exp-label` | The visible `<label>` text |
|
|
110
117
|
| `exp-column` | The column each option shows |
|
|
111
|
-
| `exp-group` | The row template's `data-group` |
|
|
112
118
|
|
|
113
|
-
An option built from two columns,
|
|
114
|
-
`lb-options` with the page's own
|
|
119
|
+
An option built from two columns, a row with a second element, or options
|
|
120
|
+
in groups, is `lb-options` with the page's own templates.
|
|
115
121
|
|
|
116
122
|
## `lb-table`
|
|
117
123
|
|
|
@@ -123,11 +129,14 @@ row, the row template, and optionally a footer, each as a `<template>`:
|
|
|
123
129
|
<template lb-exp-template="head">
|
|
124
130
|
<tr><th>Date</th><th>Amount</th></tr>
|
|
125
131
|
</template>
|
|
126
|
-
<template
|
|
127
|
-
<tr><
|
|
132
|
+
<template lb-group>
|
|
133
|
+
<tr><th colspan="2" lb-column="month"></th></tr>
|
|
134
|
+
<template>
|
|
135
|
+
<tr><td lb-column="date"></td><td lb-column="amount"></td></tr>
|
|
136
|
+
</template>
|
|
128
137
|
</template>
|
|
129
138
|
<template lb-exp-template="foot">
|
|
130
|
-
<tr
|
|
139
|
+
<tr><td>Total</td><td lb-sum="amount"></td></tr>
|
|
131
140
|
</template>
|
|
132
141
|
</lb-table>
|
|
133
142
|
```
|
|
@@ -140,15 +149,99 @@ row, the row template, and optionally a footer, each as a `<template>`:
|
|
|
140
149
|
|-----------------------------------|-----------------------------------------|
|
|
141
150
|
| `<template lb-exp-template="head">` | The `<thead>` |
|
|
142
151
|
| `<template lb-exp-template="foot">` | The `<tfoot>` |
|
|
143
|
-
| Any other `<template>` | The row template, in the `<tbody>`
|
|
144
|
-
|
|
145
|
-
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
+
| Any other `<template>` | The row or group template, in the `<tbody>` |
|
|
153
|
+
|
|
154
|
+
- The hub places the rows by the query's order and builds its groups. The
|
|
155
|
+
rows land in the one `<tbody>`, so a group here is a heading row with its
|
|
156
|
+
rows after it.
|
|
157
|
+
- The footer is not a row of `ledger`. An aggregate there covers every row;
|
|
158
|
+
a figure that is not a sum of the rows, such as a budget, is a `<tr>`
|
|
159
|
+
naming a `row` query of its own.
|
|
160
|
+
- A `<template lb-exp-template="ghost">` is a blank row for entering a new
|
|
161
|
+
one, in a `<tbody>` of its own. The widget joins its controls to a form
|
|
162
|
+
outside the table, since a `<form>` cannot wrap a `<tr>`, and puts the
|
|
163
|
+
cursor back in it once an insert from it succeeds.
|
|
164
|
+
- After rows land, the widget scrolls the row the page's own request created
|
|
165
|
+
or moved into view.
|
|
166
|
+
|
|
167
|
+
## `lb-confirm`
|
|
168
|
+
|
|
169
|
+
A button that asks before it sends. The page writes the question inside the
|
|
170
|
+
tag, and the request goes on the dialog's confirm button, so nothing reaches
|
|
171
|
+
the hub until the user says yes:
|
|
172
|
+
|
|
173
|
+
```html
|
|
174
|
+
<lb-confirm exp-label="Delete" exp-request="lb-row-delete">
|
|
175
|
+
Delete <b lb-column="name"></b>?
|
|
176
|
+
</lb-confirm>
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
| Parameter | Fills |
|
|
180
|
+
|---------------|--------------------------------------------------|
|
|
181
|
+
| `exp-label` | The text of the button that opens the dialog |
|
|
182
|
+
| `exp-request` | The confirm button's `lb-request` |
|
|
183
|
+
| `exp-confirm` | The confirm button's text, `Confirm` when absent |
|
|
184
|
+
|
|
185
|
+
The widget closes the dialog once `lb-request-done` says the request
|
|
186
|
+
succeeded, and leaves it open on a refusal.
|
|
187
|
+
|
|
188
|
+
## `lb-form`
|
|
189
|
+
|
|
190
|
+
A `<form>` over one row's controls. A row with a key saves each control's
|
|
191
|
+
column on `change`; a row whose key is empty is new, and the hub sends no
|
|
192
|
+
update for it, so its controls wait for a submit. A definition only.
|
|
193
|
+
|
|
194
|
+
| Parameter | Fills |
|
|
195
|
+
|-----------|-----------------|
|
|
196
|
+
| `exp-id` | The form's `id` |
|
|
197
|
+
|
|
198
|
+
## `lb-insert-dialog`
|
|
199
|
+
|
|
200
|
+
A row entered in a modal dialog, written once outside every row and opened
|
|
201
|
+
with `commandfor` and `command="show-modal"`. Save is the form's
|
|
202
|
+
`lb-row-insert`; on success the widget chooses the new row in the nearest
|
|
203
|
+
`lb-options` around the button that opened it, and closes. The handler
|
|
204
|
+
answers with a patch holding the new row.
|
|
205
|
+
|
|
206
|
+
| Parameter | Fills |
|
|
207
|
+
|-------------|---------------------------------------------------|
|
|
208
|
+
| `exp-id` | The dialog's `id` |
|
|
209
|
+
| `exp-title` | The dialog's heading |
|
|
210
|
+
| `exp-query` | The form's `lb-query`, which it inserts into |
|
|
211
|
+
| `exp-save` | The Save button's text, `Save` when absent |
|
|
212
|
+
|
|
213
|
+
## `lb-master`
|
|
214
|
+
|
|
215
|
+
A set, one of its rows, and the buttons that act on the set: New, Copy,
|
|
216
|
+
Delete, Save new and Cancel, each shown only for a row on record or a new
|
|
217
|
+
one. A definition only, built from `lb-form` and `lb-confirm`. New sends
|
|
218
|
+
`new` and Copy sends `copy`, requests the page declares; `new` returns
|
|
219
|
+
`url()` emptying the parm that names the row.
|
|
220
|
+
|
|
221
|
+
| Parameter | Fills |
|
|
222
|
+
|---------------|--------------------------------------------|
|
|
223
|
+
| `exp-row` | The `lb-query` of the row the form shows |
|
|
224
|
+
| `exp-form-id` | The form's `id`, `master-form` when absent |
|
|
225
|
+
|
|
226
|
+
## `lb-checkbox`
|
|
227
|
+
|
|
228
|
+
A checkbox and its label as one element, for an application to style. A
|
|
229
|
+
definition only: a native checkbox is already a control (see
|
|
230
|
+
[Checkboxes](./data-binding.md#checkboxes)), so the widget is the markup, a
|
|
231
|
+
`<label>` holding the `<input type="checkbox">` and a `<span>` with the
|
|
232
|
+
text. The column and request go on the checkbox inside, so they arrive as
|
|
233
|
+
expansion attributes.
|
|
234
|
+
|
|
235
|
+
Unlike `lb-input`, it has no script making the tag the control. A value
|
|
236
|
+
that lands before a widget's script has loaded arrives only as the string
|
|
237
|
+
stamp `lb-column-value`, and a script checkbox would read `"false"` as
|
|
238
|
+
checked. The hub sets a native checkbox's `checked` directly.
|
|
239
|
+
|
|
240
|
+
| Parameter | Fills |
|
|
241
|
+
|---------------|-----------------------------------------------|
|
|
242
|
+
| `exp-column` | The checkbox's `lb-column` |
|
|
243
|
+
| `exp-label` | The label's text |
|
|
244
|
+
| `exp-request` | The checkbox's `lb-request`, none when absent |
|
|
152
245
|
|
|
153
246
|
## `lb-unknown-page`
|
|
154
247
|
|