@loadbare/app 0.25.0 → 0.27.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 +1 -2
- package/dist/build/assemble.d.ts.map +1 -1
- package/dist/build/assemble.js +31 -37
- package/dist/build/assemble.js.map +1 -1
- package/dist/build/cli.d.ts +4 -10
- package/dist/build/cli.d.ts.map +1 -1
- package/dist/build/cli.js +11 -33
- package/dist/build/cli.js.map +1 -1
- package/dist/build/declared.js +1 -1
- package/dist/build/declared.js.map +1 -1
- package/dist/core/lb-constants.d.ts +15 -13
- package/dist/core/lb-constants.d.ts.map +1 -1
- package/dist/core/lb-constants.js +47 -51
- package/dist/core/lb-constants.js.map +1 -1
- package/dist/core/lb-types.d.ts +12 -11
- package/dist/core/lb-types.d.ts.map +1 -1
- package/dist/core/lb-types.js +7 -0
- package/dist/core/lb-types.js.map +1 -1
- package/dist/hub/lb-apply.d.ts +10 -34
- package/dist/hub/lb-apply.d.ts.map +1 -1
- package/dist/hub/lb-apply.js +92 -151
- 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 +115 -127
- package/dist/hub/lb-hub.browser.js.map +1 -1
- package/dist/hub/lb-lifecycle.d.ts.map +1 -1
- package/dist/hub/lb-lifecycle.js +4 -11
- package/dist/hub/lb-lifecycle.js.map +1 -1
- package/dist/server/lb-express.d.ts.map +1 -1
- package/dist/server/lb-express.js +3 -3
- package/dist/server/lb-express.js.map +1 -1
- package/dist/server/lb-server.d.ts +35 -19
- package/dist/server/lb-server.d.ts.map +1 -1
- package/dist/server/lb-server.js +141 -88
- package/dist/server/lb-server.js.map +1 -1
- package/docs/binding-cases.md +150 -0
- package/docs/comparison.md +34 -38
- package/docs/opinions.md +2 -2
- package/docs/reference/chrome.md +8 -10
- package/docs/reference/css.md +9 -10
- package/docs/reference/custom-elements.md +11 -8
- package/docs/reference/data-binding.md +93 -134
- package/docs/reference/names.md +21 -22
- package/docs/reference/page-files.md +24 -26
- package/docs/reference/server.md +3 -4
- package/docs/roadmap.md +2 -2
- package/docs/testing.md +5 -6
- package/package.json +1 -1
- package/skills/loadbare-app/SKILL.md +55 -48
- package/skills/loadbare-app/references/chrome.md +8 -10
- package/skills/loadbare-app/references/css.md +9 -10
- package/skills/loadbare-app/references/custom-elements.md +11 -8
- package/skills/loadbare-app/references/data-binding.md +93 -134
- package/skills/loadbare-app/references/names.md +21 -22
- package/skills/loadbare-app/references/page-files.md +24 -26
- package/skills/loadbare-app/references/server.md +3 -4
package/docs/reference/chrome.md
CHANGED
|
@@ -101,7 +101,6 @@ server's row lands, so a chrome shows where the page is with no code:
|
|
|
101
101
|
|-------------------|---------------------------------------------------------|
|
|
102
102
|
| `lb-path` | The path, such as `/members`. The row's key |
|
|
103
103
|
| `lb-page-label` | The page's title, or its stub when it has none |
|
|
104
|
-
| `lb-page-unknown` | `true` when no page's stub matches the path |
|
|
105
104
|
| Any other name | The query parm of that name, or empty when it is absent |
|
|
106
105
|
|
|
107
106
|
The path names a page, never a resource: `/accounts/42` is not a way to
|
|
@@ -116,9 +115,9 @@ page file carries; see [page files](./page-files.md#the-page-title). The hub
|
|
|
116
115
|
sets the document title to `lb-page-label` whenever it is not null, so the
|
|
117
116
|
tab and the browser history show the page.
|
|
118
117
|
|
|
119
|
-
`lb-url` is one of
|
|
120
|
-
declare. The
|
|
121
|
-
names
|
|
118
|
+
`lb-url` is one of the queries a page may use that the server does not
|
|
119
|
+
declare. The others are `lb-sort`, `lb-filters` and `lb-hub-status`. A page
|
|
120
|
+
names any the same way, anywhere inside the hub.
|
|
122
121
|
|
|
123
122
|
### Where focus starts
|
|
124
123
|
|
|
@@ -223,8 +222,8 @@ pushes one instead when the element carrying `lb-request` also carries
|
|
|
223
222
|
The hub answers the request itself, with no round trip, then reloads the
|
|
224
223
|
page's queries at the new URL. The page stays in place, and rows that come
|
|
225
224
|
back keep their place. A request that leaves the URL as it was does
|
|
226
|
-
nothing. `lb-page-label`
|
|
227
|
-
never sets
|
|
225
|
+
nothing. `lb-page-label` is the hub's, and a request
|
|
226
|
+
never sets it.
|
|
228
227
|
|
|
229
228
|
A request that gives `lb-path` a new value enters that page, pushes a
|
|
230
229
|
history entry, and the new URL carries only the query parms the request
|
|
@@ -288,8 +287,8 @@ it; a per-session database role means an id outside the caller's reach
|
|
|
288
287
|
finds nothing.
|
|
289
288
|
|
|
290
289
|
An order or a filter the hub applies to rows the page already holds is not
|
|
291
|
-
a query parm. It is a [
|
|
292
|
-
the page changes.
|
|
290
|
+
a query parm. It is a [sort or a filter](./data-binding.md#sort-and-filters),
|
|
291
|
+
which holds until the page changes.
|
|
293
292
|
|
|
294
293
|
The hub sends the query parms with every round trip, and the server hands
|
|
295
294
|
them to `contextFor`; see [the Express server](./server.md#database-layer).
|
|
@@ -308,8 +307,7 @@ show the path:
|
|
|
308
307
|
</dialog>
|
|
309
308
|
```
|
|
310
309
|
|
|
311
|
-
When
|
|
312
|
-
`lb-page-label` is null, `<main>` keeps the page it had, the hub calls
|
|
310
|
+
When the path names a page that does not exist, `lb-page-label` is null, `<main>` keeps the page it had, the hub calls
|
|
313
311
|
`showModal()` on the dialog, and reports the path to the console. A chrome
|
|
314
312
|
with no dialog shows nothing. `lb-url` lands before the page is looked up,
|
|
315
313
|
so the dialog shows the path by naming it like any other element.
|
package/docs/reference/css.md
CHANGED
|
@@ -69,7 +69,6 @@ in the stamp, so the selector reads the number and not its text. See
|
|
|
69
69
|
| Select | For |
|
|
70
70
|
|----------------------|-------------------------------------------------|
|
|
71
71
|
| `[lb-row-live]` | Every live row of a list |
|
|
72
|
-
| `[lb-row-selected]` | A row its `lb-select` checkbox ticks |
|
|
73
72
|
| `[lb-row-editing]` | The row a pointed form is editing |
|
|
74
73
|
| `[lb-key-value="…"]` | One row, by its key |
|
|
75
74
|
| `[hidden]` | A row a filter hides; the browser hides it |
|
|
@@ -86,11 +85,10 @@ landed inside a list, such as a total in a table's foot, carries a key and
|
|
|
86
85
|
is not one of the list's rows.
|
|
87
86
|
|
|
88
87
|
```css
|
|
89
|
-
[lb-row-selected] { background: var(--selected); }
|
|
90
88
|
[lb-row-editing] { outline: 2px solid var(--accent); }
|
|
91
89
|
```
|
|
92
90
|
|
|
93
|
-
See [Rows](./data-binding.md#rows)
|
|
91
|
+
See [Rows](./data-binding.md#rows)
|
|
94
92
|
and [Editing a row in one form](./data-binding.md#editing-a-row-in-one-form).
|
|
95
93
|
|
|
96
94
|
### A group
|
|
@@ -179,18 +177,19 @@ form:not([lb-key-value=""]) .save-new { display: none; }
|
|
|
179
177
|
|
|
180
178
|
See [Editing a row in one form](./data-binding.md#editing-a-row-in-one-form).
|
|
181
179
|
|
|
182
|
-
### The user's
|
|
180
|
+
### The user's order and filters
|
|
183
181
|
|
|
184
|
-
|
|
185
|
-
element showing
|
|
186
|
-
it with `:has()`:
|
|
182
|
+
The order the user chose is the `order` column of `lb-sort`, and a filter
|
|
183
|
+
is a column of `lb-filters`, so the element showing either carries it as
|
|
184
|
+
`lb-column-value`. Style anything else by it with `:has()`:
|
|
187
185
|
|
|
188
186
|
```css
|
|
189
|
-
|
|
190
|
-
|
|
187
|
+
:has([lb-column="name"][lb-column-value="^=Amazon"]) th.name::after {
|
|
188
|
+
content: "🔍";
|
|
189
|
+
}
|
|
191
190
|
```
|
|
192
191
|
|
|
193
|
-
See [
|
|
192
|
+
See [Sort and filters](./data-binding.md#sort-and-filters).
|
|
194
193
|
|
|
195
194
|
### Content shown by condition
|
|
196
195
|
|
|
@@ -572,18 +572,21 @@ missing a field its name needs, and stamps the dispatching element with
|
|
|
572
572
|
|
|
573
573
|
Let the event bubble, so an ancestor can stop it before the hub sends it.
|
|
574
574
|
|
|
575
|
-
A request with `lb-row-update` for `lb-url`
|
|
576
|
-
|
|
577
|
-
|
|
575
|
+
A request with `lb-row-update` for `lb-url` is keyed by the path; one for
|
|
576
|
+
`lb-sort` or `lb-filters` is keyed by the query's name. An element anywhere
|
|
577
|
+
on the page may set a query parm or make a
|
|
578
|
+
[sort or a filter](./data-binding.md#sort-and-filters) without sitting
|
|
579
|
+
inside the query:
|
|
578
580
|
|
|
579
581
|
```ts
|
|
580
|
-
import {
|
|
582
|
+
import { SORT_QUERY, LB_EVENT_NAME, REQUEST_ROW_UPDATE } from "@loadbare/app/constants";
|
|
581
583
|
import type { HubRequest } from "@loadbare/app/types";
|
|
582
584
|
|
|
583
585
|
const detail: HubRequest = {
|
|
584
586
|
name: REQUEST_ROW_UPDATE,
|
|
585
|
-
query:
|
|
586
|
-
|
|
587
|
+
query: SORT_QUERY,
|
|
588
|
+
key: "ledger",
|
|
589
|
+
values: { order: "-amount" },
|
|
587
590
|
};
|
|
588
591
|
this.dispatchEvent(new CustomEvent(LB_EVENT_NAME, { bubbles: true, detail }));
|
|
589
592
|
```
|
|
@@ -616,8 +619,8 @@ listener. Import its name as `LB_DONE_EVENT_NAME`.
|
|
|
616
619
|
`items` is every response item that landed because of the request, in
|
|
617
620
|
order. `refusal` is set beside `error` when the handler refused the
|
|
618
621
|
request, holding its `message` and `columns`. An answer that moved the URL contributes its `lb-url` item, which
|
|
619
|
-
carries a key only the server knew, and the page load. A
|
|
620
|
-
the row of `lb-
|
|
622
|
+
carries a key only the server knew, and the page load. A sort or a filter contributes
|
|
623
|
+
the row of `lb-sort` or `lb-filters` it made. `error` is set when
|
|
621
624
|
the round trip failed, and then nothing landed. A new row's key is in the
|
|
622
625
|
answer only when the handler returned it in a patch: a refresh sends all
|
|
623
626
|
rows, and nothing marks which one is new.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
A page shows server data by naming queries and columns in its HTML, and asks
|
|
4
4
|
the server to change that data by naming requests. The developer writes
|
|
5
|
-
|
|
5
|
+
ten `lb-` attributes. The server declares every query a page may show and
|
|
6
6
|
every request it may send, and refuses anything it has not declared.
|
|
7
7
|
|
|
8
8
|
Everything is a query. A query is a name for rows, of kind `row` or `rows`,
|
|
@@ -46,12 +46,9 @@ each with its key, and permits the three requests on `roster`; see
|
|
|
46
46
|
| `lb-query` | Any element | The query whose rows land in it |
|
|
47
47
|
| `lb-column` | Any element | The column it shows, and the column it gathers |
|
|
48
48
|
| `lb-show` | Any element but `<template>` | The column that decides whether it is present |
|
|
49
|
-
| `lb-
|
|
50
|
-
| `lb-filter` | An element with `lb-query` | The columns a choice filters; see [Filters](#filters) |
|
|
49
|
+
| `lb-filter` | An element with `lb-query` | The columns the user may filter; see [Filters](#filters) |
|
|
51
50
|
| `lb-group` | A `<template>` | Nothing: it marks a group template; see [Groups](#groups) |
|
|
52
|
-
| `lb-
|
|
53
|
-
| `lb-sum`, `lb-avg`, `lb-min`, `lb-max` | Any element | The column aggregated; see [Aggregates](#aggregates) |
|
|
54
|
-
| `lb-select` | A checkbox in a row template | Nothing: it selects its live row; see [Selecting rows](#selecting-rows) |
|
|
51
|
+
| `lb-aggregate` | Any element | The function it applies to `lb-column`; see [Aggregates](#aggregates) |
|
|
55
52
|
| `lb-request` | Any element | The request it sends when it commits |
|
|
56
53
|
| `lb-url-link` | An `<a>` | A link between pages; see [chrome](./chrome.md#links) |
|
|
57
54
|
| `lb-url-parm` | An `<a lb-url-link>` in a row | Columns of the row its `href` carries as parms; see [chrome](./chrome.md#a-link-from-a-row) |
|
|
@@ -73,7 +70,6 @@ builder writes a stamp, and a stylesheet or a custom element reads it.
|
|
|
73
70
|
| `lb-row-created`, `lb-row-changed`, `lb-row-moved`, `lb-row-requested`, `lb-row-unplaced` | What happened to a row; see [What happened to a row](#what-happened-to-a-row) |
|
|
74
71
|
| `lb-row-leaving`, `lb-group-leaving` | A row or group on its way out |
|
|
75
72
|
| `lb-row-editing` | The row a form is pointed at; see [Editing a row in one form](#editing-a-row-in-one-form) |
|
|
76
|
-
| `lb-row-selected` | A row whose `lb-select` is ticked |
|
|
77
73
|
| `lb-request-pending` | The element's request is in flight |
|
|
78
74
|
| `lb-request-error` | The element's last request failed |
|
|
79
75
|
| `lb-request-refused` | The handler refused it; see [Refusals](#refusals) |
|
|
@@ -185,7 +181,7 @@ or `""`:
|
|
|
185
181
|
|
|
186
182
|
A checkbox lands what it sends, so it shows the same state after a round
|
|
187
183
|
trip through a query whose values are strings, such as `lb-url` or
|
|
188
|
-
`lb-
|
|
184
|
+
`lb-filters`. A query parm the URL does not carry lands as `""`, so the
|
|
189
185
|
checkbox is unchecked. Unchecked sends `"false"` rather than nothing, so a
|
|
190
186
|
flag can be set back. A checkbox carrying a `value` attribute is not a flag
|
|
191
187
|
but one of a set, holding a query parm the URL repeats; see
|
|
@@ -271,25 +267,22 @@ roster: rows("id", (ctx) => ctx.db.members(), { order: "team,name" }),
|
|
|
271
267
|
With no order, rows show in the order they arrived, and a patch's new rows
|
|
272
268
|
go last.
|
|
273
269
|
|
|
274
|
-
The user's order replaces the server's.
|
|
275
|
-
|
|
276
|
-
column holds an order written the same way
|
|
277
|
-
server's order places the rows:
|
|
270
|
+
The user's order replaces the server's. The hub serves the query
|
|
271
|
+
[`lb-sort`](#sort-and-filters), one row per `rows` query, keyed by the
|
|
272
|
+
query's name, whose `order` column holds an order written the same way.
|
|
273
|
+
While it is empty, the server's order places the rows:
|
|
278
274
|
|
|
279
275
|
```html
|
|
280
|
-
<
|
|
281
|
-
<select lb-column="roster_order" lb-request="lb-row-update">
|
|
282
|
-
<option value="">By team</option>
|
|
283
|
-
<option value="name">By name</option>
|
|
284
|
-
<option value="-joined">Newest first</option>
|
|
285
|
-
</select>
|
|
286
|
-
</div>
|
|
287
|
-
|
|
288
|
-
<ul lb-query="roster" lb-order="roster_order">
|
|
276
|
+
<ul lb-query="roster">
|
|
289
277
|
<template><li lb-column="name"></li></template>
|
|
290
278
|
</ul>
|
|
291
279
|
```
|
|
292
280
|
|
|
281
|
+
A control makes a choice by sending `lb-row-update` for `lb-sort`, keyed by
|
|
282
|
+
the query's name; the `<lb-table>` widget's sortable headings do this for
|
|
283
|
+
each column. The hub places the rows again from the ones it already holds,
|
|
284
|
+
and tells the server through `onChoices`.
|
|
285
|
+
|
|
293
286
|
| Values | Compare |
|
|
294
287
|
|----------------------|----------------------------------------------|
|
|
295
288
|
| Two numbers | Numerically |
|
|
@@ -321,7 +314,7 @@ user works through them. It names `order`, `filter` or both, separated by a
|
|
|
321
314
|
space:
|
|
322
315
|
|
|
323
316
|
```html
|
|
324
|
-
<lb-table lb-query="entries"
|
|
317
|
+
<lb-table lb-query="entries"
|
|
325
318
|
lb-filter="description, is_unmatched" lb-manual="order filter">
|
|
326
319
|
```
|
|
327
320
|
|
|
@@ -382,20 +375,19 @@ the move.
|
|
|
382
375
|
|
|
383
376
|
Write `lb-filter` on the element carrying `lb-query`, naming the columns of
|
|
384
377
|
its rows the user may filter, separated by commas. The column of
|
|
385
|
-
[`lb-
|
|
378
|
+
[`lb-filters`](#sort-and-filters) of the same name holds the filter for
|
|
379
|
+
each:
|
|
386
380
|
|
|
387
381
|
```html
|
|
388
|
-
<div lb-query="lb-choices">
|
|
389
|
-
<input lb-column="name" lb-request="lb-row-update" placeholder="Name" />
|
|
390
|
-
</div>
|
|
391
|
-
|
|
392
382
|
<ul lb-query="roster" lb-filter="name, team">
|
|
393
383
|
<template><li lb-column="name"></li></template>
|
|
394
384
|
</ul>
|
|
395
385
|
```
|
|
396
386
|
|
|
397
|
-
A
|
|
398
|
-
|
|
387
|
+
A filter is made by sending `lb-row-update` for `lb-filters`, keyed by the
|
|
388
|
+
query's name; the `<lb-table>` widget's selection does this.
|
|
389
|
+
|
|
390
|
+
A row that does not pass every filter is `hidden`. Under `lb-manual="filter"`, a row an answer changed stays
|
|
399
391
|
showing until the rows are placed again; see
|
|
400
392
|
[Placing by hand](#placing-by-hand). A group whose rows are all hidden is hidden too
|
|
401
393
|
([miswart](../miswarts.md#rows-hidden-by-a-filter)). An empty
|
|
@@ -494,23 +486,24 @@ group, and are reported once.
|
|
|
494
486
|
|
|
495
487
|
### Aggregates
|
|
496
488
|
|
|
497
|
-
`lb-
|
|
498
|
-
|
|
499
|
-
|
|
489
|
+
`lb-aggregate` sets an element from the rows of the nearest group around
|
|
490
|
+
it, or of the whole list outside any group. It names the function, and
|
|
491
|
+
`lb-column` names the column:
|
|
500
492
|
|
|
501
493
|
```html
|
|
502
|
-
<tr><td><span lb-count></span> people</td><td lb-sum="salary"></td></tr>
|
|
494
|
+
<tr><td><span lb-aggregate="count"></span> people</td><td lb-aggregate="sum" lb-column="salary"></td></tr>
|
|
503
495
|
```
|
|
504
496
|
|
|
505
|
-
|
|
|
497
|
+
| `lb-aggregate` | Sets the element to |
|
|
506
498
|
|----------------|-----------------------------------------------------------|
|
|
507
|
-
| `
|
|
508
|
-
| `
|
|
509
|
-
| `
|
|
510
|
-
| `
|
|
511
|
-
| `
|
|
512
|
-
|
|
513
|
-
An aggregate lands as a column does, with `lb-column-value
|
|
499
|
+
| `count` | The number of rows; with `lb-column`, the values in it that are not null |
|
|
500
|
+
| `sum` | The sum of the column |
|
|
501
|
+
| `avg` | The average of the column |
|
|
502
|
+
| `min` | The least value of the column, by the [order](#order)'s comparison |
|
|
503
|
+
| `max` | The greatest, likewise |
|
|
504
|
+
|
|
505
|
+
An aggregate lands as a column does, with `lb-column-value`; its
|
|
506
|
+
`lb-column` names the column it totals, and no row lands on it. A sum and an
|
|
514
507
|
average are exact decimals, read from JSON numbers and from strings holding
|
|
515
508
|
a plain decimal, as Postgres sends `numeric`. A sum has as many places as
|
|
516
509
|
the most precise value, and an average up to two more. `null` and empty
|
|
@@ -578,8 +571,8 @@ and its `lbRowsLanded` runs as its rows land. See
|
|
|
578
571
|
[Holding rows](./custom-elements.md#holding-rows).
|
|
579
572
|
|
|
580
573
|
A request always goes to the server, and a query re-runs only when a
|
|
581
|
-
response names it. A [
|
|
582
|
-
the hub kept. A patch that
|
|
574
|
+
response names it. A [sort or a filter](#sort-and-filters) is the one thing
|
|
575
|
+
landed from what the hub kept. A patch that
|
|
583
576
|
arrives before all of a query's rows is not kept, since it is not the whole
|
|
584
577
|
of anything.
|
|
585
578
|
|
|
@@ -753,8 +746,7 @@ Every request has one shape:
|
|
|
753
746
|
```
|
|
754
747
|
|
|
755
748
|
The hub takes `query`, `key` and `values` from where the element sits, and
|
|
756
|
-
sends each when it has one.
|
|
757
|
-
in place of `key`; see [Selecting rows](#selecting-rows). The server runs the handler for the name and
|
|
749
|
+
sends each when it has one. The server runs the handler for the name and
|
|
758
750
|
answers with response items, which land like any others.
|
|
759
751
|
|
|
760
752
|
### Committing
|
|
@@ -1009,10 +1001,10 @@ The hub sends one of these only when it has what the table lists, and
|
|
|
1009
1001
|
otherwise reports to the console. An insert or an update that gathers
|
|
1010
1002
|
nothing is not sent.
|
|
1011
1003
|
|
|
1012
|
-
For a query the hub serves, `lb-url` or `lb-
|
|
1013
|
-
`lb-row-update` itself, with no round trip; see
|
|
1014
|
-
[Query parms](./chrome.md#query-parms) and
|
|
1015
|
-
`lb-hub
|
|
1004
|
+
For a query the hub serves, `lb-url`, `lb-sort` or `lb-filters`, the hub
|
|
1005
|
+
answers `lb-row-update` itself, with no round trip; see
|
|
1006
|
+
[Query parms](./chrome.md#query-parms) and
|
|
1007
|
+
[Sort and filters](#sort-and-filters). `lb-hub-status` takes no request.
|
|
1016
1008
|
|
|
1017
1009
|
A key comes from a live row, or from an element a `row` landed on, so all
|
|
1018
1010
|
three work against either kind:
|
|
@@ -1118,6 +1110,27 @@ The rows a form's answer lands are placed by the list's `lb-manual`, as any
|
|
|
1118
1110
|
answer's are, whether the form was pointed by Edit or by New; see
|
|
1119
1111
|
[Placing by hand](#placing-by-hand).
|
|
1120
1112
|
|
|
1113
|
+
A list nested in the form follows the row the form is bound to. When Edit
|
|
1114
|
+
or New binds the form, the hub drops the list's rows not yet entered and
|
|
1115
|
+
asks the server for the list's query again, as the request `lb-read`, with
|
|
1116
|
+
the bound row's key added to the query string as the parm named for the
|
|
1117
|
+
form's key column. `contextFor` receives it among the parms, and the query
|
|
1118
|
+
reads it as it reads any parm, so one query serves a master the URL names
|
|
1119
|
+
and a master Edit binds. New sends the parm empty, and the query answers
|
|
1120
|
+
with no rows:
|
|
1121
|
+
|
|
1122
|
+
```ts
|
|
1123
|
+
function contextFor(req: Request, parms: URLSearchParams): HubContext {
|
|
1124
|
+
return { db: openDb(), paycheck: parms.get("paycheck_id") ?? "" };
|
|
1125
|
+
}
|
|
1126
|
+
|
|
1127
|
+
deductions: rows("id", (ctx) => ctx.db.deductionsFor(ctx.paycheck)),
|
|
1128
|
+
```
|
|
1129
|
+
|
|
1130
|
+
A form with no list inside it sends nothing when it is bound. An answer
|
|
1131
|
+
that returns after the form is bound to another row, or after the page
|
|
1132
|
+
moved on, lands nothing.
|
|
1133
|
+
|
|
1121
1134
|
A successful request from the form lets it go, as Cancel does: the form
|
|
1122
1135
|
empties, its controls return to their defaults, and the stamps go. A failed
|
|
1123
1136
|
one leaves the form as the user had it, to correct.
|
|
@@ -1145,63 +1158,6 @@ outside a live row of the form's query, Edit for a key the hub holds no row
|
|
|
1145
1158
|
for, and any of these three commands aimed at an element that is not a form
|
|
1146
1159
|
carrying `lb-query`.
|
|
1147
1160
|
|
|
1148
|
-
### Selecting rows
|
|
1149
|
-
|
|
1150
|
-
A checkbox carrying `lb-select` in a row template selects the live row it
|
|
1151
|
-
sits in. It is not a column: it carries no `lb-column`, lands nothing and
|
|
1152
|
-
is not gathered. The hub stamps the row `lb-row-selected` while it is
|
|
1153
|
-
ticked.
|
|
1154
|
-
|
|
1155
|
-
A request for the query that names no one row then acts on the rows
|
|
1156
|
-
selected, and carries their keys as `keys`:
|
|
1157
|
-
|
|
1158
|
-
```html
|
|
1159
|
-
<tbody lb-query="transactions">
|
|
1160
|
-
<template>
|
|
1161
|
-
<tr>
|
|
1162
|
-
<td><input type="checkbox" lb-select lb-show="selecting" /></td>
|
|
1163
|
-
<td lb-column="description"></td>
|
|
1164
|
-
<td lb-column="amount"></td>
|
|
1165
|
-
</tr>
|
|
1166
|
-
</template>
|
|
1167
|
-
</tbody>
|
|
1168
|
-
|
|
1169
|
-
<form lb-query="transactions" lb-request="lb-row-update">
|
|
1170
|
-
<lb-picker lb-query="accounts" lb-column="acct" exp-label="Account" exp-column="name"></lb-picker>
|
|
1171
|
-
<button type="submit">Apply</button>
|
|
1172
|
-
<button type="button" lb-request="lb-row-delete">Delete</button>
|
|
1173
|
-
</form>
|
|
1174
|
-
```
|
|
1175
|
-
|
|
1176
|
-
```json
|
|
1177
|
-
{ "name": "lb-row-update", "query": "transactions", "keys": ["4", "9"], "values": { "acct": "12" } }
|
|
1178
|
-
```
|
|
1179
|
-
|
|
1180
|
-
| Request | With rows selected | With none ticked |
|
|
1181
|
-
|------------------|----------------------------------------|----------------------|
|
|
1182
|
-
| `lb-row-update` | Sent with `keys` | Not sent |
|
|
1183
|
-
| `lb-row-delete` | Sent with `keys` | Not sent |
|
|
1184
|
-
| A declared one | Sent with `keys` | Sent with `keys: []` |
|
|
1185
|
-
| `lb-row-insert` | Sent as ever; the selection is not its | Sent as ever |
|
|
1186
|
-
|
|
1187
|
-
An update or delete with nothing ticked has nothing to act on, and nothing
|
|
1188
|
-
is reported. A request from inside a row still names that row alone. The
|
|
1189
|
-
server runs the page's `rowUpdate` or `rowDelete` once for each key, as for
|
|
1190
|
-
each row alone, and refreshes once; see [crud](./page-files.md#crud).
|
|
1191
|
-
|
|
1192
|
-
After the request succeeds, the hub clears the selection. A failed one
|
|
1193
|
-
leaves it, to try again.
|
|
1194
|
-
|
|
1195
|
-
Only a checkbox that is showing counts. Turning a selector off with
|
|
1196
|
-
`lb-show` also clears its tick, so leaving a selecting mode abandons the
|
|
1197
|
-
selection rather than keeping it out of sight. With every selector off, a
|
|
1198
|
-
request for the query is an ordinary one again.
|
|
1199
|
-
|
|
1200
|
-
Which rows are selected, and whether the page is in a selecting mode, is
|
|
1201
|
-
interaction state. A mode the URL keeps, such as `?selecting=1`, reaches
|
|
1202
|
-
the rows as a column the query computes from the parm, which `lb-show`
|
|
1203
|
-
reads.
|
|
1204
|
-
|
|
1205
1161
|
### Declared requests
|
|
1206
1162
|
|
|
1207
1163
|
A request name the page declares under `handlers` runs the application's
|
|
@@ -1331,7 +1287,7 @@ returns its controls to their defaults, and the hub removes
|
|
|
1331
1287
|
`lb-column-value` from each of them. A cancelled reset keeps both.
|
|
1332
1288
|
|
|
1333
1289
|
A page load that fails lands nothing and is reported to the console, and
|
|
1334
|
-
the query `lb-hub` says so; see [The hub's state](./chrome.md#the-hubs-state).
|
|
1290
|
+
the query `lb-hub-status` says so; see [The hub's state](./chrome.md#the-hubs-state).
|
|
1335
1291
|
A load
|
|
1336
1292
|
started by a request for `lb-url` stamps the element that sent it, as any
|
|
1337
1293
|
request stamps its element.
|
|
@@ -1363,28 +1319,28 @@ answers it with no round trip:
|
|
|
1363
1319
|
See [The URL](./chrome.md#the-url) for its columns, links, history, and the
|
|
1364
1320
|
unknown-page dialog.
|
|
1365
1321
|
|
|
1366
|
-
##
|
|
1322
|
+
## Sort and filters
|
|
1367
1323
|
|
|
1368
|
-
The hub serves
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
`lb-row-update`
|
|
1373
|
-
|
|
1374
|
-
|
|
1324
|
+
The hub serves two queries for how rows show: `lb-sort` and `lb-filters`,
|
|
1325
|
+
one row per `rows` query, keyed by the query's name. `lb-sort` holds each
|
|
1326
|
+
query's order as the server resolved it; `lb-filters` holds each query's
|
|
1327
|
+
filter values. An element makes a sort or a filter by dispatching
|
|
1328
|
+
`lb-request` with `lb-row-update` for `lb-sort` or `lb-filters`, keyed by
|
|
1329
|
+
the query's name; the `<lb-table>` widget's sortable headings and its
|
|
1330
|
+
selection do this; see
|
|
1375
1331
|
[Sending a request](./custom-elements.md#sending-a-request).
|
|
1376
1332
|
|
|
1377
|
-
A
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1333
|
+
A sort or a filter shows with no round trip: the hub places and filters the
|
|
1334
|
+
rows it already holds again, as a round trip carrying the choice would
|
|
1335
|
+
have. Then it sends the server the choice, in `lb-row-update` for `lb-sort`
|
|
1336
|
+
or `lb-filters`. No element waits on it, and the page's
|
|
1337
|
+
[`onChoices`](./page-files.md#onchoices) runs, when it has one, with the
|
|
1338
|
+
query and its new `sort` or `filters`.
|
|
1383
1339
|
|
|
1384
1340
|
Choices hold until the page changes, and a change of query parm keeps them.
|
|
1385
|
-
On entering a page,
|
|
1386
|
-
|
|
1387
|
-
parms, and the URL does not carry them.
|
|
1341
|
+
On entering a page, `lb-sort` and `lb-filters` land empty, unless the
|
|
1342
|
+
page's `onPageEnter` restores them with `sort()` and `filters()`. Choices
|
|
1343
|
+
are not query parms, and the URL does not carry them.
|
|
1388
1344
|
|
|
1389
1345
|
## The markup checks
|
|
1390
1346
|
|
|
@@ -1392,16 +1348,18 @@ The developer writes `lb-` attributes in markup, and script never assigns
|
|
|
1392
1348
|
them. The builder checks the markup of the chrome and of every page, after
|
|
1393
1349
|
expansion, and refuses to build:
|
|
1394
1350
|
|
|
1395
|
-
- an `lb-` attribute that is not one of the
|
|
1351
|
+
- an `lb-` attribute that is not one of the ten the developer writes;
|
|
1396
1352
|
`lb-exp-slot` and `lb-exp-template` are consumed by expansion and never
|
|
1397
1353
|
reach the check
|
|
1398
1354
|
- `lb-request` naming an `lb-` request other than the three Loadbare provides
|
|
1399
1355
|
- `lb-query` naming a query the page does not declare; every page and the
|
|
1400
|
-
chrome may name `lb-url` and `lb-
|
|
1356
|
+
chrome may name `lb-url`, `lb-sort`, `lb-filters` and `lb-hub-status`,
|
|
1357
|
+
and the chrome names no other
|
|
1401
1358
|
- `lb-request` naming a request the page does not declare under `handlers`;
|
|
1402
1359
|
the chrome sends none
|
|
1403
1360
|
- one of the three requests for a query whose `crud` entry does not declare
|
|
1404
|
-
it, or any but `lb-row-update` for `lb-url` or `lb-
|
|
1361
|
+
it, or any but `lb-row-update` for `lb-url`, `lb-sort` or `lb-filters`;
|
|
1362
|
+
the query is
|
|
1405
1363
|
a form's own when the form carries `lb-query`, and otherwise the nearest
|
|
1406
1364
|
`lb-query` around the element
|
|
1407
1365
|
- `lb-url-link` on anything but an `<a>`
|
|
@@ -1416,20 +1374,21 @@ expansion, and refuses to build:
|
|
|
1416
1374
|
- `lb-show` on a `<template>`, or on a row template's root
|
|
1417
1375
|
- `lb-show` with no `lb-query` around it
|
|
1418
1376
|
- `lb-show="!"` or `lb-show="!!column"`, which reverse no column
|
|
1419
|
-
- `lb-
|
|
1420
|
-
no column
|
|
1377
|
+
- `lb-filter` on an element not carrying `lb-query`, or naming no column
|
|
1421
1378
|
- `lb-manual` on an element not carrying `lb-query`, or naming anything but
|
|
1422
1379
|
`order`, `filter` or both
|
|
1423
|
-
- `lb-
|
|
1424
|
-
template
|
|
1380
|
+
- `lb-group` on anything but a `<template>`, or on one holding no
|
|
1381
|
+
`<template>` for its contents
|
|
1382
|
+
- `lb-aggregate` on a `<template>`, naming a function other than `count`,
|
|
1383
|
+
`sum`, `avg`, `min` or `max`, or, for any but `count`, beside no
|
|
1384
|
+
`lb-column`
|
|
1385
|
+
- `lb-count`, `lb-sum`, `lb-avg`, `lb-min` or `lb-max`, with what to write
|
|
1386
|
+
instead
|
|
1425
1387
|
- a `command` beginning `--lb-` that is not one of the four commands
|
|
1426
1388
|
- one of the four commands with no `commandfor`
|
|
1427
1389
|
- `--lb-new` aimed at an element the markup holds that is neither a
|
|
1428
1390
|
`<form>` nor a list carrying `lb-query` nested directly in a form's own
|
|
1429
1391
|
query
|
|
1430
|
-
- `lb-group` on anything but a `<template>`, or on one holding no
|
|
1431
|
-
`<template>` for its contents
|
|
1432
|
-
- an aggregate on a `<template>`, or any but `lb-count` naming no column
|
|
1433
1392
|
- a chrome without exactly one `<lb-hub>` and exactly one `<main>`, a
|
|
1434
1393
|
`<main>` outside `<lb-hub>`, or a `<main>` holding anything but whitespace
|
|
1435
1394
|
- a page carrying an `<lb-hub>` or a `<main>`
|