Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Datetimepicker Bundle Laravel Package

stephanecollot/datetimepicker-bundle

Symfony bundle that integrates the Bootstrap DateTimePicker widget into Symfony forms, providing a configurable date/time picker form type and the required front-end assets so you can add polished date and time selection with minimal setup.

View on GitHub
Deep Wiki
Context7

Getting Started

Install the bundle and register it. It's a Symfony‑2/3‑era bundle, so the registration mechanics depend on your Symfony version.

composer require stephanecollot/datetimepicker-bundle

Symfony ≤3 (app/AppKernel.php):

new Collot\DateTimePickerBundle\CollotDateTimePickerBundle(),

Symfony 4+ (config/bundles.php):

Collot\DateTimePickerBundle\CollotDateTimePickerBundle::class => ['all' => true],

This single step is the first thing to check when anything looks wrong — the bundle does nothing until it is enabled and its form theme is registered. Add the theme globally (recommended) in config/packages/twig.yaml:

twig:
    form_themes:
        - '@CollotDateTimePickerBundle/Form/fields.html.twig'
        # older path style: 'CollotDateTimePickerBundle:Form:fields.html.twig'

Then publish the bundle assets (Symfony 4+) and pull in the front‑end dependencies yourself — the bundle renders the input and the inline init script, but you are responsible for jQuery, Moment.js and the Bootstrap 3 datetimepicker CSS/JS:

php bin/console assets:install --symlink public

First use case: swap a plain DateTimeType on an admin form for a calendar popup. Nothing else in your entity or controller changes.

use Collot\DateTimePickerBundle\Form\Type\DateTimePickerType;

$builder->add('publishedAt', DateTimePickerType::class, [
    'pickerOptions' => [
        'format' => 'DD/MM/YYYY HH:mm',
        'pickTime' => true,
        'showTodayButton' => true,
        'sideBySide'  => true,
    ],
]);

Render the form as usual — the theme supplies the widget block that wires the JS.

Implementation Patterns

Set a sane application default once. Because pickerOptions is a plain array option, every field you add will otherwise repeat the same five lines. Either create a thin project type that extends DateTimePickerType and injects defaults in configureOptions(), or use a FormTypeExtension so all pickers inherit your house style:

class DateTimePickerDefaultsExtension extends AbstractTypeExtension
{
    public static function getExtendedTypes(): iterable
    {
        return [DateTimePickerType::class];
    }

    public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver->setDefault('pickerOptions', [
            'format' => 'DD/MM/YYYY HH:mm',
            'locale' => 'fr',
            'useCurrent' => false,
            'ignoreReadonly' => true,
            'allowInputToggle' => true,
        ]);
    }
}

Note that setDefault only applies when the caller omits the option entirely; per-field pickerOptions arrays replace rather than merge. If you need merge semantics, do it in the extension with a normalizer.

Separate the two "format" worlds explicitly. You have three formats that must agree:

Concern Option Token style Example
What the user sees in the JS picker pickerOptions['format'] Moment.js DD/MM/YYYY HH:mm
What Symfony parses on submit format ICU/IntlDateFormatter dd/MM/yyyy HH:mm
What the PHP DateTime becomes model_timezone / with_seconds — —

Date-only fields. The type parents to DateTimeType, so it always yields a DateTime. For a birthdate-style field, disable time picking and make the formats line up:

$builder->add('birthDate', DateTimePickerType::class, [
    'format' => 'dd/MM/yyyy',
    'pickerOptions' => ['pickTime' => false, 'format' => 'DD/MM/YYYY'],
]);

Bounded ranges. Keep the picker bounds and the validator bounds in sync — the picker is UX only and is trivially bypassed:

$builder->add('startsAt', DateTimePickerType::class, [
    'pickerOptions' => ['minDate' => 'now', 'maxDate' => '+1 year'],
    'constraints'   => [new Assert\GreaterThanOrEqual('today')],
]);

Integrating with AJAX / dynamic collections. The init script runs inline per widget. Rows inserted after page load need re-initialisation; the pragmatic pattern is to opt out of the generated inline script (override the widget block) and instead add a marker class via attr, then initialise in your own delegated handler:

'attr' => ['class' => 'js-datetimepicker', 'data-format' => 'DD/MM/YYYY HH:mm']

Extension points worth knowing. The Twig block (collot_datetimepicker_widget / its script block) can be overridden per project — copy it into templates/form/, adjust to emit data-* attributes instead of inline JS, and register yours after the bundle theme. That is the cleanest way to add aria attributes, custom buttons, or a picker icon.

Gotchas and Tips

  • The single most common failure is a format mismatch. If the picker writes 12/03/2024 14:30 but Symfony's format is yyyy-MM-dd, submit fails with "This value is not valid." Remember moment uses YYYY/DD/HH, Symfony uses yyyy/dd/HH. YYYY vs yyyy (week-year vs year) and DD vs dd (day-of-year vs day-of-month) are the traps.
  • getName() / block prefix drift. On Symfony 4.3+ the block prefix is derived correctly, but if you see the widget render as a bare text input, the form theme silently wasn't applied — check twig.form_themes and that the template path is right for your Symfony version (the Bundle:Dir:file.html.twig notation is deprecated/removed for bundles outside templates/).
  • Load order matters more than usual. jQuery must be present before the picker JS, and the picker JS before the bundle's inline init snippet. With defer/async or scripts in <head>, you get $(...).datetimepicker is not a function in the console — the field still renders, so it looks like a styling issue.
  • Assets after upgrade. In Symfony 4/5 the bundle's Resources/public is only served after assets:install. In Symfony 5.2+ with the new asset mapper, the public/bundles/... copies may need to be referenced by the asset() function with the full bundle path.
  • Timezone skew. JS emits local wall-clock time with no offset; PHP parses it in the form's model_timezone/view_timezone. If users report times "off by an hour" around DST, set model_timezone explicitly and store UTC.
  • Locale has two knobs. pickerOptions['locale'] picks the Moment locale file (which must actually be loaded), while the Symfony locale governs server-side parsing. Mismatched month names are the symptom.
  • Multiple pickers on a page are fine, but duplicate DOM ids (common when cloning form prototypes) break the picker's data-target wiring — ensure prototype placeholders are replaced.
  • Maintenance risk. Last tagged release was 2017 and it has no dependents. It works on Symfony 3.4/4.x, but expect friction on Symfony 5+ and a hard stop on anything that removed the old bundle/asset plumbing. Practical mitigations: pin the exact version, and if you hit an incompatibility, the realistic exit is to keep the pickerOptions API in your own form type that extends plain DateTimeType with widget => single_text and a handful of lines of JS — the bundle is thin enough that forking or inlining is cheaper than fighting it.
  • Debugging checklist when a field misbehaves: (1) is the bundle registered, (2) is the theme applied, (3) do jQuery/Moment/picker exist in the console, (4) does the rendered data-*/inline options JSON match, (5) do the three formats agree.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager