Custom field

If you make a custom field. Please share it with the community! (Make a PR)

Forget the label, help and error messages.

Don't create code for labels, help or error messages when creating a custom field, it's automatically added by the form component.

Extend existing component, instead of creating a custom field

If you are looking to change the styling of an existing field it is enough to extend the fields Blade Class or create your own theme.

Steps to create a custom field

1. Create a Field class that extends BaseField

  • Name your class in a non-conflicting and descriptive way

  • add the $type property, best practice is to slug case the class name.

namespace YourNameSpace;

use Tanthammar\TallForm\BaseField;

class MyField extends BaseField
{
    public $specialProp; //example adding your own properties

    // all properties that exists in BaseField or its traits should be set in the overrides() method.
    public function overrides(): self
    {
       $this->type = 'my-field'; //required property!
       return $this;
    }

    //now your field has access to all BaseField methods, you can override them or add your own
    public function specialProp($prop): self
    {
        $this->specialProp = $prop;
        return $this;
    }
}

2. Create a Blade component class, with the same name

Extend BaseBladeField

use Illuminate\View\View;
use Illuminate\View\Component;
use Tanthammar\TallForms\Traits\BaseBladeField;

class MyField extends BaseBladeField 
{     
    public function __construct(
        public array|object      $field = [],
        public array             $attr = []
    )
    {
        parent::__construct((array)$field, $attr);
        $this->attr = array_merge($this->inputAttributes(), $attr);
    }
    
    //add defaults for headless use cases
    protected function defaults(): array
    {
        return [
            'id' => 'select', //input name and wire:model is autogenerated from the id attribute
            'placeholder' => 'my placeholder',
            'class' => 'form-input my-1 w-full shadow', //error class is autogenerated in BaseBladeField
            'wrapperClass' => null,
            'disabled' => false,
        ];
    }
    
    //add input attributes
    protected function inputAttributes(): array
    {
        $custom = data_get($this->field, 'attributes.input', []); //support field->inputAttr()
        $default = [
            $this->field->wire => $this->field->key,
            'id' => $this->field->id,
            'name' => $this->field->name
        ];
        return array_merge($default, $custom);
    }
    
    public function render(): View
    {
        return view('components.my-field'); //observe the file name
    }
}

3. Create a blade component view

  • resources/views/components/my-field.blade.php.

  • Name the view the same as the field $type.

  • You have access to all the $field attributes and methods, in your blade view.

Example using an input field based on MyField blade component class:

<div>
    <div>{{ $field->specialProp }}</div>
    <input
        @if($field->disabled) disabled @endif
        {{ $attributes->except([...array_keys($attr), 'disabled'])
            ->merge($attr)
            ->merge(['class' => $errors->has($field->key) ? $field->errorClass : $field->class ]) 
        }} />
</div>

4. Use your field in a form component

MyField::make(...)

Please share your field!

If you make a new field. Please share it! Make a PR or paste the code in an issue, and I'll add it to the package.

Last updated