
With two related date picker fields limit the end date to be after the start date.
Update: David Brabyn tweeted that it wasn’t working in a repeater field in an options page. I investigated and did a big rewrite, removing the field keys requirement and supporting Date Picker fields inside a Repeater field. The start date field needs to have a ‘start-dp-wrapper‘ class and the end date field needs the ‘end-dp-wrapper‘ class.
I am working on a tourism based website and it uses Advanced Custom Fields extensively. They enter ‘Start tour’ and ‘End tour’ dates and want to ensure the end cannot be before the start.
The ACF documentation
ACF has extensive documentation with many examples.
I read about the acf/render_field action as a way to output additional HTML before or after a field. I decided to use it to specify what admin pages I added my JavaScript code via the acf/input/admin_footer action.
I limited the acf/render_field action to date picker fields to reduce the number of times it was called. I used an array of field keys so that the acf/input/admin_footer action is only called when one of those fields is on the page.
That was all the easy part.
Date Picker initialisation
I then read about the ACF JavaScript API. It’s like hooks for JavaScript. Brilliant!
For a Date Picker field it runs an init action and an args filter. I added both and added console.log() calls to see the incoming data (similar to how I would use error_log() to debug PHP code in WordPress).
I used the args filter to set the year range to be from current year to 10 years in the future.
Setting End tour date
The main UX change requested was to simplify entering the end tour date. The client often arranges tours for 18 months to 2 years into the future. Tours are generally 1 to 3 weeks long.
After a number of mouse clicks to set the ‘Start tour’ date they have to repeat those clicks to set the ‘End tour’ date. It’s a bit tedious and error prone. Ensuring that the ‘End tour’ date cannot be before the ‘Start tour’ date simplifies and speeds up data entry.
The Events Manager plugin sets the event end date to the same as the start date (because it can’t ever be before the start!). I read through its JavaScript and found the appropriate code and copied it.
You will see the jQuery next() function. This is because the actual date picker element does not have a known ID. The element before it is a hidden field with an ID matching the field ID (like acf-field_5eedde06a3231 where field_5eedde06a3231 is the field key). So, I target that hidden field and get the next element in order to retrieve the date picker element!
Update: With the rewrite, I use the date picker’s wrapper class to directly target the date picker input field.
The code watches for changes to the ‘Start tour’ date picker. It will then set the minimum selectable date for the ‘End tour’ date picker. If the ‘Start tour’ date is set to later than the previously selected ‘End tour’ date then the ‘End tour’ date will be changed to the new ‘Start tour’ date.
Field keys needed
Update: After my rewrite, the field keys are no longer required.
To use the code you will need the field keys of the two date picker fields. These can be found when editing the field group and checking ‘Field keys‘ from ‘Screen Options‘.

Here the field keys ‘field_5eedde06a3231‘ and ‘field_5eedde28a3232‘ will be used in the code.
Resulting behaviour


Hello admin, I’m using this plugin and when i try to change the date like you did in the photo above, i get no change in my website. please send me some details in the reply email. Thank you
Hi thanks for your efforts. How can this be used with “Date Time Picker” Field?
Thank you!!
@Max – Great question. I tweaked the code to work with Date Time Picker fields. Read the post ACF Date Time Picker – set end date to after start date.
I really love it, do i need to setup something in the code to make it work ? Name of my fields or else?
@Ip: When I rewrote the code so that it did not require the field key I didn’t add a screenshot to highlight what you have to do to make it work.
For the start date you need to give it a class of start-dp-wrapper. For the end data you give it a class of end-dp-wrapper.
Shoot, that is what i missed! The container name, i may misread! That was in the big yellow block at the start of the article.
Thank you!
@Loic – I will update the screenshots to make it clearer – I know that I would jump to the code and skip over a note block at the top of the post.