Jump to content

Use relative date input in datetime field


MarkE
 Share

Recommended Posts

I've done some searching for an answer on this as I can't believe it has not come up before:

My problem is that I would like to use a "selector" field (i.e. the interactive selector builder) to compare, for example, a datetime field with 'today'. The issue is that I want it to operate dynamically, so the comparator needs to be stored as 'today' and only converted when the selector is run.

This works fine if I just use a text field instead of the selector field and allow the user to input a selector string - e.g. "myDatetime>today", but in the selector builder the comparison field requires an absolute date - a string entry of a relative date is impossible. However, for many reasons, I would prefer not to have a user attempting to enter a selector string.

Has anyone tried something similar? If not, I'm toying with the idea of writing a module to extend InputfieldDatetime. That would permit the storing of a valid string as well as an actual date. The string would be only converted to a date at runtime. This would allow entering a date as, for example, 'last month' such that when the field is formatted it would be displayed as a date one month before the execution date. This contrasts with the present module where, although you can default to 'today', I think that is converted to a timestamp at the time of entry and stored as such. Any thoughts on that?

Link to comment
Share on other sites

When searching a datetime field the PW PageFinder can use any string that the PHP strtotime() function understands. So the problem you're describing only relates to limitations on the input where you are putting your search value. InputfieldSelector uses the jQuery UI datepicker for the value input, and this has a constrainInput setting that's true by default.

So if you set constrainInput to false you can enter free text into the input and it should just work. You have to set this option after the datepicker is initialised because PW doesn't provide any way of customising the datepicker options before initialisation (I've opened a request for that here: https://github.com/processwire/processwire-requests/issues/523).

Here's how you might do it with some custom admin JS:

$(document).on('focus', '.InputfieldSelector .InputfieldDatetimeDatepicker', function() {
	const $el = $(this);
	// Set constrainInput to false after a brief delay so that the datepicker has had time to initialise
	setTimeout(function() {
		if($el.datepicker('option', 'constrainInput')) {
			$el.datepicker('option', 'constrainInput', false);
			// Updating the option seems to cause the datepicker to hide so show it again
			$el.datepicker('show');
		}
	}, 100);
});

The result in Pages > Find as an example:

image.png.801cade75d40cb109645174784fdb67a.png

 

Edit: you may know this already but you can add a custom row to InputfieldSelector where you can use any selector clause you like. So if you can trust your editors to get the field name right you could have a row like this:

image.png.01c84a3303f77fc460b20be7a819c6c4.png

This is the better option if you want to save the value in a Lister bookmark for example, as it seems that InputfieldDatetime will convert a time string to the equivalent timestamp when it reloads so it then loses the "dynamic" aspect. 

  • Like 3
  • Thanks 1
Link to comment
Share on other sites

9 hours ago, Robin S said:

Here's how you might do it with some custom admin JS:

That works @Robin S. Thanks a lot. However, as you say 

9 hours ago, Robin S said:

it seems that InputfieldDatetime will convert a time string to the equivalent timestamp

so it doesn't meet my need for the relative date to be used dynamically, which is why I was wondering if what is really needed is an extension or modification of InputfieldDatetime so that it can store a strtotime-comprehensible text field. Meanwhile the custom row is another option which is less user-friendly, but probably better than just allowing a selector input ion a plain text field.

  • Like 1
Link to comment
Share on other sites

Posted (edited)
32 minutes ago, MarkE said:

Meanwhile the custom row is another option which is less user-friendly, but probably better than just allowing a selector input ion a plain text field.

However, I also had problems using the generated result (e.g. 'template=96, _custom="eventDate>2 months ago"') in the $pages->find() api. It returned all pages matching the template. I had to use regex to turn 'template=96, _custom="eventDate>2 months ago"' into 'template=96,  eventDate>2 months ago' which seems a bit clunky.  The answer is to  set the allowCustom option to true in find().

Edited by MarkE
Correction
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...