Blog Sections Open
AJAX Forms in Evolution CMS 3 with Routing, Validation, Request, and Response
A practical guide post that turns an Evo 3 Telegram note into a reusable AJAX form pattern instead of leaving it as scattered gist material.
One of the strongest developer-facing improvements in Evolution CMS 3 was the ability to build cleaner request flows instead of forcing every interactive feature through older snippet habits. AJAX forms are a good example. Once routing, validation, request handling, and response helpers are available, form code becomes easier to reason about and much easier to maintain.
The main gain is not that an AJAX form suddenly becomes possible. Evo projects could already do that. The real gain is structure: define a route, validate input predictably, return a clear response, and keep the form logic in a place developers can actually maintain.
Why this approach matters
- it replaces older ad-hoc AJAX patterns like
index-ajax, plugin routing hacks, or standalone PHP files - it keeps validation, request data, and response generation inside a controller-oriented flow
- it makes Evo 3 forms easier to test, extend, and reuse
Minimal route setup
<?php
use Illuminate\Support\Facades\Route;
use EvolutionCMS\Main\Controllers\FormController;
Route::post('ajax_request', [FormController::class, 'form']);
Route::get('foo', function () {
return 'Hello World';
});Frontend pattern
<div id="ajaxAuthForm">
@include('partials.form')
</div>
<script type="text/javascript">
function send(form) {
fetch('ajax_request', {
method: 'post',
body: new FormData(form)
})
.then(res => res.json())
.then(res => {
document.querySelector('#ajaxAuthForm').innerHTML = res.output;
Object.keys(res.errors || {}).forEach((key) => {
document.querySelector(`[name='${key}']`).classList.add('is-invalid')
});
});
}
</script>Controller example
<?php
namespace EvolutionCMS\Main\Controllers;
use Illuminate\Http\Request;
class FormController
{
public function form(Request $request)
{
$validator = \Validator::make($request->all(), [
'name' => ['required', 'min:5'],
'email' => ['required', 'email:rfc,dns'],
]);
if (!$validator->fails()) {
$data = [
'output' => \View::make('partials.thanks', $request)->toHtml()
];
evolutionCMS()->sendmail([
'from' => 'info@example.com',
'to' => 'team@example.com',
'subject' => 'test mail from evo 3.0',
'body' => \View::make('partials.report', $request)->toHtml()
]);
} else {
$data = [
'output' => \View::make('partials.form', $request)->withErrors($validator)->toHtml(),
'errors' => $validator->errors(),
];
}
return \Response::json($data);
}
}This is the part that really changed the developer experience. Instead of tying form submission to a snippet call hidden inside a document, you can route the request explicitly, validate it with Laravel-style rules, and return HTML or JSON in a controlled way.
Source: Telegram post and the original gist example. Related docs: Routing, Validation, Request, Response.
Localization in Evolution CMS 3 with Laravel-Style Translations
A practical guide to Laravel-style localization in Evolution CMS 3, including .htaccess routing, locale config, and translation namespaces.
Adding Lazy-Loading Image Classes to TinyMCE in Evolution CMS
A small TinyMCE customization that adds a lazy-loading class option directly to the image dialog in Evolution CMS.