Skip to content
Grav 2.0 is officially stable. Read the announcement →

Community guidelines

Please keep discussions civil and on-topic. Repeated violations may lead to a temporary ban.

General

Using DatePicker in Form with dynamic min date

Solved by Thomas View solution

Started by Thomas 4 years ago · 5 replies · 3461 views
4 years ago

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:

YAML
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?

last edited 05/12/22 by Thomas
4 years ago

@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:
    YAML
    ---
    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:

    PHP
    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:
    TXT
    <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.
last edited 05/12/22 by pamtbaau
4 years ago

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:

PHP
        // 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.

4 years ago

@red

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

4 years ago Solution

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:
YAML
---
    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 }:
PHP
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:
TXT
<input name="data[startdate]" value="" type="date" min="2022-05-12" max="2022-05-31" class="form-input ">
👍 1
last edited 05/13/22 by Thomas
4 years ago

As for my other requirement,

For a hotel form with arrival_date & departure_date fields, set the departure_date’s datepicker minimum date to be 1 day after the date entered by the user in the previous arrival_date field

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.

Suggested topics

Topic Participants Replies Views Activity
General · by Jerry Hunt, 4 days ago
2 95 14 hours ago
General · by pamtbaau, 20 hours ago
1 61 19 hours ago
General · by Andy Miller, 1 day ago
0 47 1 day ago
General · by Marcel, 12 months ago
6 356 5 days ago
General · by Duc , 6 days ago
3 44 6 days ago