How to Create Date Field in Gutenberg

It’s relatively easy to create date/time picker in Gutenberg editor. What we need to do is to import and use DateTimePicker component and we can create something like this:

Here’s the step by step to create date/time picker:

This tutorial is using “My Data” plugin as base. You can read more about it here: Custom Field & Meta Box in Gutenberg Editor

1. Import Components.

To create this date field, we will need to import several components:

  • PanelRow: this is generic panel element.
  • Popover: popup element.
  • Button: we can use other element (like span or link), but WordPress use button as trigger to open popup, probably for accessibility reason.
  • dateI18n: this is to convert the date to different formats. You can read more in date module documentation.
const {
    date: { dateI18n },
    components: { DateTimePicker, Popover, Button, PanelRow },
} = wp;

2. Add state to Popover

We will need to add state management to the date popup, we will need to open it if user click date field and we also need to close if it’s not in focus/no longer use.

To do that we need to use useState() function.

const [openDatePopup, setOpenDatePopup] = useState( false );

And when user click the button we will set the state openDatepopup to true/false:

<Button isLink={true} onClick={() => setOpenDatePopup( ! openDatePopup )}>
   Click here to set date.
</Button>

After that, we need to open the popup if the openDatePopup state is true.

{ openDatePopup && (
    <Popover onClose={ setOpenDatePopup.bind( null, false )}>
        Date piker goes here.
    </Popover>
) }

And now we will have a fully working popup:

3. Add Date & Time Picker.

<DateTimePicker
    label="My Date/Time Picker"
    currentDate={myData}
    onChange={setMyData}
    is12Hour ={true}
/>

It’s simple and straightforward to use. We set the label, onChange callback function, and set the current value in currentDate attr. If we use am/pm in time picker we can set is12Hour attr to true (set it to false if we use 24h format).

At this stage, the date field is actually working fine. We can select the date & time, and if we save the post, it will actually save the field properly.

The next step is to finalize it by dynamically changing the “Click here and set date” text to the selected date/time field.

4. Show the Date & Time in Button Text

{ myData ? dateI18n( 'F j, Y g:i a', myData ) : "Pick Date & Time" }

So basically, if the data is set, we will use the data and convert it to F j, Y g:i a (php) format. If not set, we simply use “Pick Date & Time” text.

And that’s it. It’s so cool that we have this component available to use.

You can download the code at github in my-data repo (feature/datetime branch)

5. Additional Information:

  1. The date field stored is WordPress MySQL DATETIME. example: 2020-06-21T11:22:00 / Y-m-d H:i:s
  2. You can use gmdate() or WordPress date_i18n() to convert it to another format in front-end/template.

Let me know if you have any question about date/time field!

9 Comments

  1. Brent

    Great tutorial. Would be super helpful to understand how to incorporate validation into this. I.e. can only select future dates, or something like that?

  2. sonaise

    It was indeed very helpful and insightful. A good informative post that you have shared and thankful your work for sharing the information. I appreciate your efforts and all the best.

  3. makkaan com

    To create a date field in Gutenberg, you can use the “Date & Time” block. Simply add the block to your blog post, and it will allow you to select the desired date format and customize the appearance. This feature is useful for displaying the publication date, event dates, or any other date-related information within your blog content.

  4. Deeksy

    Thanks for the info.
    I have a glitch in Gutenburg where my datepicker is a 1 hour out. I’m assuming it has to do with British Summer time but I cannot find where the error is coming from. If I put 11am in the datepicker, the page displays 10am.
    Time zone is set to London.

Comments are closed.