Skip to content

Example form

TinaH edited this page Aug 27, 2021 · 13 revisions

The Field class is used to declare your form fields.

public $photos;

public function fields()
{
    return [
        Select::make('Brand', 'brand_id')->options(Brand::pluck('id', 'name'))->help('Please select a brand.'),
        Input::make('Name')->rules(['required', Rule::unique('cars', 'name')->ignore($this->model->id)]),
        Select::make('Color')->options(['Red', 'Green', 'Blue']),
        Repeater::make('Owners')->fields([
            Input::make('Name')->placeholder('Name')->rules('required'),
            Input::make('Phone')->type('tel')->placeholder('Phone')->rules('required'),
        ])->sortable()->help('Click plus to add an Owner'),
        Checkbox::make('Insurable')->placeholder('Is the car insurable?')->rules('accepted'),
        Radio::make('Fuel Type')->options(['Gas', 'Diesel', 'Electric'])->default('Diesel'),
        Checkboxes::make('Features')->options(['Stereo', 'Bluetooth', 'Navigation'])->rules('required|min:2'),
        Textarea::make('Description'),
        FileUpload::make('Photos')->multiple()->rules('nullable|mimes:png,jpg,jpeg,gif,tiff|max:1024')->accept("image/*"),
    ];
}

KeyVal example

public function fields()
{
 return [
    Keyval::make(trans('fields.settings').' '.trans('fields.upfront'), 'upfronts')->fields([
        Checkbox::make(trans('fields.upfront_auto'), 'auto')
            ->placeholder(trans('fields.auto'))
            ->help(trans('fields.upfront_auto_hint'))
            ->rules('required|boolean')
            ->colspan(12),
        Input::make(trans('fields.amount'), 'amount')
            ->type('number')
            ->prefix('kr')
            ->placeholder(300)
            ->help(trans('fields.upfront_amount_hint'))
            ->rules('nullable|numeric|integer|min:10')
            ->colspan(6),
        Input::make(trans('fields.percent'),'amount_percent')
            ->type('number')
            ->prefix('%')
            ->placeholder(50)
            ->help(trans('fields.percent_hint') . ' ' . trans('fields.upfront_percent_hint'))
            ->rules('nullable|numeric|integer|between:1,100')
            ->colspan(6),
    ])->help(trans('fields.upfront_help')),
 ];
}

A form with almost every field

<?php

namespace App\Http\Livewire\Forms;

use App\Models\User;
use Illuminate\Validation\Rule;
use Livewire\Component;
use Livewire\WithFileUploads;
use Tanthammar\TallForms\Checkbox;
use Tanthammar\TallForms\Checkboxes;
use Tanthammar\TallForms\FileUpload;
use Tanthammar\TallForms\Input;
use Tanthammar\TallForms\KeyVal;
use Tanthammar\TallForms\SpatieTags;
use Tanthammar\TallForms\TallForm;
use Tanthammar\TallForms\Radio;
use Tanthammar\TallForms\Range;
use Tanthammar\TallForms\Repeater;
use Tanthammar\TallForms\Select;
use Tanthammar\TallForms\Textarea;
use Tanthammar\TallForms\Traits\UploadsFiles;

class CreateUser extends Component
{
    use TallForm, WithFileUploads, UploadsFiles;

    public $image;
    public $files;

    public function mount(?User $user)
    {
        //Gate::authorize()
        $this->fill([
            'formTitle' => 'Create User',
            'onKeyDownEnter' => 'saveAndStay', //this is the default submit function, you can change it to any other component method Used for wire:submit
            'wrapWithView' => true,
            'showGoBack' => true,
            'inline' => true,
        ]);
        $this->mount_form($user);
    }

    public function onCreateModel($validated_data)
    {
        $this->model = User::create($validated_data);
    }

    public function onUpdateModel($validated_data)
    {
        $this->model->update($validated_data);
    }


    public function fields()
    {
        return [
            $this->name(),
            $this->text(),
            $this->password(),
            $this->passwordConfirmation(),
            $this->url(),
            $this->number(),
            $this->tel(),
            $this->email(),
            $this->dateTimeLocal(),
            $this->select(),
            $this->checkbox(),
            $this->checkboxes(),
            $this->radio(),
            $this->textarea(),
            $this->fileUpload(),
            $this->fileUploads(),
            $this->range(),
            $this->repeater(),
            $this->keyval(),
            $this->tags(),
        ];
    }

    //single file upload
    public function saveImage($validated_file)
    {

        $path = filled($validated_file) ? $this->image->store('photos') : null;

        if (optional($this->model)->exists && filled($path)) {
            $this->model->single_image_url = $path;
            $this->model->save();
        }
    }

    //multiple file uploads
    public function saveFiles($validated_files)
    {
        $paths = [];
        if (filled($validated_files)) {
            foreach ($this->files as $file) {
                if (filled($file)) array_push($paths, $file->store('files'));
            }
        }

        if (optional($this->model)->exists && filled($paths)) {
            $this->model->multiple_image_urls = $paths;
            $this->model->save();
        }
    }

    public function number()
    {
        return Input::make('Number')
            ->type('number')
            ->prefix('#')
            ->step(2)
            ->min(5)
            ->max(10)
            ->rules('required|integer');
    }

    public function dateTimeLocal()
    {
        return Input::make('Date Time Local', 'birthday')
            ->type('datetime-local')
            ->step(7)
            ->min('2020-09-15')
            ->max('2021-12-31')
            ->default(now()->toDateTimeLocalString('minute')) //or now()->format('Y-m-d\TH:i')
            ->rules('required');
    }

