When using the AJAX framework, you have the option to specify the extras suffix which includes additional StyleSheet and JavaScript files. These features are useful when working with AJAX requests in front-end CMS pages.
{% framework extras %}
The first feature you should notice is a loading indicator that is displayed on the top of the page when an AJAX request runs. The indicator hooks in to global events used by the AJAX framework.
When an AJAX request starts the ajaxPromise
event is fired that displays the indicator and puts the mouse cursor in a loading state. The ajaxFail
and ajaxDone
events are used to detect when the request finishes, where the indicator is hidden again.
You may specify the data-request-validate
attribute on a form to enable validation features.
<form
data-request="onSubmit"
data-request-validate>
<!-- ... -->
</form>
In the server side AJAX handler you may throw a validation exception using the ValidationException
class to make a field invalid, where the first argument is an array. The array should use field names for the keys and the error messages for the values.
function onSubmit()
{
throw new ValidationException(['name' => 'You must give a name!']);
}
Note: You can also pass an instance of the validation service as the first argument of the exception.
Inside the form, you may display the first error message by using the data-validate-error
attribute on a container element. The content inside the container will be set to the error message and the element will be made visible.
<div data-validate-error></div>
To display multiple error messages, include an element with the data-message
attribute. In this example the paragraph tag will be duplicated and set with content for each message that exists.
<div class="alert alert-danger" data-validate-error>
<p data-message></p>
</div>
To add custom classes on AJAX invalidation, hook into the ajaxInvalidField
and ajaxPromise
JS events.
$(window).on('ajaxInvalidField', function(event, fieldElement, fieldName, errorMsg, isFirst) {
$(fieldElement).closest('.form-group').addClass('has-error');
});
$(document).on('ajaxPromise', '[data-request]', function() {
$(this).closest('form').find('.form-group.has-error').removeClass('has-error');
});
Alternatively, you can show validation messages for individual fields by defining an element that uses the data-validate-for
attribute, passing the field name as the value.
<!-- Input field -->
<input name="phone" />
<!-- Validation message for the field -->
<div data-validate-for="phone"></div>
If the element is left empty, it will be populated with the validation text from the server. Otherwise you can specify any text you like and it will be displayed instead.
<div data-validate-for="phone">
Oops.. phone number is invalid!
</div>
When any element contains the data-attach-loading
attribute, the CSS class oc-loading
will be added to it during the AJAX request. This class will spawn a loading spinner on button and anchor elements using the :after
CSS selector.
<form data-request="onSubmit">
<button data-attach-loading>
Submit
</button>
</form>
<a
href="#"
data-request="onDoSomething"
data-attach-loading>
Do something
</a>
Specify the data-request-flash
attribute on a form to enable the use of flash messages on successful AJAX requests.
<form
data-request="onSuccess"
data-request-flash>
<!-- ... -->
</form>
Combined with use of the Flash
facade in the event handler, a flash message will appear after the request finishes.
function onSuccess()
{
Flash::success('You did it!');
}
To remain consistent with AJAX based flash messages, you can render a standard flash message when the page loads by placing this code in your page or layout.
{% flash %}
<p
data-control="flash-message"
class="flash-message fade {{ type }}"
data-interval="5">
{{ message }}
</p>
{% endflash %}
Below is a complete example of form validation. It calls the onDoSomething
event handler that triggers a loading submit button, performs validation on the form fields, then displays a successful flash message.
<form
data-request="onDoSomething"
data-request-validate
data-request-flash>
<div>
<input name="name" />
<span data-validate-for="name"></span>
</div>
<div>
<input name="email" />
<span data-validate-for="email"></span>
</div>
<button data-attach-loading>
Submit
</button>
<div class="alert alert-danger" data-validate-error>
<p data-message></p>
</div>
</form>
The AJAX event handler looks at the POST data sent by the client and applies some rules to the validator. If the validation fails, a ValidationException
is thrown, otherwise a Flash::success
message is returned.
function onDoSomething()
{
$data = post();
$rules = [
'name' => 'required',
'email' => 'required|email',
];
$validation = Validator::make($data, $rules);
if ($validation->fails()) {
throw new ValidationException($validation);
}
Flash::success('Jobs done!');
}