16

having a problem with browser form validation using .preventDefault()

Is there a way to let browser check validation of required inputs, but stops submit?

Is there any flags I can use to get if form is valid?

Thanks

update: using both backbone and jquery

events: {
    "click #commentFormSubmit": "commentFormSubmit",
},
commentFormSubmit: function(el){
    el.preventDefault();
    var $el = $(el.target).parent();

    // this.$el.find('button').prop('disabled', true).addClass('disabled');
    var commentData = {};
    commentData.name = this.$el.find('input[name=comment_name]').val();
    commentData.country = this.$el.find('input[name=comment_country]').val();
    commentData.email = this.$el.find('input[name=comment_email]').val();
    commentData.comment = this.$el.find('textarea[name=comment_text]').val();
    commentData.grade = this.$el.find('.commnt_grade:checked').val();
    console.log('dd')
    this.model.onSubmitComment(commentData);
},

and the form:

    <form action="" class="" method="post">
        <span>
            <input type="text" name="comment_name" class="comment_input" placeholder="{{ 'your name'|_ }}" required>
            <input type="text" name="comment_country" class="comment_input" placeholder="{{ 'country'|_ }}">
            <input type="text" name="comment_email" class="comment_input" placeholder="{{ 'your email'|_ }}" required>
        </span>

        <textarea name="comment_text" id="comment_text" cols="30" rows="10" placeholder="{{ 'your comment'|_ }}" required></textarea>
        <span class="grades">

            <input type="radio" name="commnt_grade" class="commnt_grade" id="grade_1" value="1">
            <label for="grade_1" class="selectGrades" data-eq="1"></label>

            <input type="radio" name="commnt_grade" class="commnt_grade" id="grade_2" value="2">
            <label for="grade_2" class="selectGrades" data-eq="2"></label>

            <input type="radio" name="commnt_grade" class="commnt_grade" id="grade_3" value="3">
            <label for="grade_3" class="selectGrades" data-eq="3"></label>

            <input type="radio" name="commnt_grade" class="commnt_grade" id="grade_4" value="4">
            <label for="grade_4" class="selectGrades" data-eq="4"></label>

            <input type="radio" name="commnt_grade" class="commnt_grade" id="grade_5" value="5">
            <label for="grade_5" class="selectGrades" data-eq="5"></label>
        </span>
        <button type="submit" id="commentFormSubmit">{{ 'submit'|_ }}</button>

    </form>
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
aleXela
  • 1,270
  • 2
  • 21
  • 34

4 Answers4

18

If you want to validate without submitting, you can get the browser to check the validity of the form by calling checkValidity on it, and to report the validity by calling reportValidity. (On browsers that support HTML validation.)

Calling both checks and then reports, without submitting:

yourFormElement.checkValidity();
yourFormElement.reportValidity();

Example:

$("input[type=button]").on("click", function() {
  var yourFormElement = $("form")[0];
  yourFormElement.checkValidity();
  yourFormElement.reportValidity();
});
<form>
<input type="text" required>
<br><input type="text" required>
<br><input type="button" value="Click to check">
</form>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

You can also do it at the individual element level:

yourInputElement.checkValidity();
yourInputElement.reportValidity();

Example:

$("input[type=button]").on("click", function() {
  var yourInputElement = $("#second")[0];
  yourInputElement.checkValidity();
  yourInputElement.reportValidity();
});
<form>
<input id="first" type="text" required>
<br><input id="second" type="text" required>
<br><input type="button" value="Click to check second field only">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Since you've mentioned you're using jQuery, I'll just emphasize that these are methods of the DOM element, not the jQuery object. So for instance, if your form has an id and you look it up like this:

var $myForm = $("#the-form");

then you'd use

$myForm[0].checkValidity();
$myForm[0].reportValidity();

not

$myForm.checkValidity();  // Wrong
$myForm.reportValidity(); // Wrong

Or you could give yourself a little plugin for it:

jQuery.fn.checkValidity = function() {
    var el = this[0];
    return el && el.checkValidity();
};
jQuery.fn.reportValidity = function() {
    var el = this[0];
    return el && el.reportValidity();
};

That's in keeping with jQuery's various other "getters" in that it only looks at the first element in the set inside the jQuery object.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • what if i have 5 fields? – aleXela Jun 05 '17 at 16:08
  • @aleXela: Call it on the form. Oddly enough, I'd just realized I hadn't said that and was editing the above as you commented; hit refresh. :-) – T.J. Crowder Jun 05 '17 at 16:09
  • and there no simple way to do it?? wired. – aleXela Jun 05 '17 at 16:13
  • @aleXela: What's not simple about two function calls on the form element? – T.J. Crowder Jun 05 '17 at 16:16
  • i tried to use checkValidity() for some reason its not working. i think i'm referencing wrong object. and i need to run this code for all input objects. – aleXela Jun 05 '17 at 16:21
  • @aleXela: Working examples above. Remember, checking and reporting are different things. Also remember these are methods on the DOM element; if you're looking up the element with jQuery, do as the examples above do and access the DOM element inside the jQuery object via `[0]`. – T.J. Crowder Jun 05 '17 at 16:23
  • $el.find('input')[0].checkValidity() works. and need to run each for this. that's not simple here, is that browser has this feature (validation) i only want to run my models' method after validation give OK. – aleXela Jun 05 '17 at 16:27
  • @aleXela: Again: If you want to check all of the inputs in a form, call the methods on the form. – T.J. Crowder Jun 05 '17 at 16:28
  • @T.J.Crowder please mention that `checkValidity()` and `reportValidity()` are mutual exclusive. Both invoke validation on the form elements (``) while only `reportValidity()` triggers the browser native visual reporting. `checkValidity()` is used when you want to provide your own visual reporting. You should **never** use these two methods together. Both methods returns a boolean. – dotnetCarpenter Mar 28 '21 at 12:06
7

While @TJ provided a good solution in his answer, the alternative method is to listen for the submit event on the actual form while using event.preventDefault(). This will allow the form validation to trigger but prevent the form submit.

holmberd
  • 2,393
  • 26
  • 30
0

Thanks for @T.J. Crowder for the direction. as for me it's a fix, not a solution.

commentFormSubmit: function(el){
    var $el = $(el.target).parent();    
    if ($el[0].checkValidity()){
        el.preventDefault();
        // this.$el.find('button').prop('disabled', true).addClass('disabled');
        var commentData = {};
        commentData.name = this.$el.find('input[name=comment_name]').val();
        commentData.country = this.$el.find('input[name=comment_country]').val();
        commentData.email = this.$el.find('input[name=comment_email]').val();
        commentData.comment = this.$el.find('textarea[name=comment_text]').val();
        commentData.grade = this.$el.find('.commnt_grade:checked').val();
        // this.model.onSubmitComment(commentData);
    }
    else $el[0].reportValidity();
},

Again, thanks!

aleXela
  • 1,270
  • 2
  • 21
  • 34
-3

You can always rely to HTML5 form validation attributes that prevents you to submit your request while you have invalid form data:

  • disabled
  • max
  • min
  • pattern
  • required

So you do not need to prevent default behavior - use can't submit form until you have invalid data.

<form action="/action_page_post.php" method="post">
  <input type="text" name="fname" required>
  <input type="submit" value="Submit">
</form>

https://www.w3schools.com/js/js_validation.asp

VadimB
  • 5,533
  • 2
  • 34
  • 48