Tutorials
Last updated on:
Dec 9, 2024

How to create custom form validation rules in Webflow

BRIX Templates Logo
Author
BRIX Templates
How to create custom form validation rules in Webflow
Table of contents

Form validation is crucial for avoiding spam or unwanted form submissions on your website. While Webflow provides basic form functionality, there are scenarios where you need more advanced validation capabilities, such as:

  • Blocking submissions from specific countries (e.g., limiting service availability to US and Canada only)
  • Preventing spam by filtering out submissions containing specific keywords (e.g., blocking known spam phrases or competitor names)
  • Setting up domain-specific email restrictions (e.g., blocking free email providers for B2B forms)

Implementation overview

We will guide you on how to easily implement a form validation system on Webflow that supports as many validations as you need, all at a local browser level, ensuring there are no security or privacy compliance issues. The validation system works through the following sequential process:

  1. User input monitoring: The system continuously monitors form fields for user input, checking each character entered against predefined validation rules. This ensures real-time feedback without waiting for form submission.
  2. Validation processing: When input is detected, the system compares it against a list of blocked words or phrases. This process runs instantly, ensuring smooth user experience while maintaining strict validation standards.
  3. Response generation: Based on the validation results, the system either enables form submission and hides error messages, or disables the submit button and displays clear error messages, helping them understand exactly what needs to be corrected.

Step-by-step implementation of validators in Webflow forms

1. Setting up form elements

First, we need to add specific IDs to our form elements. Each element plays a crucial role in the validation process:

Open your form in the Webflow Designer

For each field you want to validate:

  1. Select the input field that needs validation (this could be any form input where you want to check for blocked words)
  2. In the right sidebar's Settings panel, add the ID brix-form-validator-1 (for your first validator)
  3. This ID connects the input field to its specific validation rules
  4. For additional validators, use incrementing numbers (e.g., brix-form-validator-2, brix-form-validator-3)
Add validation functionality to Webflow form input

Select your form's submit button:

  1. In the right sidebar's Settings panel, add the ID brix-form-validator-button
  2. This ID allows the validation script to enable/disable form submission based on validation results
Add form submission button validation on Webflow

Add a new Text element below your button:

  1. This element will display error messages when validation fails
  2. In the right sidebar's Settings panel, add the ID brix-form-validator-message
  3. In the right sidebar's Style panel, set the Display property to "None" - this ensures the message is hidden by default
  4. The validation script will handle showing and hiding this message as needed
Add form validation message on Webflow form

2. Adding the CSS classes

Add these classes to your Webflow styles. These classes control the visual feedback for users:

Create a .deactivated class for the submit button:

  1. Set opacity to 0.5
  2. Set cursor to not-allowed
  3. This class visually indicates when the submit button is disabled due to validation failures, so if you want to customize it to have any other look to match your brand guidelines, feel free to do so.
Customize form submission button validation on Webflow

Create a .show class for the message:

  1. Set display to block
  2. Style the error message appearance to match your website design style (color, font, etc.)
  3. This class will control the visibility and styling of error messages

3. Adding the validation code

Choose where to add your code based on your form's usage:

For forms on specific pages:

  1. Go to the page containing the form
  2. Click the Settings icon
  3. Select "Page Settings"
  4. Navigate to "Custom Code"
  5. Add the code in the "Before </body> tag" area
Add page custom code to add form validation functionality on Webflow

For site-wide forms:

  1. Click the Settings icon
  2. Select "Project Settings"
  3. Navigate to "Custom Code"
  4. Add the code in the "Before </body> tag" area
Add custom code to add form validation functionality on Webflow

Add the following JavaScript code:

