-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2 from withastro-utils/feat/view-state
feat: form@3.3
- Loading branch information
Showing
13 changed files
with
294 additions
and
121 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,36 +1,54 @@ | ||
import { defineConfig } from 'astro/config'; | ||
import {defineConfig} from 'astro/config'; | ||
import starlight from '@astrojs/starlight'; | ||
|
||
import expressiveCode from "astro-expressive-code"; | ||
|
||
// https://astro.build/config | ||
export default defineConfig({ | ||
site: 'https://withastro-utils.github.io', | ||
base: '/docs', | ||
integrations: [expressiveCode(), starlight({ | ||
editLink: { | ||
baseUrl: 'https://github.com/withastro-utils/docs/tree/main/', | ||
}, | ||
lastUpdated: true, | ||
favicon: '/favicon.png', | ||
title: 'Astro Utils', | ||
logo: { | ||
src: '/src/assets/logo.png' | ||
}, | ||
social: { | ||
github: 'https://github.com/withastro-utils/utils' | ||
}, | ||
sidebar: [{ | ||
label: 'Guides', | ||
autogenerate: { | ||
directory: 'guides' | ||
} | ||
}, { | ||
label: 'Reference', | ||
autogenerate: { | ||
directory: 'reference' | ||
} | ||
}], | ||
customCss: ['./src/styles/home.css', './src/styles/code-margin.css'] | ||
})] | ||
site: 'https://withastro-utils.github.io', | ||
base: '/docs', | ||
integrations: [expressiveCode(), starlight({ | ||
editLink: { | ||
baseUrl: 'https://github.com/withastro-utils/docs/tree/main/', | ||
}, | ||
lastUpdated: true, | ||
favicon: '/favicon.png', | ||
title: 'Astro Utils', | ||
logo: { | ||
src: '/src/assets/logo.png' | ||
}, | ||
social: { | ||
github: 'https://github.com/withastro-utils/utils' | ||
}, | ||
sidebar: [{ | ||
label: 'Guides', | ||
items: [{ | ||
label: 'Forms', | ||
items: [ | ||
{ | ||
label: 'Getting Started', | ||
link: '/guides/forms/getting-started' | ||
}, { | ||
label: 'Data Binding', | ||
link: '/guides/forms/data-binding' | ||
}, { | ||
label: 'JS Helpers', | ||
link: '/guides/forms/js-helpers' | ||
} | ||
] | ||
}, { | ||
label: 'Context', | ||
link: '/guides/context' | ||
}, { | ||
label: 'Express Endpoints', | ||
link: '/guides/express-endpoints' | ||
}] | ||
}, { | ||
label: 'Reference', | ||
autogenerate: { | ||
directory: 'reference/forms' | ||
} | ||
}], | ||
customCss: ['./src/styles/home.css', './src/styles/code-margin.css'] | ||
})] | ||
}); |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
--- | ||
title: Binding & Validation | ||
description: Using data binding with Astro Forms | ||
--- | ||
|
||
# Introduction | ||
|
||
With Astro Forms you can easily create forms with data binding and validation. It also provides a simple way to handle form submissions and preserve state between postbacks. | ||
|
||
## Data Binding | ||
|
||
Astro Forms supports two-way data binding. This means that you can bind a form field to a property on `Bind` instance and the value of the property will be updated when the field changes and vice versa. | ||
|
||
### Example | ||
|
||
```astro | ||
--- | ||
import { Bind, BindForm, BButton, BInput } from "@astro-utils/forms/forms.js"; | ||
import Layout from "../layouts/Layout.astro"; | ||
type Form = { | ||
name: string; | ||
age: number; | ||
} | ||
const form = Bind<Form>(); | ||
let showSubmitText: string; | ||
function formSubmit(){ | ||
showSubmitText = `You name is ${form.name}, you are ${form.age} years old. `; | ||
form.age++; | ||
} | ||
--- | ||
<Layout> | ||
<BindForm bind={form}> | ||
{showSubmitText} | ||
<h4>What you name*</h4> | ||
<BInput type="text" name="name" maxlength={20} required/> | ||
<h4>Enter age*</h4> | ||
<BInput type="int" name="age" min={10} required/> | ||
<BButton onClick={formSubmit} whenFormOK>Submit</BButton> | ||
</BindForm> | ||
</Layout> | ||
``` | ||
|
||
In this example, the `Bind` instance is bound to the form fields. | ||
- When the user changes the value of the `name` or `age` fields and submit, the `Bind` instance will be updated. | ||
- The `formSubmit` function will be called when the user clicks the `Submit` button and the form is valid. | ||
- After `formSubmit` the `age` property will be incremented and the `showSubmitText` will be updated. | ||
|
||
## View State | ||
|
||
Astro Forms also supports view state. This means that the values of the form fields will be preserved between postbacks. | ||
|
||
### Example | ||
|
||
```astro | ||
--- | ||
type Form = { | ||
counter: number; | ||
} | ||
const form = Bind<Form>({counter: 0}); | ||
function incCounter(){ | ||
form.counter++; | ||
} | ||
--- | ||
<Layout> | ||
<BindForm bind={form}> | ||
Counter: {form.counter} | ||
<BButton onClick={formSubmit}>Increase counter</BButton> | ||
</BindForm> | ||
</Layout> | ||
``` | ||
|
||
What happens here is that the `counter` property of the `Bind` instance will be incremented every time the user clicks the `Increase counter` button. | ||
|
||
The `Bind` state will persist between postbacks, by storing the data on the client side compressed and __encrypted__. | ||
|
||
### Valid values | ||
|
||
The state of the `Bind` instance must be serlizable, but you can use more then just JSON. | ||
|
||
You can use any valid [SuperJSON](https://github.com/blitz-js/superjson) value in the `Bind` instance. | ||
Meaning also `Date`, `Map`, `URL`, `Set`, `RegExp`, `BigInt`, `undefined` are supported. | ||
|
||
|
||
### Button State | ||
|
||
You can use state per `BButton` component. You can also change the `BButton` props easily each time the button is clicked. | ||
|
||
Special props: | ||
- **state**: any - store state per button | ||
- **extra**: any - store extra data per button (cannot be changed in the `onClick` function) | ||
- **innerText**: string - the text of the button (overides the children) | ||
- **innerHTML**: string - the HTML of the button (overides the children) | ||
- **remove**: boolean - remove the button from the HTML | ||
|
||
```astro | ||
--- | ||
import { BButton, Bind, BindForm } from '@astro-utils/forms/forms.js'; | ||
import Layout from '../layouts/Layout.astro'; | ||
const colors = ['red', 'green', 'blue', 'yellow', 'purple', 'orange', 'pink', 'black', 'white', 'gray']; | ||
function changeColor() { | ||
this.state.color++; | ||
if (this.state.color >= colors.length) { | ||
this.state.color = this.extra; | ||
} | ||
this.style = `color: ${colors[this.state.color]}`; | ||
} | ||
--- | ||
<Layout> | ||
<BindForm> | ||
{ | ||
colors.map((_, i) => ( | ||
<BButton onClick={changeColor} extra={i} state={{ color: i }}> | ||
Button {i} | ||
</BButton> | ||
)) | ||
} | ||
</BindForm> | ||
</Layout> | ||
``` | ||
|
||
In this example, the `changeColor` will change the button color each time it is clicked for a different color in the `colors` array. | ||
|
||
If the button is clicked more times then the length of the `colors` array, it will start from the beginning. | ||
|
||
#### Initial state | ||
|
||
![Initial state](../../../../assets/change-color/initial-state.png) | ||
|
||
|
||
#### After some clicks | ||
|
||
![After clicks](../../../../assets/change-color/after-clicks.png) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
--- | ||
title: JS Helpers | ||
description: SSR JS for client actions | ||
--- | ||
|
||
# Introduction | ||
|
||
Astro forms ship with some utility functions to handle forms. | ||
Some functionality works by sending the script to the client and running it there. | ||
|
||
You can access them via `Astro.locals.forms`. | ||
|
||
### Controllers | ||
|
||
```ts | ||
class FormsReact { | ||
scriptToRun: string; | ||
overrideResponse: Response | null; | ||
|
||
// server side redirect | ||
redirect(location: string, status?: ValidRedirectStatus): void; | ||
updateSearchParams(): { | ||
search: URLSearchParams; | ||
redirect(status?: ValidRedirectStatus): void; | ||
}; | ||
updateOneSearchParam(key: string, value?: string, status?: ValidRedirectStatus): void; | ||
|
||
// client side redirect | ||
redirectTimeoutSeconds(location: string, timeoutSec = 2): void; | ||
|
||
alert(message: string): void; | ||
consoleLog(...messages: any[]): void; | ||
console(type: keyof Console, ...messages: any[]): void; | ||
callFunction(func: string, ...args: any[]): void; | ||
} | ||
``` | ||
|
||
### Example | ||
|
||
```astro | ||
--- | ||
import { Bind, BindForm, BButton, BInput } from "@astro-utils/forms/forms.js"; | ||
import Layout from "../layouts/Layout.astro"; | ||
type Form = { | ||
name: string; | ||
age: number; | ||
} | ||
const form = Bind<Form>(); | ||
let showSubmitText: string; | ||
function formSubmit(){ | ||
showSubmitText = `You name is ${form.name}, you are ${form.age} years old. `; | ||
// Redirect to home page after 2 seconds | ||
Astro.locals.forms.redirectTimeoutSeconds('/'); | ||
} | ||
--- | ||
<Layout> | ||
<BindForm bind={form}> | ||
{showSubmitText} | ||
<h4>What you name*</h4> | ||
<BInput type="text" name="name" maxlength={20} required/> | ||
<h4>Enter age*</h4> | ||
<BInput type="int" name="age" min={10} required/> | ||
<BButton onClick={formSubmit} whenFormOK>Submit</BButton> | ||
</BindForm> | ||
</Layout> | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.