npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@astro-utils/forms

v3.9.9

Published

Server component for Astro (call server functions from client side with validation and state management)

Downloads

1,163

Readme

Astro Forms Utils

Build License License Version

Server component for Astro (validation and state management)

Full feature server components for Astro.js

This package is a framework for Astro.js that allows you to create forms and manage their state without any JavaScript.

It also allows you to validate the form on the client side and server side, and protect against CSRF attacks.

More features

  • JWT session management
  • Override response at runtime (useful for error handling)
  • Custom server validation with zod
  • Multiples app states at the same time

Show me the code

---
import { Bind, BindForm, BButton, BInput } from "@astro-utils/forms/forms.js";
import Layout from "../layouts/Layout.astro";

const form = Bind();
let showSubmitText: string;

function formSubmit(){
    showSubmitText = `You name is ${form.name}, you are ${form.age} years old. `;
}
---
<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" required/>
    
        <BButton onClick={formSubmit} whenFormOK>Submit</BButton>
    </BindForm>
</Layout>

Usage

Add the middleware to your server

npm install @astro-utils/forms

Add the middleware to your server

src/middleware.ts

import astroForms from "@astro-utils/forms";
import {sequence} from "astro/middleware";

export const onRequest = sequence(astroForms());

Add to Layout

Add the WebForms component in the layout

layouts/Layout.astro

---
import {WebForms} from '@astro-utils/forms/forms.js';
---
<WebForms>
    <slot/>
</WebForms>

Easy debugging

When vite reloads the page, the browser will popup confirmation dialog. This is annoying when you are debugging. You can disable this by using the astro-utils integration

astro.config.mjs

import { defineConfig } from 'astro/config';
import astroFormsDebug from "@astro-utils/forms/dist/integration.js";

export default defineConfig({
    output: 'server',
    integrations: [astroFormsDebug]
});

Complex Form Validation

pages/index.astro

---
import { Bind, BindForm, FormErrors, BButton, BInput, BOption, BSelect, BTextarea } from "@astro-utils/forms/forms.js";
import Layout from "../layouts/Layout.astro";

type formType = {
    name: string,
    age: number,
    about?: string
    favoriteFood?: 'Pizaa' | 'Salad' | 'Lasagna'
}

const form = Bind<formType>();
let showSubmitText: string;

function formSubmit(){
    showSubmitText = `You name is ${form.name}, you are ${form.age} years old. `;

    if(form.about){
        showSubmitText += `\n\n${form.about}\n\n`;
    }

    if(form.favoriteFood){
        showSubmitText += `Your favorite food is ${form.favoriteFood}`;
    }
}
---
<Layout>
    <BindForm bind={form}>
        <FormErrors title="Form Errors"/>
    
        <h4>What you name*</h4>
        <BInput type={'text'} name="name" maxlength={20} required/>
    
        <h4>Enter age*</h4>
        <BInput type={'int'} name="age" required/>
    
        <h4>Tell about yourself</h4>
        <BTextarea name="about" maxlength={300}></BTextarea>
    
        <h4>What you favorite food?</h4>
        <BSelect name="favoriteFood" required={false}>
            <BOption disabled selected>Idk</BOption>
            <BOption>Pizaa</BOption>
            <BOption>Salad</BOption>
            <BOption>Lasagna</BOption>
        </BSelect>
    
        <BButton onClick={formSubmit} whenFormOK>Submit</BButton>
    
        {showSubmitText && <>
            <h3>You submitted the form:</h3>
            <div style="white-space: pre;">{showSubmitText}</div>
        </>}
    </BindForm>
</Layout>

Button Hook

You can also use this as a simple on click hook

---
import { BButton } from "@astro-utils/forms/forms.js";
import { Button } from 'reactstrap';

const { session } = Astro.locals;

function increaseCounter() {
    session.counter ??= 0
    session.counter++
}
---
<Layout>
    <BButton as={Button} props={{color: 'info'}} onClick={increaseCounter}>++</BButton>
    {session.counter}
<Layout/>

The session.counter will show the last value and not the update value.

This is because the output is not reactive. You can use it inside BindForm to make it reactive.