Skip to content

Custom Field

TinaH edited this page Mar 20, 2021 · 36 revisions

Forget the label, help and error messages.

You do not have to create code for labels, help or error messages when creating custom fields. They are handled by this package. All fields are automatically wrapped with the default field slots.

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 component. See Blade Components.

1. Create a class that extends Tanthammar\TallForm\BaseField

  • Name your class in a non-conflicting and descriptive way
  • add the $type property, naming rule = slug casing the class name.
namespace YourNameSpace;

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

    // to avoid IDE errors, all properties that exists in BaseField or its traits should be set in the overrides() method.
    // please put this method first, for code readability
    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 more
    public function specialProp($prop): self
    {
        $this->specialProp = $prop;
        return $this;
    }
}

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

  • Minimum requirements is to pass the $field
use Illuminate\View\View;
use Illuminate\View\Component;
use YourNameSpace\MyField as Field;
use Tanthammar\TallForms\Traits\Helpers;

class MyField extends Component
{
    use Helpers;

    public Field $field;

    public function __construct(Field $field)
    {
        $this->field = $field;
    }

    public function render(): View
    {
        return view('components.my-field'); //observe the file name
    }

3. Make the Blade component compatible with $field attributes

If you want to share your field, it is required that you use the same method naming as all other fields.

  • Apply the options(), class() and error() methods.
   public function options(): array
    {
        $custom = $this->field->getAttr('input');
        $default = [
            $this->field->wire => $this->field->key,
            'type' => 'text', //example when using an input field
            'name' => $this->field->key,
            'class' => $this->class()
        ];
        return array_merge($default, $custom);
    }

    public function class()
    {
        $class = "form-input my-1 w-full "; //example class from a default input field
        $class .= $this->field->class;
        return Helpers::unique_words($class);
    }

    public function error()//example class from a default input field
    {
        return Helpers::unique_words($this->class()." border-red-300 text-red-900 placeholder-red-300 focus:border-red-300 focus:shadow-outline-red");
    }

4. Create the blade component view

  • resources/views/components/my-field.blade.php. Name the view the same as the field $type.
  • You have access to the $field and all component attributes in your blade view.

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

<div>
<div>{{ $field->specialProp }}</div>
<input
    value="{{ old($field->key) }}"
    @foreach($options() as $key => $value) {{$key}}="{{$value}}" @endforeach
    {{ $attributes->merge(['class' => $errors->has($field->key) ? $error() : $class() ]) }} />
</div>

5. Create the field blade view

  • resources/views/vendor/tall-forms/fields/my-field.blade.php. Name the view the same as the field $type.
  • use the blade component you just created
<x-my-field :field="$field" />

6. Use your field in a form

MyField::make(...)

7. Optional theme css

If you are going to share your field with the community. Please move (applicable) classes to tall-theme.css in order for other users to easily be able to redesign the field. At the moment there are two theme files, tailwind 1.x/2.x. Please consider compatibility with both versions. This will change in the future when this package only supports TW2.x.

Troubleshooting

If you run into errors where you get a message that the property or method does not exist in Livewire\LivewireViewCompilerEngine, you are probably trying to access
{{$this->someComponentMethod()}} or {{$this->someComponentProperty}} or {{$someComponentProperty}}.
To get around it, you have to pass the property from the field blade view to the blade component.

@entangle issues

If you are having trouble with @entangle I recommend reviewing existing @entangle issues

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.

Clone this wiki locally