Joomla 4 Tips and Tricks: Check two dates

From Joomla! Documentation

Introduction[edit]

This code was created for an application that has events with start and end dates that must be less than 30 days apart. The code is for the Administrator data entry form.

For the sake of argument, in this example the events are described as camps. They could be festivals, horse races, conferences or anything else that has defined start and end dates.

The form XML file[edit]

The dates are required calendar fields. Note that validation is passed as a custom class starting with validate-.

		... other elements ...
		<field
			name="date_start"
			type="calendar"
			label="COM_THINGY_CAMP_DATE_START_LABEL"
			description="COM_THINGY_CAMP_DATE_START_DESC"
			class="w-25 validate-date_start"
			required="required"
			>
		</field>

		<field
			name="date_end"
			type="calendar"
			label="COM_THINGY_CAMP_DATE_END_LABEL"
			description="COM_THINGY_CAMP_DATE_END_DESC"
			class="w-25 validate-date_end"
			required="required"
			>
		</field>
		... other elements ...

The edit.php template file[edit]

Load the javascript file[edit]

The form template file is typically edit.php. This seems to be the best/recognised place to make sure the required scripts are loaded. For exanple, after the use statements, insert:

$wa = $this->document->getWebAssetManager();
$wa->useScript('keepalive')
	->useScript('form.validate')
	->useScript('com_thingy.camp');

For this to work you need to set up the installation so that the js and css assets go into the site media folder with a joomla.asset.json file. You can look up how to do that elsewhere. In this case the loaded javascript file is media/com_thingy/js/camp.js.

Add some javascript language translations[edit]

The validation script contains a couple of alert messages apart from the default messages that appear for invalid fields. The alert message translations go next in the edit.php file:

Text::script('COM_THINGY_JS_ERROR_DATES_WRONG_ORDER', true);
Text::script('COM_THINGY_JS_ERROR_DATES_TOO_FAR_APART', true);

These lines create inline script statements containing the key and translation pairs. The actual translations go in your language ini file along with all of your other string translations.

Validate the Form[edit]

The form needs class="form-validate":

<form action="<?php echo Route::_('index.php?option=com_thingy&view=camp&layout=edit&id=' . (int) $this->item->id); ?>"
	class="form-validate" method="post" name="adminForm" id="adminForm">

The joomla.asset.json file[edit]

This file is located in the root of the component media file (media/com_thingy/joomla.asset.json) and amongst other things contains the following:

    ,{
      "name": "com_thingy.camp",
      "type": "script",
      "uri": "com_thingy/camp.js",
      "dependencies": [
        "core"
      ],
      "attributes": {
        "defer": true
      }
    }

The Javascript file[edit]

In this example the events must be less than 30 days apart. That ought to be a configurable value but here it is hard-coded.

// ===== validation =====

document.addEventListener('DOMContentLoaded', (event) => {

	document.formvalidator.setHandler('date_start', function(value) {
		const regex = /^\d{4}-\d{2}-\d{2}$/;
		return regex.test(value);
	});

	document.formvalidator.setHandler('date_end', function(value) {
		const regex = /^\d{4}-\d{2}-\d{2}$/;
		if (!regex.test(value)) {
			return false;
		}
		let date_start = document.getElementById('jform_date_start').value;
		if (value <= date_start) {
			alert (Joomla.Text._('COM_THINGY_JS_ERROR_DATES_WRONG_ORDER'));
			return false;
		}
		date_start = date_start.split('-');
		date_start = new Date(date_start[0], date_start[1] - 1, date_start[2]); // milliseconds
		let date_end = value.split('-');
		date_end = new Date(date_end[0], date_end[1] - 1, date_end[2]); // milliseconds
		let diff = (date_end - date_start)/(1000*60*60*24);
		if (diff > 30) {
			alert (Joomla.Text._('COM_THINGY_JS_ERROR_DATES_TOO_FAR_APART'));
			return false;
		}
		return true;
	});
	... more validation rules ...
});

You could probably improve on this. Make the date regex a global constant? Make the allowed gap configurable?

Parent Links[edit]

Back to J4.x:Tips and Tricks for Joomla 4 Developers