Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Form Builder Guide

Form Builder is a flexible Vue 3 component that works with Inertia's useForm and shadcn/ui components to create dynamic forms with minimal configuration.

Installation

Ensure you have the required shadcn/ui components installed:

php artisan shadcn:init
php artisan shadcn:component button
php artisan shadcn:component input
php artisan shadcn:component label
php artisan shadcn:component select
php artisan shadcn:component checkbox
php artisan shadcn:component textarea
php artisan shadcn:component card

Basic Usage

Here's a simple example of how to use the Form Builder:

<script setup>
import { useForm } from '@inertiajs/vue3'
import { createSchema, FormBuilder } from '@/Components/FormBuilder'

const form = useForm({
    name: '',
    email: '',
    message: ''
})

const schema = createSchema()
    .field('name')
        .required()
        .placeholder('Your name')
    .field('email')
        .email()
        .required()
        .placeholder('your@email.com')
    .field('message')
        .textarea()
        .rows(6)
        .placeholder('Your message here')
    .build()
</script>

<template>
    <FormBuilder
        :form="form"
        :schema="schema"
        title="Contact Form"
        @submit="form.post('/contact')"
    />
</template>

Schema Configuration

The schema builder provides a fluent API to configure form fields:

const schema = createSchema()
    .field('username')
        .label('Username')
        .required()
        .props({
            autocomplete: 'username'
        })
    .field('email')
        .email()
        .label('Email Address', {
            required: true,
            requiredText: '(Required)',
            className: 'font-semibold'
        })
    .field('country')
        .select([
            { value: 'us', label: 'United States' },
            { value: 'uk', label: 'United Kingdom' }
        ])
    .field('bio')
        .textarea()
        .rows(4)
        .span('full')
        .asCard()
    .build()

Available Field Types

  1. Text Input:
.field('username')
    .text()  // default type
    .placeholder('Enter username')
  1. Email:
.field('email')
    .email()
    .required()
  1. Textarea:
.field('description')
    .textarea()
    .rows(4)
  1. Select:
.field('country')
    .select([
        { value: 'us', label: 'United States' },
        { value: 'uk', label: 'United Kingdom' }
    ])
  1. Checkbox:
.field('terms')
    .checkbox()
    .props({ label: 'I agree to terms' })

Customizing Components

You can customize how fields are rendered using slots:

Type-based customization

This will apply to all fields of a specific type:

<FormBuilder :form="form" :schema="schema">
    <!-- Custom component for all text inputs -->
    <template #text="{ field, value, onChange }">
        <Input
            :id="field.name"
            :value="value"
            @input="e => onChange(e.target.value)"
            v-bind="field.props"
        />
    </template>
</FormBuilder>

Field-specific customization

This will only apply to a specific field:

<FormBuilder :form="form" :schema="schema">
    <!-- Custom component just for email field -->
    <template #field-email="{ field, value, onChange }">
        <Input
            :id="field.name"
            :value="value"
            @input="e => onChange(e.target.value)"
            class="special-email-input"
            type="email"
            v-bind="field.props"
        />
    </template>
</FormBuilder>

Available Slots

  1. Field Type Slots:
  • #text - Text inputs
  • #textarea - Textarea fields
  • #select - Select dropdowns
  • #checkbox - Checkbox inputs
  1. Field-Specific Slots:
  • #field-{fieldName} - Custom component for specific field
  1. General Slots:
  • #label - Customize field labels
  • #help - Help text below fields
  • #errors - Error messages
  • #submit - Submit button

Each slot receives these props:

  • field - Field configuration
  • value - Current field value
  • onChange - Function to update value
  • form - The entire form object

Grid Layout

Control the form layout using columns:

<FormBuilder :form="form" :schema="schema" :columns="2">

Span fields across columns:

.field('email')
    .span(2)  // Takes up 2 columns
    .required()

.field('bio')
    .span('full')  // Takes full width
    .textarea()

Card Layout

Wrap fields in cards:

.field('profile')
    .asCard()
    .span('full')

Or wrap the entire form:

<FormBuilder :form="form" :schema="schema" :useCards="true">

Custom Submit Button

Customize the submit button:

<FormBuilder :form="form" :schema="schema">
    <template #submit="{ form }">
        <div class="flex justify-end space-x-2">
            <Button variant="outline">Cancel</Button>
            <Button type="submit" :disabled="form.processing">
                {{ form.processing ? 'Saving...' : 'Save Changes' }}
            </Button>
        </div>
    </template>
</FormBuilder>

Error Handling

Customize error display:

<FormBuilder :form="form" :schema="schema">
    <template #errors="{ errors }">
        <div v-if="Object.keys(errors).length" class="bg-red-50 p-4 rounded-md">
            <ul class="list-disc pl-4">
                <li v-for="error in errors" :key="error" class="text-red-700">
                    {{ error }}
                </li>
            </ul>
        </div>
    </template>
</FormBuilder>

Best Practices

  1. Always provide meaningful labels for fields
  2. Use appropriate field types
  3. Group related fields using grid layout
  4. Use cards for complex sections
  5. Provide clear validation messages
  6. Consider mobile responsiveness when choosing layouts
  7. Use help text for complex fields
  8. Customize components to match your design system

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Used by

Contributors

Languages