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

WallyJ's avatar

Livewire and Bootstrap Datepicker

I like the Boostrap datepicker and am trying to use it, and it works fine at choosing and showing the date in the field. But I can't get it into the db.

I have seen this discussion: https://forum.laravel-livewire.com/t/using-livewire-with-select2-selectpicker/18 And these docs: https://laravel-livewire.com/docs/third-party-libraries/

But I can't get my code to allow the correct property to receive the correct value in my Livewire component:

Component View:

<div class="col-md-6">
    <div class="row">
        <div class="col-md-9"><h3><a href="/deals/{{$this->deal->id}}">{{$this->deal->dealtype}}</a></h3></div>
        <h1>DealID: {{ $this->deal['id'] }}</h1>
        <div class="col-md-3">
            <a href="link_to_action('DealsController@destroy', $title, $parameters = array(), $attributes = array());">Delete</a>
        </div>
    </div>
    <div class="tasks">
        <h5>Tasks</h5>
        <div class="card-block">
        <div class="form-row">
            <div class="input-group form-group col-md-9">
                <input type="text" name="tasktext" class="form-control" placeholder="New Task" wire:model="tasktext">
            </div>
            <div class="form-group col-md-3" id="datepickerfield">
                <div class="input-group date taskduedatepicker">
                <input type="text" name="taskduedate" class="form-control datepicker" id="taskduedate" placeholder="Due Date" data-provide="datepicker" data-date-autoclose="true" data-date-today-highlight="true" autocomplete="off">
                </div>
            </div>
        </div>
        <div class="form-row">
            <div class="form-group col-md-12">
                <button class="btn btn-primary" wire:click="addTask" type="submit">Add</button>
            </div>
        </div>
        </div>
        <div>
            <ul class="list-group">
                @foreach($this->deal['tasks'] as $task)
                <li class="list-group-item d-flex justify-content-between align-items-center">
                    <div>
                        <input type="checkbox" class="mr-4">
                        {{Carbon\Carbon::parse($task['taskduedate'])->format('m/d/Y')}} - {{$task['tasktext']}}
                    </div>
                    <div>
                        <form class=".mb-0" action="#" method="POST">
                            @csrf
                            <button class="btn btn-sm btn-danger">&times;</button>
                        </form>
                    </div>
                </li>
                @endforeach
            </ul>
        </div>
    </div>
</div>
<script>
('#datepicker').datepicker({
   dateFormat: 'dd-mm-yy',
   onSelect: function(taskduedate) {
       @this.set('taskduedate', taskduedate);
   }
});
</script>

Controller:

public function addTask()
    {
        $this->deal->tasks()->create([
            'tasktext' => $this->tasktext,
            'taskduedate' => $this->taskduedate,
        ]);
    }

It may be that my Javascript is wrong. it probably is, but I'm a JS noob and have no idea what could be wrong.

My understanding is that this JS is supposed to declare the value of the "taskduedate" to Livewire so it receives it in the "$this->taskduedate" value in the controller.

0 likes
17 replies
Snapey's avatar

wire:bind the input field to the public property in the component

WallyJ's avatar

I changed the section of my view to be this:

<div class="input-group date taskduedatepicker">
  <input type="text" name="taskduedate" wire:bind="taskduedate" class="form-control datepicker" id="taskduedate" placeholder="Due Date" data-provide="datepicker" data-date-autoclose="true" data-date-today-highlight="true" autocomplete="off">
</div>

And I still get "null" if I dd($this->taskduedate) in my controller.

Did I get the syntax correct?

I believe the correct way to bind data is to use wire:model, but the resources I mentioned explain that wire:model does not work with other JS because of how it affects the value. The suggestion is to remove wire:model and add JS that manually sets the value for that Livewire property on the changed value of the input field.

That is why I added the script at the end of the view. I believe the problem lies there, unless I'm missing something else.

Snapey's avatar

And I still get "null" if I dd($this->taskduedate) in my controller.

Controller or Component

There is no way the data gets to your controller unless you post it as a form.

Snapey's avatar

In the earlier post, I should have said wire:model="taskduedate" but I was working from memory

Snapey's avatar

Livewire component binds to a single root element so you might need to move your script inside the div so that it has access to the same component scope.

WallyJ's avatar

It is the "controller" of the component itself. Sorry if I am not using the right terminology.

If I dd($this->tasktext), I see what I input into the "tasktext" input box, so the data is getting sent to that component controller file. Just not the taskduedate.

Also, my understanding of Livewire's purpose is to send the data to the component controller which rewrites the DOM with the new data without technically submitting a form, though the data still persists to the db and changes on the page without a page refresh.

Snapey's avatar

The problem is that Livewire does not notice that the date field has changed.

If you use wire:model as suggested, change the date with the datapicker, then make a small change to the text in the date field, Livewire will notice it has changed and push the new value to the server.

So, I think something like you tried within the datepicker events will be required, but it MUST be within the scope of the Livewire component, and its single root element (a div in your case)

In your datepicker javascript, add a console.log to see if it is being fired when the date changes.

WallyJ's avatar

Sorry for the late reply. I was out of the country for a while.

Thanks for the suggestion. However, I'm using the Bootstrap datepicker that calls an external js file and then uses data properties to create the datepicker, so there isn't really a script section of my code where I can add a console.log event.

There's something wrong with my simple javascript that isn't setting the property value correctly. I was hoping someone familiar with Livewire and datepickers would notice what I'm doing wrong.

masepri's avatar

At your javascript, add this code:

$('#datepicker').on('change', function (e) {
       @this.set('taskduedate', e.target.value);
});

so that your javascript code looks like this:

<script>
('#datepicker').datepicker({
   dateFormat: 'dd-mm-yy',
});

$('#datepicker').on('change', function (e) {
       @this.set('taskduedate', e.target.value);
});
</script>
3 likes
Snapey's avatar

This seems to work with the Bootstrap Datepicker. Not confirmed in all browsers though;

<input 
	wire:model="taskduedate"
	type="text" class="form-control datepicker" placeholder="Due Date" autocomplete="off"
	data-provide="datepicker" data-date-autoclose="true" 
	data-date-format="mm/dd/yyyy" data-date-today-highlight="true"                        
	onchange="this.dispatchEvent(new InputEvent('input'))"
 >

Livewire is looking for an input event to know that the field is dirty. The date picker seems to not trigger any input events, but it does trigger a regular input onchange event. We can hook into this and dispatch an input event. This causes Livewire to sync the field with the server.

19 likes
twoarmtom's avatar

I was having a similar issue and this fixed it, thanks!

1 like
Distinta's avatar

@Snapey Ohhh yeaaahh!! for many days fighting and thanks to your contribution I managed to solve! onchange="this.dispatchEvent(new InputEvent('input'))" worked the miracle! works for jQuery datetimepicker as well. Thank you very much!!

virgiltu's avatar

@Snapey I know this is old but this is till an issue all date pickers. The trick was as @snapey said onchange="this.dispatchEvent(new InputEvent('input'))"

Please or to participate in this conversation.