Form / foldkit-form
Nested input
A key mapped with Relation.nested
holds the relation's target, not an id. A nested form is a form: the key
holds rows, each a Model of the form built from the nested input.
ts
const NewComment = Entity.input(Blog.Comment, Schema.Struct({ body: Schema.String }))
const CreatePost = Entity.input(
Blog.Post,
Schema.Struct({ title: Schema.String, comments: Schema.Array(NewComment.schema) }),
{ comments: Relation.nested(Blog.Post.relations.comments, NewComment) },
)
// The form that edits a comment alone is the form a post's form nests.
const CommentForm = Form.make('Comment', NewComment, { inputs: { body: Input.multiline() } })
const PostForm = Form.make('PostForm', CreatePost, { nested: { comments: CommentForm } })
PostForm.row('comments', 'r0').Changed({ key: 'body', value: 'First' }) // a Message of PostForm
PostForm.nested.comments // CommentForm
PostForm.Message.RowAdded({ key: 'comments' })
PostForm.Message.RowRemoved({ key: 'comments', row: 'r0' })
PostForm.rows(PostForm.initial, 'comments') // [{ id, model }], each a Model of the nested form| The key is | Rows |
|---|---|
a one whose schema must be there | exactly one, from the start; it cannot be removed |
a one that admits null or undefined | none or one; none submits that nothing |
a many | any number, starting with none |
- The nested form is one you make and pass (
nested: { comments: CommentForm }), from the same inputRelation.nestedwas given. The form that edits a comment alone is the form a post nests, with its controls, checks and words. A nested key given none gets a plain form of its input, with this form'smessagesanddebounce. A form of another input throws. - A row is addressed with types.
PostForm.row('comments', id)has the nested form's own constructors (Changed,Blurred,Searched,RowAdded, ...), each givingPostForm's Message, andsend(message)for one already made, which is how a row inside a row is reached.PostForm.nested.commentsis the form itself. Underneath it isMessage.Nested({ key, row, message }). A Message for a row that is gone, or that is not one of the nested form, is dropped. A row's id is never reused. - A nested key's control is of kind
Nested, withdata{ cardinality, optional, form }(narrow it withInput.Nested.is(control));formis the nested form, with its owncontrols,field, androws. Nested keys are inmodel.rows, notmodel.fields. - A submit validates every row too and shows every failure; it waits for a check
running in a row as it does for its own. A rule on the list itself
(
Schema.isMaxLength(5)) is a failure of the whole, inerrors. fillfills rows from values, and nesting goes as deep as the inputs do.