    public function range()
    {
        return Range::make('Range')
            ->default(3)
            ->min(1)
            ->max('100')
            ->step(1)
            ->rules('required|integer');
    }

    public function keyval()
    {
        return KeyVal::make('Bio')->fields([
            Input::make('Profession')->colspan(6)->help('Field help')->rules('required'),
            Input::make('Spouse')->colspan(6)->rules('required'),
            Input::make('Pet')->colspan(6)->help('Field help')->rules('required'),
            Input::make('Children')->colspan(6)->rules('required'),
        ]);
    }

    public function repeater()
    {
        return Repeater::make('Friends')->fields([
            Input::make('First name')
                ->afterLabel('After Label slot')
                ->rules('required')
                ->colspan(6),
            Input::make('Last name')
                ->afterLabel('Best slot to display field help')
                ->colspan(6)
                ->rules('required'),
        ])->sortable()
        ->help('Click plus to add a friend');
    }

    public function tel()
    {
        return Input::make('Phone')
            ->type('tel')
            ->prefix('phone:')
            ->rules('required');
    }

    public function email()
    {
        //example: set the validation based on if the model exists in optional model binding
        $email_rule = optional($this->model)->exists
            ? ['required', 'email', Rule::unique('users', 'email')->ignore($this->model->id)]
            : 'required|email|unique:users,email';
        return Input::make('Email')
            ->type('email')
            ->prefix('@')
            ->rules($email_rule);
    }

    public function url()
    {
        return Input::make('Url', 'url')
            ->type('url')
            ->prefix('https://')
            ->rules('required|active_url');
    }

    public function text()
    {
        return Input::make('Text')
            ->help('Some help text')
            ->icon('file-user')//requires blade ui kit icons
            ->rules('required|string');
    }

    public function textarea()
    {
        return Textarea::make('Textarea')
            ->placeholder('Tell me a story')
            ->rows(3)
            ->rules('required');
    }

    public function checkbox()
    {
        return Checkbox::make('Checkbox') //cast to boolean on model
            ->placeholder('The checkbox label')
            ->rules('boolean')
            ->default(1); //equivalent to checked
    }

    /**
     * Checkboxes, associative array
     * @return Checkboxes
     */
    public function checkboxes()
    {
        $options = ['Wifi' => 'wf', 'Bluetooth' => 'bl', 'Ethernet' => 'eth'];
        return Checkboxes::make('Checkboxes')
            ->options($options)
            ->rules(['array', Rule::in(array_values($options))])
            ->default(['wf']);
    }

    /**
     * Radio, associative array
     * @return Radio
     */
    public function radio()
    {
        $options = ['Wifi' => 'wf', 'Bluetooth' => 'bl', 'Ethernet' => 'eth'];
        return Radio::make('Radio')
            ->options($options)
            ->rules([Rule::in(array_values($options))])
            ->default('wf');
    }

    public function fileUpload()
    {
        return optional($this->model)->exists //you probably do not want to attach files if the model does not exist
            ? FileUpload::make('Upload image', 'image')
                ->help('Max 1024kb, png, jpeg, gif or tiff')//important for usability to inform about type/size limitations
                ->rules('nullable|mimes:png,jpg,jpeg,gif,tiff|max:1024') //only if you want to override livewire main config validation
                ->accept("image/*") //html5 file input accept attribute
            : null;
    }

    public function fileUploads()
    {
        return optional($this->model)->exists //you probably do not want to attach files if the model does not exist
            ? FileUpload::make('Upload files', 'files')
                ->multiple() //remove if you want single file upload
                ->help('Max 1024kb, pdf, png, jpeg, gif or tiff')//important for usability to inform about type/size limitations
                ->rules('nullable|mimes:pdf,png,jpg,jpeg,gif,tiff|max:1024') //only if you want to override livewire main config validation
                ->accept("image/*,.pdf") //html5 file input accept attribute
            : null;
    }

    public function select()
    {
        $options = ['Wifi' => 'wf', 'Bluetooth' => 'bl', 'Ethernet' => 'eth'];
        return Select::make('Select')
            ->options($options)
            ->placeholder('Please select an option')
            ->rules(['nullable', Rule::in(array_values($options))]);
    }

    public function tags()//tested, multiple tag fields in same form works :)
    {
        return optional($this->model)->exists //do it like this or use the syncTags() method onUpdateModel or onSaveModel
            ? SpatieTags::make('Tags')
                ->type('categories')
                ->placeholder('Click to add tag ...')//default = "Add tag ..."
                ->suffix('user')
                ->help('Press SPACE to create a new tag, or SELECT an existing tag by CLICKING on it.')//we use space to avoid conflict with enter to submit form
                ->rules('string|between:3,60') //default: 'string|between:3,50'
                ->errorMsg('The tag must be between 3 to 60 chars long and only consist of alpha-numeric characters.') //default = :attribute is set to 'tag'
            : null;
    }

    public function name()
    {
        return Input::make('Name')->rules('required|string');
    }

    public function password()
    {
        return Input::make('Password')
            ->type('password')
            ->rules('required|alpha_dash|min:8');
    }

    public function passwordConfirmation()
    {
        return Input::make('Repeat password', 'password_confirmation')
            ->type('password')
            ->custom()
            ->rules('required|same:form_data.password');
    }

}
Clone this wiki locally