FormValidation errors not displaying correctly in Tailwind version
Hi,
I’m using Metronic Tailwind version and I’m having issues with FormValidation error messages. The validation itself is working (fields are marked invalid), but the error messages are not being displayed correctly, especially for the Toggle Password
field.
Any guidance or example specific to Tailwind + FormValidation would be really helpful.
Thanks in advance!
Replies (1)
Hi
The issue is related to the DOM structure of Toggle Password fields and how FormValidation handles error message placement. Here's the specific solution:
The Toggle Password component in Metronic Tailwind has a specific DOM structure:
<pre> <div class="kt-input" data-kt-toggle-password="true"> <input type="password" name="password" /> <div class="kt-btn kt-btn-icon" data-kt-toggle-password-trigger="true"> <!-- toggle icons --> </div> </div> </pre>You need to customize the FormValidation error message placement for Toggle Password fields. Here's the solution:
<pre> // Initialize FormValidation with custom error handling for Toggle Password const fv = FormValidation.formValidation(form, { fields: { password: { validators: { notEmpty: { message: 'Password is required' }, stringLength: { min: 8, message: 'Password must be at least 8 characters long' } } } }, plugins: { trigger: new FormValidation.plugins.Trigger(), submitButton: new FormValidation.plugins.SubmitButton(), defaultSubmit: new FormValidation.plugins.DefaultSubmit(), icon: new FormValidation.plugins.Icon({ valid: 'fa fa-check', invalid: 'fa fa-times', validating: 'fa fa-refresh' }) } }); // Custom error handling for Toggle Password fields fv.on('core.field.invalid', function(e) { const element = e.element; const message = e.result.message; // Check if this is a Toggle Password field const togglePasswordContainer = element.closest('[data-kt-toggle-password="true"]'); if (togglePasswordContainer) { // Remove existing error message const existingError = togglePasswordContainer.querySelector('.fv-error-message'); if (existingError) { existingError.remove(); } // Add error styling to the container togglePasswordContainer.classList.remove('border-green-500', 'focus:border-green-500', 'focus:ring-green-500'); togglePasswordContainer.classList.add('border-red-500', 'focus:border-red-500', 'focus:ring-red-500'); // Create error message element const errorElement = document.createElement('div'); errorElement.className = 'fv-error-message text-red-600 text-sm mt-1 flex items-center'; errorElement.innerHTML = ` <svg class="w-4 h-4 mr-1 flex-shrink-0" fill="currentColor" viewBox="0 0 20 20"> <path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z" clip-rule="evenodd" /> </svg> ${message} `; // Insert error message after the Toggle Password container togglePasswordContainer.parentNode.insertBefore(errorElement, togglePasswordContainer.nextSibling); } else { // Standard error handling for regular fields element.classList.remove('border-green-500', 'focus:border-green-500', 'focus:ring-green-500'); element.classList.add('border-red-500', 'focus:border-red-500', 'focus:ring-red-500'); const existingError = element.parentNode.querySelector('.fv-error-message'); if (existingError) { existingError.remove(); } const errorElement = document.createElement('div'); errorElement.className = 'fv-error-message text-red-600 text-sm mt-1 flex items-center'; errorElement.innerHTML = ` <svg class="w-4 h-4 mr-1 flex-shrink-0" fill="currentColor" viewBox="0 0 20 20"> <path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z" clip-rule="evenodd" /> </svg> ${message} `; element.parentNode.appendChild(errorElement); } }); // Handle valid fields fv.on('core.field.valid', function(e) { const element = e.element; const togglePasswordContainer = element.closest('[data-kt-toggle-password="true"]'); if (togglePasswordContainer) { // Remove error styling from container togglePasswordContainer.classList.remove('border-red-500', 'focus:border-red-500', 'focus:ring-red-500'); togglePasswordContainer.classList.add('border-green-500', 'focus:border-green-500', 'focus:ring-green-500'); // Remove error message const errorElement = togglePasswordContainer.parentNode.querySelector('.fv-error-message'); if (errorElement) { errorElement.remove(); } } else { // Standard valid field handling element.classList.remove('border-red-500', 'focus:border-red-500', 'focus:ring-red-500'); element.classList.add('border-green-500', 'focus:border-green-500', 'focus:ring-green-500'); const errorElement = element.parentNode.querySelector('.fv-error-message'); if (errorElement) { errorElement.remove(); } } }); </pre>If this solution doesn't resolve your issue, please share your specific HTML structure and JavaScript code so I can provide a better solution.