Dual-use Conditional Laravel Controller Methods for Inertia + Vue
Dual-use Controllers in Laravel Dual-use controllers in Laravel serve a dual purpose: they return/render an Inertia/Vue page when accessed normally and JSON…
In Laravel applications using Inertia.js and Vue.js, there might be scenarios where you need to submit a form to a new window.
Standard Inertia.js forms, being AJAX-based, don't natively support the target="_blank" attribute, which you would use in plain HTML forms to achieve this behavior.
Browsers typically allow new windows to be opened only as a direct result of a user action, like a click, so you can't just programmatically open a new window as a workaround.
The solution is to dynamically create a standard HTML form with the target="_blank" attribute, populate it with the data from the Inertia form and submit it. Note that this is converting boolean values to "1" or "0", because otherwise you would end up with strings "true" and "false" that will fail Laravel's validation rules for boolean values.
function submitFormInNewWindow(form, actionUrl, csrfToken) {
// Create a new FormData object
const formData = new FormData();
// Append CSRF token to the form data
formData.append('_token', csrfToken);
// Retrieve form data as an object
const formObject = form.data();
// Append each form data entry to the FormData object, converting boolean values to "1" or "0"
Object.entries(formObject).forEach(([key, value]) => {
const formattedValue = typeof value === 'boolean' ? (value ? '1' : '0') : value;
formData.append(key, formattedValue);
});
// Create a new form element
const formElement = document.createElement('form');
// Set form action, method, and target
formElement.action = actionUrl;
formElement.method = 'post';
formElement.target = '_blank';
// Append each FormData entry as a hidden input element to the form
formData.forEach((value, key) => {
const inputElement = document.createElement('input');
inputElement.type = 'hidden';
inputElement.name = key;
inputElement.value = value;
formElement.appendChild(inputElement);
});
// Append the form to the document body, submit it, and then remove it
document.body.appendChild(formElement);
formElement.submit();
document.body.removeChild(formElement);
}
Give Vroni a GitHub issue, bug report, spec, or rough idea. It reads the repo, plans the change, writes code, runs checks, and works toward a review-ready pull request.
Take a look at vroni.com