AutoFocus on Form Input

I’m creating a form using LiveWire.

The gimmick is that is one question, click next and LiveWire pulls next question. Etc…

The problem is autofocus.

On the first question it’s fine, user can type in the answer.

Subsequent questions, autofocus does not work.

Is there a way to trigger autofocus, when LiveWire pulls a new question? I cant see anything in the docs.

<div class="flex max-w-2x1" wire:key="question-{{$input_name}}">
<input wire:model.lazy="{{$input_name}}" type="{{$activequestion->inputtype ?? 'text'}}" autofocus>
</div>

I solved it with triggering an event:
$this->emit('newfocus');

Then adding normal javascript:
<script> document.addEventListener('livewire:load', () => { window.livewire.on('newfocus', inputname => { document.getElementById("currentInput").focus(); }) }); </script>

Then giving the form input a target of “currentInput”:
<input wire:model.lazy="{{$input_name}}" type="{{$activequestion->inputtype ?? 'text'}}" id="currentInput">

This works but now LiveWire is retaining the input from the last question, thinking its the same question (as they all have same id). So, thats not working. I think i need a better JavaScript and ID Selector solution…

You might think about using Alpine and x-init. If you have the Alpine x-data on a component that gets swapped out every time, you can trigger javascript within x-init.

<div> {{-- livewire root--}}
    <div x-data x-init="$refs.answer.focus()"> <!-- this component needs to swap out -->
        <input wire:model="answer" x-ref="answer" type="text">
    </div>
</div>
6 Likes

A huge thanks for this @shortbrownman your solution is so much cleaner. Helped me understand Alpine a bit better too.

1 Like