gabelbart/nova-improved-date-field

A Laravel Nova field.

0.5.4 2023-06-26 13:30 UTC

This package is auto-updated.

Last update: 2024-04-26 15:07:55 UTC


README

This package for Laravel Nova aims at improving the default date and datetime field. The problem with the original field, that it has very little options for customizing the date format.

The \Gabelbart\Laravel\Nova\Fields\Date\Date and \Gabelbart\Laravel\Nova\Fields\Date\DateTime fields provided by this package are derived from the original \Laravel\Nova\Fields\Date and \Laravel\Nova\Fields\DateTime fields. However, the Vue components got replaced with a more customizable version, that is still using the luxon package. This package can coexist with the native Date/Datetime fields of laravel Nova.

This package also provides an option to use flatpickr since some browsers have incomplete support for the type="datetime-local" input field. The flatpickr will only be enabled on Firefox-desktop (enableFirefoxFlatpickr) and Safari (enableSafariFlatpickr)

Requirements

  • php: ^8.0
  • laravel/nova: ^4.0

Usage

Installation

Install the package via Composer:

composer require gabelbart/nova-improved-date-field

Getting started

Just use it like the default Laravel Nova date(time)-fields. For customizing behavior and appearance see options below.

<?php

namespace App\Nova;

use Laravel\Nova\Fields\ID;
use Laravel\Nova\Http\Requests\NovaRequest;

use Gabelbart\Laravel\Nova\Fields\Date\DateTime;

class User extends Resource
{
    public static $model = \App\Models\User::class;
    public static $title = 'name';
    public static $search = ['id'];

    public function fields(NovaRequest $request): array
    {
        return [
            ID::make()->sortable(),

            DateTime::make('Email verified at'),
        ];
    }

    // snip...
}

Or just replace the imports of \Laravel\Nova\Fields\DateTime or \Laravel\Nova\Fields\Date with \Gabelbart\Laravel\Nova\Fields\Date\DateTime or \Gabelbart\Laravel\Nova\Fields\Date\Date.

Options

enableFirefoxFlatpickr(bool $flag = true)/enableSafariFlatpickr(bool $flag = true)

The Firefox/Safari implementation of the datetime-local field is incomplete with the desktop browser. For the date a picker is provided but the time has to be entered manually. This can confuse some users. Setting this option to true will enable flatpickr in the Firefox desktop browser.

\Gabelbart\Laravel\Nova\Fields\Date\DateTime::make('Created at')
  ->enableFirefoxFlatpickr()
  ->enableSafariFlatpickr();

If you need users to be able to clear the field use the nullable option for Laravel Nova's Fields. This wil enable a clear button within the flatpickr dialog.

intlDateFormatOptions(array $options)

Set the Intl.DateTimeFormat parameters for luxon's DateTime.toLocaleString method. In the original implementation of Novas Vue component these where hardcoded.

It is not possible to change the format of the picker input, this will always be the format defined by the browser!

\Gabelbart\Laravel\Nova\Fields\Date\DateTime::make('Created at')
  ->intlDateFormatOptions([
    'year' => 'numeric',
    'month' => '2-digit',
    'day' => '2-digit',
    'hour' => '2-digit',
    'minute' => '2-digit',
  ]);

See the MDN docs for a full list of possible options.

timezone(?string $timezone)

By default, the field will use the timezone configured via Nova. With this option you can change the timezone used to display the date. Call this option with null to revert the prior calls to timezone.

\Gabelbart\Laravel\Nova\Fields\Date\DateTime::make('Created at')
  ->timezone('Africa/Nairobi');

See a full list of timezones on timezonedb.com

showTimezone(bool $flag)

Show the timezone for the value. On index/detail this will set the timeZoneName for the Intl.DateTimeFormat. On forms this will show the name of the timezone behind the input.

!!! This option can conflict with intlDateFormatOptions:

  • If you set this to false but configured a timeZone option for intlDateFormatOptions, it will still display a timezone.
  • If you set this to true the timeZone option for intlDateFormatOptions will be overwritten with timezoneName

You can use these options to fine tune the visibility for index, detail and form

  • showTimezoneOnIndex
  • showTimezoneOnDetail
  • showTimezoneOnForms

timezoneName(string $name)

Change the display of the timezone. This will only have effect in combination with showTimezone(true). Possible values can be found at the MDN docs for Intl.DateTimeFormat.

You can use these options to fine tune the display for index, detail and form

  • timezoneNameOnIndex
  • timezoneNameOnDetail
  • timezoneNameOnForms

showDiff(bool $flag = true)

Show a diff created with luxon's DateTime.toRelative method. On forms this will show a diff behind the input, live-updating to the date set via the input.

You can use these options to control the diff-display for index, detail and form

  • showDiffOnIndex
  • showDiffOnDetail
  • showDiffOnForms

showDiffAsPrimaryInformation(bool $flag = true)

By default, the diff enabled via showDiff will be shown in parentheses behind the date. You can invert this behavior by setting this option. The diff will be shown as primary value and the date in parentheses behind it.

comment(?string $comment = null)

Sow a comment behind the value. This is especially useful if you changed the timezone so something else but the user/app timezone via the timezone option.

hideCommentFromIndex(bool $flag = true)

Prevent the comment from getting shown on index columns in order to save space.

Recommendations

This step is optional, but I'd suggest that you derive your own classes from \Gabelbart\Laravel\Nova\Fields\Date\DateTime and \Gabelbart\Laravel\Nova\Fields\Date\Date. This way you will be able to improve on consistency, maintainability and readability of your code!

In your custom classes you can predefine Constants for the formats you are aiming to use in your app like \App\Nova\DateTime::FORMAT_SHORT or \App\Nova\DateTime::FORMAT_LONG (see intlDateFormatOptions for details). You can also predefine sets of options you want to combine in methods to maintain the DRY principle.

Alternative:

Both \Gabelbart\Laravel\Nova\Fields\Date\DateTime and \Gabelbart\Laravel\Nova\Fields\Date\Date can be configured with global defaults. This can be done via the setDefaults and addDefaults static methods. Call these in your \App\Providers\NovaServiceProvider::boot method. The setDefaults method replaces all defaults already present, the addDefaults merges the already registered defaults with the ones passed as parameter. The Parameter is an array option => [value], for possible options see the 'Options' section below.