0

Hello i need to focus first field of ErrorBag, I am using Livewire component form and because Livewire send XHR request every input change to update the DOM it will be focused every time on XHR response without submitting the form and it's not what I need, I am using also Alpine Js in the same project and I want focus it with Javascript but I don't know if it is possible to watch a property changes.

function app(){

return {

    errorBag: {!! json_encode(array_keys($errors->getMessages())) !!},
    

    focusField()
    {
     if(this.errorBag.length > 0)
      {
        fieldError = Array.from(document.getElementsByName(errorBag[0]));
        fieldError[0].focus({preventScroll:false});
      }
    }
}

}

In example i want initialize the Alpine component with x-data="app()" and then i want trigger focusField() function if the errorBag property changes to focus only once the field invalid for every form submit. Thanks for your help

2
  • Your code has syntax errors, are you sure everything has been copied correctly? Commented Sep 8, 2020 at 15:01
  • I've updated the code, now you will not receive syntax errors. Commented Sep 8, 2020 at 15:33

2 Answers 2

1

Solved myself

          <div
            x-data="
            { 
              'errors': {{ json_encode(array_keys($errors->getMessages())) }},
              focusField(input){
                  fieldError = Array.from(document.getElementsByName(input));
                  if(fieldError.length > 0){
                    fieldError[0].focus({preventScroll:false});
                  }
              },
            }
            "
            x-init="() => { $watch('errors', value => focusField(value[0])) }"
        >
        </div>

Properties in function app() are not updated,but in x-data object it works perfect.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks! I get Alpine Error: "SyntaxError: expected expression, got '}'" from this. Any idea why?
0

FWIW I didn't really like this and instead use standard validation with:

use Illuminate\Validation\Validator;
    
class ContactForm extends Component
{
    public $name;
    public $email;
 
    protected $rules = [
        'name' => 'required|min:6',
        'email' => 'required|email',
    ];

    public $errors = [];
 
    public function submit()
    {
        $this->withValidator(function (Validator $validator) {
            $validator->after(function ($validator) {
                $this->errors = $validator->failed();
            });
        })->validate();
        ...
    }

}

Then in blade:

<div 
x-data="{
errors: @entangle('errors'),
focusError() {
    es = Object.keys(this.errors);
    if (es.length == 0) { return }
    $focus.focus(document.getElementsByName(es[0])[0]);
  }
}"
x-init="$watch('errors', value => focusError())"
>

You could also scroll to element instead of or in addition to focus.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.