<script>
 /** 
   * Custom form validation in Webflow
   * Validate form inputs content
   * @author BRIX Templates
   * @version 1.0.0
**/
   
   
window.onload = function() {
    const formValidators = [
        {
            id: '1',
            blockedWords: ['spam', 'test', 'unwanted'],
            errorMessage: 'Sorry, this content is not allowed.'
        },
        {
            id: '2',
            blockedWords: ['competitor1', 'competitor2'],
            errorMessage: 'Please remove competitor references.'
        }
        
    ];

    // Get error message element
    const messageElement = document.getElementById('brix-form-validator-message');
    
    // Remove any existing styles and classes
    if (messageElement) {
        messageElement.removeAttribute('style');
        messageElement.classList.remove('show');
    }

    formValidators.forEach(validator => {
        initializeValidator(validator);
    });

    function initializeValidator(validator) {
        const inputField = document.getElementById(`brix-form-validator-${validator.id}`);
        const submitButton = document.getElementById('brix-form-validator-button');

        if (!inputField || !submitButton || !messageElement) {
            return;
        }

        // Remove initial deactivated state
        submitButton.classList.remove('deactivated');

        inputField.addEventListener('input', function() {
            const inputValue = this.value.toLowerCase();
            const containsBlockedWord = validator.blockedWords.some(word => 
                inputValue.includes(word.toLowerCase())
            );

            if (containsBlockedWord) {
                // Handle error state
                submitButton.disabled = true;
                submitButton.classList.add('deactivated');
                messageElement.textContent = validator.errorMessage;
                messageElement.classList.add('show');
            } else {
                // Handle valid state
                submitButton.disabled = false;
                submitButton.classList.remove('deactivated');
                messageElement.classList.remove('show');
            }
        });
    }
}

</script>

<!-- Clonable Instructions Rich Text Custom Elements (DELETE) -->

<script>
function parseCustomSyntax(richText) {
    // Process dividers first
    const dividerPattern = /&lt;brix-divider&gt;/g;
    richText = richText.replace(dividerPattern, `<div class="divider---brix"></div>`);

    // Process headers with HTML-like syntax - handle both encoded and non-encoded versions
    const headerPattern = /(?:&lt;brix-header|<brix-header).*?(?:&lt;\/brix-header&gt;|<\/brix-header>)/gs;

    return richText.replace(headerPattern, (match) => {
        // Decode HTML entities if present
        const decodedMatch = match.replace(/&lt;/g, '<').replace(/&gt;/g, '>');

        // Use DOMParser to parse the custom tag
        const parser = new DOMParser();
        const doc = parser.parseFromString(decodedMatch, 'text/html');
        const brixHeaderElement = doc.querySelector('brix-header');

        if (!brixHeaderElement) return match; // Return original if parsing fails

        // Extract attributes safely
        const params = {
            id: brixHeaderElement.getAttribute('id') || '1',
            title: brixHeaderElement.getAttribute('title') || '',
            paragraph: brixHeaderElement.innerHTML.trim() || ''
        };

        // If id contains 'id', remove it
        if (params.id.includes('id')) {
            params.id = params.id.replace('id', '');
        }

        // Replace code tags with spans for safety
        let processedParagraph = params.paragraph
            .replace(/\[CODE\]/g, '<code class="code-tag---brix">')
            .replace(/\[\/CODE\]/g, '</code>')
            .replace(/\[BODY\]/g, '&lt;/body&gt;');

        // Generate HTML structure
        return `
            <div class="step-header---brix">
                <div class="step-number---brix">
                    <div>${params.id}</div>
                </div>
                <div>
                    <div class="heading-size-4---brix">${params.title}</div>
                    <div>${processedParagraph}</div>
                </div>
            </div>
        `;
    });
}

function processRichText() {
    // Select the rich text elements
    const richTextElements = document.querySelectorAll('.rich-text---instructions.w-richtext');

    richTextElements.forEach(element => {
        // Get the HTML content
        let content = element.innerHTML;

        // Process the content
        const processedContent = parseCustomSyntax(content);

        // Only update if changes were made
        if (content !== processedContent) {
            element.innerHTML = processedContent;
        }
    });
}

// Function to initialize the processing
function initRichTextProcessor() {
    // Process immediately
    processRichText();

    // Set up a mutation observer to handle dynamic content changes
    const observer = new MutationObserver((mutations) => {
        mutations.forEach((mutation) => {
            if (mutation.type === 'childList' || mutation.type === 'characterData') {
                processRichText();
            }
        });
    });

    // Observe all rich text elements
    document.querySelectorAll('.rich-text---instructions.w-richtext').forEach(element => {
        observer.observe(element, {
            childList: true,
            subtree: true,
            characterData: true
        });
    });
}

// Execute when DOM is fully loaded
document.addEventListener('DOMContentLoaded', initRichTextProcessor);

// Execute when Webflow's load event occurs (for editor preview)
window.Webflow && window.Webflow.push(initRichTextProcessor);

// Make function available globally for manual triggering if needed
window.processRichText = processRichText;

</script>

4. Customizing the form validation logic

