Using DatePicker in Form with dynamic min date

In the forms DatePicker field one can set min and max values for dates. For bookings of a stay in a hotel, I would like to set the min date as follows.

Is there a way:

  • for arrival_date field: to block dates before “today” (not a fixed date);
  • for departure_date field: to allow only dates after arrival_date?

For departure_date, I tried, among others:

validate:
    required: true
    min: "{{ form.value.arrival_date }}"
    max: "2100-12-12"

but that did not work.

Thank you for suggestions. May be @maria have the solution?

@red, I’m not aware of any ‘declarative’ way and I happen to like to code…

So here is my solution for the ‘min’ date.

  • Using fresh Grav 1.7.33
  • Create page with form:
    ---
    title: Typography
    form:
      name: mindate
      fields:
        startdate:
          type: date
          validate:
            max: '2022-05-31'
      buttons:
        submit:
          type: submit
      process:
        message: 'Thanks'
    ---
    
  • Create plugin using $ bin/plugin devtools new-plugin
  • Add the following onFormInitialized() handler:
    public function onFormInitialized(Event $event)
    {
      /** @var Form */
      $form = $event['form'];
    
      if ($form->name === 'mindate') {
        $fields = $form->getFields();
        $fields['startdate']['validate']['min'] = date('Y-m-d');
        $form->setFields($fields);
      }
    }
    
  • The generated input field will now be:
    <input name="data[startdate]" value="" type="date" 
      min="2022-05-12" max="2022-05-31" class="form-input ">
    

Alternatives for ‘max’ date:

  • Setting the max date to be greater/equals the min date cannot be done elegantly. Only when the users has submitted the form. On the server, the submitted data can be checked in event ‘onFormProcessed’ and return an error when the ‘max’ date is too small. The error is not an exception, but similar to a normal validation.
  • Alternatively, you could write some javascript that will check the max date while the user is entering the form.

I thank you for your time on this & skills, sadly, my php & js is poor.

I tested your suggestion, with your form and created the plugin, without result (min=“2022-05-12” does not show up inside input), but no error message nor in the console.

I suppose I miss something in the main events part.
This is what I have at the end of the new plugin:

        // Enable the main events we are interested in
        $this->enable([
            // Put your main events here
        ]);
    }
    /**
     * My function
     */
    public function onFormInitialized(Event $event)
    {
        /** @var Form */
        $form = $event['form'];

        if ($form->name === 'mindate') {
        $fields = $form->getFields();
        $fields['startdate']['validate']['min'] = date('Y-m-d');
        $form->setFields($fields);
        }
    }
}

I tried adding ‘onFormInitialized’ => [‘onFormInitialized’, 0], just below $this->enable([, as per all other plugins, but this lead to an error: onFormInitialized() must be an instance of Grav\Plugin\Event,…

Anyway, this is just some polishing of my form and I feel like aiming too high. My life will still be OK without this.

@red

Add use RocketTheme\Toolbox\Event\Event; right below use Grav\Common\Plugin;

Great solution! Fabulous help.
Just to sum-up for others interested:

Objective: set the minimum acceptable date in a Form’s Datepicker to be the current date

  • Using fresh Grav 1.7.33
  • Create page with form:
---
    title: Typography
    form:
      name: mindate
      fields:
        startdate:
          type: date
          validate:
            max: '2022-05-31'
      buttons:
        submit:
          type: submit
      process:
        message: 'Thanks'
    ---
  • Install plugin DevTools $ bin/gpm install devtools
  • Create new plugin using $ bin/plugin devtools new-plugin

Then in the new plugin’s .php file:

  • Add use RocketTheme\Toolbox\Event\Event; right below use Grav\Common\Plugin;
  • Add ‘onFormInitialized’ => [‘onFormInitialized’, 0], just below $this->enable([
  • Add the following onFormInitialized() handler before the last }:
public function onFormInitialized(Event $event)
    {
      /** @var Form */
      $form = $event['form'];

      if ($form->name === 'mindate') {
        $fields = $form->getFields();
        $fields['startdate']['validate']['min'] = date('Y-m-d');
        $form->setFields($fields);
      }
    }
  • The generated input field will now be:
<input name="data[startdate]" value="" type="date" min="2022-05-12" max="2022-05-31" class="form-input ">
1 Like

As for my other requirement,

I understand that it cannot be done in the same way as the data have not yet been processed by the server.
I believe most users will be fine without this.

Tks again.