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

glennmulleners's avatar

Datepicker & date accessor

Hi,

I've created a Model which has a datetime column called start.

I've written the following accessor:

    /**
     * Get the start.
     *
     * @return \Illuminate\Database\Eloquent\Casts\Attribute
     */
    protected function start(): Attribute
    {
        return Attribute::make(
            get: fn ($value) => Carbon::createFromFormat('Y-m-d H:i:s', $value)->format('d-m-Y H:i'),
        );
    }

It works, except when I'm on the Edit screen. The value in that case is empty, so I guess I need to modify the settings for the Datetime field / Datepicker.

I can't figure out what/where to edit in order to get the field prepopulated with the value from the database.

Already tried different settings for $casts, which currently is:

    protected $casts = [
        'start' => 'datetime',
    ];
0 likes
8 replies
tykus's avatar

How are you passing the current value to the Datepicker? What format(s) does the Datepicker expect/support?

glennmulleners's avatar

@tykus I'm using Vemto which created the basic structure (using the UI Template Laravel Jetstream).

This is a part from the generated resources/views/app/timeslots/form-inputs.blade.php

    <x-inputs.group class="w-full">
        <x-inputs.datetime
            name="start"
            label="{{ __('crud.timeslots.inputs.start') }}"
            value="{{ old('start', ($editing ? optional($timeslot->start)->format('Y-m-d\TH:i:s') : '')) }}"
            max="255"
        ></x-inputs.datetime>
    </x-inputs.group>

resources/views/components/inputs/datetime.blade.php contains the following code:

@props([
    'name',
    'label',
    'value',
])

<x-inputs.basic type="datetime-local" :name="$name" label="{{ $label ?? ''}}" :value="$value ?? ''" :attributes="$attributes"></x-inputs.basic>
tykus's avatar

@glennmulleners so it eventually becomes a <input type="datetime-local"> element?

<x-inputs.datetime
    name="start"
    label="{{ __('crud.timeslots.inputs.start') }}"
    value="{{ old('start', ($editing ? $timeslot->start?->toDateTimeLocalString() : '') }}"
    max="255"
></x-inputs.datetime>
glennmulleners's avatar

@tykus That is correct. Source code in Chrome looks like this (as you can see, "value" stays empty):

<div class="px-4 my-2 w-full">
    <label class="label font-medium text-gray-700" for="start">
    Start
</label>
<input type="datetime-local" id="start" name="start" value="" class="block appearance-none w-full py-1 px-2 text-base leading-normal text-gray-800 border border-gray-200 rounded" max="255" autocomplete="off">
</div>

When I don't use the accessor, the input does have a value:

<input type="datetime-local" id="start" name="start" value="2022-05-08T13:00:00" class="block appearance-none w-full py-1 px-2 text-base leading-normal text-gray-800 border border-gray-200 rounded" max="255" autocomplete="off">
tykus's avatar

@glennmulleners first, I should have added above that it should be enough (in the Model) to cast the start column value to a Carbon instance using:

protected $casts = [
    'start' => 'datetime',
];

Next, is $editing actually truthy?

glennmulleners's avatar

@tykus Sorry if I don't get it.

I've already added the $casts like you mentioned.

If I modify the accessor then like below, I get error Call to a member function format() on string:

    protected function start(): Attribute
    {
        return Attribute::make(
            get: fn ($value) => $value->format('d-m-Y H:i'),
        );
    }

I'm just trying to modify the (displayed) date on the various places to become d-m-Y H:i instead of the default Y-m-D H:i:s

When not using the accessor, it's correct on the "edit" screen (d-m-Y H:i), but not on other places like the "show" or "index" screen.

tykus's avatar
tykus
Best Answer
Level 104

@glennmulleners Use the cast or the accessor method; not both. I suggested the cast because this gives you a Carbon instance to work with - you can then format it differently in different contexts, whereas the accessor (as you have implemented it) will always give you a String.

glennmulleners's avatar

@tykus Thanks, I'll use the $casts and use ->format() in the Blade templates where appropriate.

1 like

Please or to participate in this conversation.