To customize the validation:

  1. Modify the blockedWords array carefully. Choose specific phrases rather than common words to avoid false positives. For example, use complete spam phrases  instead of generic terms.
  2. Create clear, actionable error messages that help users understand the issue. For example, instead of "Invalid input," use "This field contains blocked content. Please remove any promotional or spam-related text."
  3. Add new validators by copying the validator object structure and incrementing the ID number. Make sure to add a comma after the closing curly brace. Here's an example:
const formValidators = [
    {
        id: '1',
        blockedWords: ['spam', 'test'],
        errorMessage: 'First validator message'
    }, // <- Note the comma here
    {
        id: '2',
        blockedWords: ['competitor1'],
        errorMessage: 'Second validator message'
    }, // <- Note the comma here
    {
        id: '3',
        blockedWords: ['newword'],
        errorMessage: 'Third validator message'
    } // <- No comma after the last validator
];

Best practices and troubleshooting

Testing and verification

After adding the code:

  1. Publish your Webflow site
  2. Open your form in a real browser
  3. Test each validator with both valid and invalid content
  4. Verify that error messages appear correctly
  5. Check that the submit button properly enables/disables

Common issues:

  • Validation not working? This usually means the IDs don't match exactly. Double-check that your input field IDs follow the pattern brix-form-validator-1, brix-form-validator-2, etc., and that they correspond to the id values in your validators array.
  • Error message not showing? Verify that your message element has the exact ID brix-form-validator-message and that the .show class is properly defined in your styles.
  • Submit button not responding? Ensure your button has the exact ID brix-form-validator-button and check your browser's console (F12) for any JavaScript errors.
  • Multiple validators conflicting? Make sure each validator has a unique ID number and that the corresponding form fields use matching IDs.

Using our form validation Webflow cloneable

For those looking for an even simpler solution, we offer a free form validator Webflow cloneable that includes this exact functionality.

The cloneable version comes pre-configured and ready to use - you'll just need to customize the validation rules for your specific needs, and then copy / paste it in your Webflow project (keep in mind it will have the design style from BRIX Templates, so you may want to update it 👀).

Form Validator Webflow Template Cloneable

You can find our cloneable in the Made in Webflow Community. Just go to the link, and click the 'Clone in Webflow' button.

Conclusion

This implementation provides a solid foundation for custom form validation in Webflow, helping you maintain data quality and strongly reduce unwanted form submissions. The flexible structure allows for easy expansion and customization to meet your specific needs.

While this implementation works great for keyword-based validation, you might occasionally need more sophisticated solutions. Some examples of advanced implementations could include:

  • AI-powered content filtering for more natural language understanding
  • Geographic-based validation rules for regional service restrictions
  • Custom validation logic for complex business rules
  • Multi-step validation workflows

If you find yourself needing any of these more advanced solutions, the team at BRIX Templates would be happy to help you implement them.

Whether you choose to implement the code yourself or use our cloneable, you now have the tools to create more sophisticated form validation in Webflow. Remember to test thoroughly and keep your validation rules updated to maintain the best possible user experience.

BRIX Templates Logo
About BRIX Templates

At BRIX Templates we craft beautiful, modern and easy to use Webflow templates & UI Kits.

Explore our Webflow templates
Join the conversation
Join our monthly Webflow email newsletter!

Receive one monthly email newsletter with the best articles, resources, tutorials, and free cloneables from BRIX Templates!

Webflow Newsletter
Thanks for joining our Webflow email newsletter
Oops! Something went wrong while submitting the form.
BRIX Templates - Email Newsletter with Webflow ResourcesBRIX Templates - Email NewsletterBRIX Templates - Webflow Email Newsletter
How to pre-fill Webflow forms with URL parameters

How to pre-fill Webflow forms with URL parameters

Step-by-step guide to implementing URL parameter form pre-filling in Webflow using our ready-to-use script. No coding required.

Dec 17, 2024
How to add custom security headers to your Webflow site

How to add custom security headers to your Webflow site

Learn how to strengthen your Webflow site's security by adding custom headers. A complete guide covering implementation through Cloudflare.

Dec 17, 2024
How to add real-time search to your Webflow CMS collections

How to add real-time search to your Webflow CMS collections

Step-by-step guide on implementing dynamic search functionality in your Webflow CMS — Show instant search results without page reloads.

Dec 13, 2024