processwire-issues icon indicating copy to clipboard operation
processwire-issues copied to clipboard

InputfieldDatetime does not trigger change event on <input>

Open BernhardBaumrock opened this issue 8 months ago • 3 comments

I'm working on an auto-save feature for my current project. I check for changes in the page editor like this:

document.addEventListener("input", (e) => this.registerChange(e.target));
document.addEventListener("change", (e) => this.registerChange(e.target));

Some fields like TinyMCE need special treatment, but I also realised that date inputs also do not trigger a save and I was wondering why.

This is the fix that makes it work:

// Monitor datepicker changes
$(document).on("change", ".InputfieldDatetimeDatepicker", (e) =>
  this.registerChange(e.target)
);

But I think it would be better to also trigger the change event in InputfieldDatetime.js:

if (pickerVisible) {
	$datepicker.on("change", function (e) {
		var d = $datepicker.datepicker("getDate");
		var str = $.datepicker.formatDate(dateFormat, d);

		// add .trigger('change') here
		$t.val(str).trigger("change");
	});
}

BernhardBaumrock avatar Apr 14 '25 16:04 BernhardBaumrock

@BernhardBaumrock I can't see to duplicate that. I edited a page with an InputfieldDatetime field using the datepicker and then typed this into the browser dev tools js console:

$('.InputfieldDatetimeDatepicker').on('change', function() { console.log('change') });

Every time I change the value in the datepicker, I get a "change" in the console, whether selecting from the datepicker or typing the value in the input.

ryancramerdesign avatar Apr 17 '25 14:04 ryancramerdesign

Hey @ryancramerdesign thx!

This is because jQuery has a totally custom implementation of event handling: https://github.com/jquery/jquery/issues/4815#issuecomment-736855180

So a jQuery event listener works:

$('#Inputfield_magicfrom').on('change', () => console.log('jQuery change'));

Image

But a native (vanilla) JS event listener doesn't:

document.addEventListener('change', () => console.log('native change'));

Try to edit any other field (like a select or a regular input). There it will fire.

I'm thinking... maybe it's best to stick to jQuery event handling then with all my backend js code?

BernhardBaumrock avatar Apr 17 '25 14:04 BernhardBaumrock

From jQuery UI docs (https://api.jqueryui.com/datepicker/):

This widget manipulates its element's value programmatically, therefore a native change event may not be fired when the element's value changes.

The non-standard/custom event handling mechnanism in jQuery does indeed mean that, in my experience, in e.g. our admin it is better to rely on jQuery .on() than JS event listeners.

teppokoivula avatar Apr 18 '25 09:04 teppokoivula