Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

vincej's avatar
Level 15

LiveWire: How to action the value of an input without a button

Ok, I am a total LiveWire newb.

So I have a text input which used only to take a numeric value. When I check the Chrome network tab, everything appears to be working when I add say 17.00 to the input- Great. I tried to get it to echo on the page, with no luck, don't know why. Anyway, not an issue.

The couple of tutorials I have seen (eg Bitfumes) all use a button to progress the input. I don't want a button. I want to save the input upon loosing focus. I can not see how to do this.

Many thanks

0 likes
25 replies
chaudigv's avatar

You can simply use wire:change="save()" on the input tag.

vincej's avatar
Level 15

@jlrdw @chaudigv Thanks for that. I am impressived you found that event. It is only a very small passing comment in the docs.

I don't know what is wrong with me. But I am struggeling to get my head around Livewire / Alpine. I guess I am deeply scripted in raw Javascript and JQuery having used it for many years. In contrast to the Vuejs docs, I find the LIvewire docs are frustrating, and not very well written. I have been hunting around for good tutorials and have not found one yet. It must be me.

As much as most people say on the web that Livewire is easy, and Vue is difficult, I am actually finding the opposite. Someone told me that to use Vue you need to be proficient in OOP for Javascript. Is that your experience? I have not come across that yet, and admitedly I know nothing of OOP for JS.

Many thanks.

zerosAndOnes's avatar

I tried getting into vuejs, but I couldnt.. Surprisingly, React seemed easy for me. But livewire has been quiet easy too. I have been doing trial and error with it, since I am new and I have been picking up a couple of ideas.

In the case of what you want to do, I think using a model/data binding on the input field and echo it out. Whatever variable you bind to the input should be made public in the livewire model file.

Snapey's avatar

hi Vince

The input is wire:model to the public property in your component. This binding is two-way. Whenever you change the value on either side, it is reflected in the other.

So with your input element, every keypress sends a network request to the backend to keep it in sync.

If you don't need this level of coupling, you can add .lazy to the wire model statement and now the network request is only sent when the field is dirty and looses focus.

You can echo the public property elsewhere on the page with simple blade {{ }} tags

If you want to perform logic on the backend when the public property changes value then you can create updating or updated methods (public property $foo monitored with updatedFoo() )

No need for a button to trigger actions.

Hope this helps

2 likes
vincej's avatar
Level 15

Hi Mark,

My Livewire set up appears to work ins o far that when I watch the Chrome Network tools, I can see ajax calls being made. However for the life of me it refuses to echo out on the page. Indeed, if I place the {{}} anywhere other that within the component I get a can't find variable error. Here is my set up:

View: registration.php.blade

<div class="col-md-2" > @livewire('rate') </div>

Component: rate .php.blade

<input type="text" class="form-control" wire:model="billingRate">
    
    <h4>
      {{$billingRate}}   {{--Trying to echo out the value here--}}
    </h4>
    

Controller: Rate.php

namespace App\Http\Livewire;

use Livewire\Component;

class Rate extends Component
{
     public $billingRate;

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

DivDax's avatar

Your Livewire blade template has two root elements. Wrap the content in a single div.

vincej's avatar
Level 15

@divdax Thanks but I can't see it, can you please point it out ? Thanks

DivDax's avatar

The Livewire doc says:

Livewire components MUST have a single root element.

your template should look like this:

<div>
  <input type="text" class="form-control" wire:model="billingRate">
    
  <h4>
      {{$billingRate}}   {{--Trying to echo out the value here--}}
  </h4>
</div>
vincej's avatar
Level 15

Oh bugger .... thank you!!! It's working.

vincej's avatar
Level 15

One last thing - if I place {{$billingRate}} outside of the component, anywhere else on the page, I get a can not find variable error. Is this the way it should be ?

vincej's avatar
Level 15

I am very greatful for all your help, and that I now have my input being echoed out. However, I still have not managed to solve my essential problem - how to pass the input value to my controller without a button.

I expect that it has something to do with Events, https://laravel-livewire.com/docs/2.x/events#from-template

However, I find the docs unclear in how and when to use $emit. Can someone please show me what I am doing wrong?

Many thanks!

Snapey's avatar

Why does the value need to get to your controller?

Data can only get to controller through Post actions, for which you need a form...

vincej's avatar
Level 15

@snapey

It needs to get to the controller because I want to save the input value of billingRate

A form means I need a button. I don’t want a button.

If I was using Js / Jquery I could fire a function with a simple

 ("#billingRate").on("mouseleave", function(){

// save value of id billingRate

}
 

Or something very simiylar.

I could solve this in 5 mins with JS but I am using this as a learning exercise.

Is this not easy in Livewire?

DivDax's avatar

To save the value of $billingRate you don't need a button, a form or javascript for this task. Save the value of your property inside your Livewire component.

DivDax's avatar

Like @chaudigv said: Use wire:change="save()" on your input, write a method save()in your Livewire Component and save the value of your $billingRate property. Super simple... :)

vincej's avatar
Level 15

still manage to do this wrong. w/here does the $billingRate go? All I amgetting out is error:

Unable to resolve dependency [Parameter #0 [ <required> $billingRate ]] in class App\Http\Livewire\Rate


<div>
    <input type="text" class="form-control" wire:change="saveRate()">
 </div>
class Rate extends Component
{
     public $billingRate;


    public function saveRate($billingRate){

       dd($billingRate);
    }

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


Snapey's avatar
Snapey
Best Answer
Level 122
<div>
    <input type="text" class="form-control" wire:model.lazy="billingRate">
 </div>

class Rate extends Component
{
     public $billingRate;


    public function updatedBillingRate(){

       dd($this->billingRate);     // don't forget to use $this to access class property

        // persist to database here
    }

    public function render()
    {
        return view('livewire.rate');
    }
}
2 likes
vincej's avatar
Level 15

@snapey Halleluiah! Thank you ! It works! Heaven knows what the wire:change is about.

You have the patience of a saint. I awarded you 'best answer' .

Thank you thank you !

vincej's avatar
Level 15

@snapey I don't know why I am struggleing with LiveWire, maybe because I have spent so many years with JS.

ok, so your code grabs the input value nicely. Thank you.

Next I have saved the value in the DB. However, when the page refreshes I need that value to appear in the same input. If I change that value again, then again it will be saved.

However, how in the heck can I get the DB value into the same input, when the input is being occupied by the wire:model. I really don't want two inputs. In Jquery / JS I can do this.

<div>
    <input type="text" class="form-control" wire:model.lazy="billingRate">
</div>

Many Thanks !

Snapey's avatar

Your field is mirrored both ways with the component.

You initialise it by setting the public property on the component in its mount() method

UhOh's avatar

Here's a full example. Whenever you change the input, the model will update the model. Although it's poorly documented, updated is a hook. Big issue with Livewire and Alpine is the thin documentation.

// blade view
<input type="number" wire:model.lazy="amount">
// livewire component
    public function updatedAmount($amount)
    {
        $this->goal->update([
            'amount' => $amount
        ]);
    }

Please or to participate in this conversation.