Question

I've written a custom form validation script, but for some reason, wrapping input[type=text] elements in <div class="inputWrapper" /> stops me from preventing input[type=submit]'s default setting.

Here's the relevant code:

$("input[type=text]").wrap("<div class=\"inputWrapper\" />");

Is breaking:

$("input[type=submit]").click(function(event) {
    event.preventDefault();
});

Why is this happening? If you need a more full script, let me know, and I'll just post the whole thing.

Alright, so for some reason, disabling that line of code allows .preventDefault on the input[type=submit] to work, but if I just use

// wrap inputs

    $("input[type=text]").wrap("<div class=\"inputWrapper\" />");
    // validate on form submit
    $("input[type=submit]").click(function(event) {
        event.preventDefault();
    });

It works fine. So here's the full script, what could cause this weirdness?

    $(document).ready(function() {
        // wrap inputs
        $("input[type=text]").wrap("<div class=\"inputWrapper\" />");
        $("textarea").wrap("<div class=\"inputWrapper\" />");
        // validate text inputs on un-focus
        $("input[type=text].required").blur(function() {
            if ($(this).hasClass("error")) {
                // do nothing
            } else if ($(this).val() === "") {
                $(this).addClass("error");
                $(this).parent(".inputWrapper").append("<div class=\"errorPopup\">" + $(this).attr("placeholder") + "</div>");
            }
        });
        // validate textareas on un-focus
        $("textarea.required").blur(function() {
            if ($(this).hasClass("error")) {
                // do nothing
            } else if ($(this).val() === "") {
                $(this).addClass("error");
                $(this).parent(".inputWrapper").append("<div class=\"errorPopup\">" + $(this).attr("placeholder") + "</div>");
            }
        });

        // validate on form submit
        $("input[type=submit]").click(function(event) {
            event.preventDefault();
            // check fields

            $(this).parent("form").children("input.required").each(function() {
            // check textboxes

            if ($(this + "[type=text]")) {
                if (!$(this).val()) {
                    $(this).addClass("error");
            };
            };

            // end textboxes
    // check textareas
            $(this).parent("form").children("textarea.required").each(function() {
            if (!$(this).val()) {
                    $(this).addClass("error");
                };
            });

            // end textareas
        // check checkboxes and radio buttons
        if ($(this).is(":checkbox") || $(this).is(":radio")) {
                var inputName = $(this).attr("name");
                if (!$("input[name=" + inputName + "]").is(":checked")) {
                    var inputId = $(this).attr("id");
            $("label[for=" + inputId + "]").addClass("error");
                };
            };

            // end checkboxes and radio buttons
        });

        // end fields
        // submit form
        var errorCheck = $(this).parent("form").children(".error").length > 0;
            if (errorCheck == 0) {
                $(this).parent("form").submit();
            } else {
                alert("You didn't fill out one or more fields. Please review the form.");
                window.location = "#top";
            };
        // end submit form
    });
    // clear errors 
    $("input.required").each(function() {
        // clear textboxes
            if ($(this + "[type=text]")) {
                $(this).keypress(function() {
                    $(this).removeClass("error");
                    $(this).next(".errorPopup").remove();
                });
            };
        // end textboxes
        // clear textareas
            $("textarea.required").each(function() {
                $(this).keypress(function() {
                    $(this).removeClass("error");
                    $(this).next(".errorPopup").remove();
                });
            });
        // end textareas
        // check checkboxes and radio buttons
            if ($(this).is(":checkbox") || $(this).is(":radio")) {
                var inputName = $(this).attr("name");
                var labelFor = $(this).attr("id");
                $(this).click(function() {
                    $("input[name=" + inputName + "]").each(function() {
                        var labelFor = $(this).attr("id");
                        $("label[for=" + labelFor + "]").removeClass("error");
                    });
                });
            };
        // end checkboxes and radio buttons
    });
    // end clear textbox errors
});

Alright, I was wrong about what the problem was. It's related to the line I thought it was, but it's actually having an issue finding the .error after I wrap the inputs.

Here's where the problem lies:

var errorCheck = $(this).parent("form").children(".error").length > 0;`\
Was it helpful?

Solution

var errorCheck = $(this).parent("form").children(".error").length > 0;

When you .wrap the text inputs, they are no longer children of the form. Use .find

By the way, $(this + "selector") is not valid. You probably want to use $(this).is("selector")

OTHER TIPS

You will need some sort of reference maintained with the new DOM element. This would be placing it as an initialised DOM element in a variable first (not as a string as you did) and the same for the original element, which will be placed back in to maintain the event:

var $inputWrapper = $("<div class=\"inputWrapper\" />"),
    $inputText = $("input[type=text]");
$inputText.wrap("<div class=\"inputWrapper\" />");

Then you can replace the element back in.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top