0

I have a very simple livewire component

class Test extends Component
{

    public $test = "test";

    public function submit()
    {
        dd($this->test);
    }

    public function render()
    {
        return view('livewire.test');
    }
}

and view

<div>
    <form wire:submit.prevent="submit" method="post">
        <input type="text" wire:model="test" id="test">
        <button type="button" id="ok">ok</button>
        <button type="submit">submit</button>
    </form>
    <script>
        const button = document.getElementById('ok');
        button.addEventListener('click', function() {
            const input = document.getElementById('test');
            input.value = "Test";
        });
    </script>
</div>

I simplified the code for illustrative purposes to show that JavaScript changes a value.

When I click ok what changes the value from test to Test and then submit, I get test shown instead of Test.

I except to see Test. What am I doing wrong?

It seems that the Livewire Component is not recognising the change from the Javascript code, as the following function doesn't fire either:

public function updatedTest()
{
   dd("Fired");
}

2 Answers 2

2

What @Peppermingtology said isn't entirely true. He is right that it is not the preferred way of handling Livewire, but sometimes you can't escape it.

You can indeed use AlpineJS and that will solve your issue, but you can also cast a normal change event. Your Livewire variable isn't updating because Livewire has not detected any change. That's because programattically updated inputs don't trigger any event by default to prevent infinite event loops.

If you simply add an event, it should also work:

const input = document.getElementById('test');
input.value = "Test";
let event = new Event('change', {bubbles: true});
input.dispatchEvent(event);
Sign up to request clarification or add additional context in comments.

1 Comment

I wanted to add that if the change event still doesn't update your variable, it might be because Livewire has made some changes, and now strictly listens to change only on wire:model.lazy and uses input for wire:model.
1

You can't manipulate properties in that manner with Livewire. The preferred way is to use the AlpineJS entangle method which specifically caters for sharing state between Livewire and your client.

That being said, you can achieve what you're after without using AlpineJS. Replacing your existing JavaScript with the below should get you the result you're after.

<script>
    document.addEventListener('livewire:load', (evt) => {
        const button = document.getElementById('ok');
        button.addEventListener('click', function() {
            document.getElementById('test').value = @this.test = 'Test';
        });
    })
</script>

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.