If you have a form separated into a few tabs with jQuery UI Tabs, then default Laravel validation will redirect you back to the first tab, even if the error was on the third tab. How to override it and set the correct tab proactively?
It's pretty simple, actually.
Step 1. Load Tabs with Active Tab Variable
Wherever you load your tabs in your JS code in Blade, add an option and a Laravel variable:
$( "#tabs" ).tabs({ active: {{ $active_tab ?? '0' }} });
If the variable is not set, it will default to first tab (indexed as 0), so pretty safe to add this code snippet.
Step 2. Setting Active Tab in create() Method
Now, we need to set this variable somehow, right? Let's say we're working with create() -> store() methods in Controller, and we're redirected back to create() with a usual Laravel validation, like this one:
public function store(Request $request)
{
$request->validate([
'postcode_from' => 'required',
'postcode_to' => 'required',
]);
// ...
}
So, now we're back in create() method and somehow we need to go through errors (there can be many of them) and calculate the active tab from them.
All errors are actually saved in Laravel session, so to get them we can just do session('errors'). But the content is not a simple array, it's a MessageBag object so we need to use its specific functions, like $errors->has('field_name').
Next, we need to manually specify which field belongs to which tab. So we're creating that array of arrays. So, here's the full function to detect active tab:
$active_tab = 0;
$errors = session('errors');
if ($errors) {
$fields_tabs = [
['name', 'email'], // Tab 1
['password', 'confirm_password'], // Tab 2
['avatar', 'bio'], // Tab 3
];
foreach ($fields_tabs as $tab => $fields) {
foreach ($fields as $field) {
if ($errors->has($field)) {
$active_tab = $tab;
break;
}
}
}
}
As you can see, we're taking $tab as array index (starts with 0, as tab numeration, too), and we're doing a break; on the first error we've found.
Final thing we need to do is to pass that $active_tab variable into our Blade view:
return view('order_form', compact('active_tab'));
That's it, hope it was helpful!
No comments or questions yet...