Here is the scenario.
A user fills out a form. He forgets some required info. My validation code indicates to the user the missing field is required. He fills out the form fully and submits. Presto it works.
Now, the user manually deletes the required field and hits submit again. Presto it works (IT SHOUDLNT). How can I get my validation to work a second time around to prevent empty fields from being submitted? Here is my code. It only works on 1 iteration of a form submit. All subsequent submits ignore my validation.
Thank you…
//Validation
$('#CommentsForm').validate({
rules: {
Author: "required",
Message: "required"
},
messages: {
Author: "Author is required.",
Message: "Comment is required."
},
errorContainer: "#CommentsErrorBox",
errorLabelContainer: "#CommentsErrorBox ul",
wrapper: "li"
});
//User Clicked Submit Button
$('#CommentsForm').live('submit', function (e) {
e.preventDefault(); //Prevent Browser from getting new url
//Create JSON object
var jsonCommentData = {
ID: $('#HiddenID').val(),
Author: $('#Author').val(),
Message: $('#Message').val()
}
//Add the comment.
$.ajax({
url: '/Home/_CommentsAdd',
type: 'POST',
data: JSON.stringify(jsonCommentData),
dataType: 'html',
contentType: 'application/json',
//The request was a success. Repopulate the div with new result set.
success: function (data) {
$('#AjaxComments').html(data);
$('abbr.timeago').timeago(); //update the timestamp with timeago
//Change colors of message.
if ($('#CommentStatus').html() == "Your Comment Has Been Added!") {
$('#CommentStatus').css('color', 'GREEN');
}
},
error: function (data) {
alert('Fail');
}
});
});
Here is my Partial view: _Comments
@model DH.ViewModels.CommentsViewModel
<div id="AjaxComments">
@{
<input type="hidden" id="HiddenPageNumber" value="@Model.PageNumber.ToString()" />
<input type="hidden" id="HiddenPageCount" value="@Model.PageCount.ToString()" />
//No Comments Yet
if (Model.CommentStatus.Length > 0)
{
<div id="CommentStatus">@Model.CommentStatus</div>
}
foreach (var item in Model.Comment)
{
<div class="CommentContainer">
<div class="RateComment">
<img src="/content/images/icons/Thumbs-Up-16x16.png" alt="Thumbs Up" title="Uprate Comment" style="margin-top: 10px;" />
<div class="CommentRating">8</div>
<img src="/content/images/icons/Thumbs-Down-16x16.png" alt="Thumbs Down" title="Downrate Comment" style="margin-top: 5px;" />
</div>
<div class="CommentHeader">
<div class="CommentAuthor">@item.Author</div>
<div class="MessageDate">
<img src="/content/images/icons/Clock-16x16.png" width="16" height="16" alt="Comment Time" style="vertical-align: middle; padding-bottom: 2px;" />
<abbr class="timeago" title="@item.MessageDate" style="border-bottom-width: 0;">@item.MessageDate</abbr>
</div>
</div>
<div class="CommentMessage">@item.Message</div>
<div style="clear: both;"></div>
</div>
}
}
<div id="Pagination">
@{
//Setting up Increments of 10 Pagination links
int StartPage;
int EndPage;
int PageNumber = Model.PageNumber;
int PageCount = Model.PageCount;
if (PageCount < 10) {
StartPage = 1;
EndPage = PageCount;
}
else {
if (PageNumber < 10) {
StartPage = 1;
EndPage = 10;
}
else {
StartPage = PageNumber - 5;
EndPage = PageNumber + 4;
if (EndPage > PageCount) {
EndPage = PageCount;
StartPage = EndPage - 9;
}
}
}
//Display "Page of" if there are comments.
if (@Model.PageCount > 0)
{
<div id="PageOf">Page @Model.PageNumber of @Model.PageCount</div>
}
//Set up First and Prev arrow links
if (Model.PageNumber > 1) {
<a class="PaginationLink" title="Prev" href="">< Prev</a>
}
//Loop through and create the page #'s.
for (var PageCounter = StartPage; PageCounter <= EndPage; PageCounter++) {
//Display the Page # in a Black Box
if (PageCounter == PageNumber) {
<span class="CurrentPage">@PageNumber</span>
}
//Create the Page # Links.
else {
<a class="PaginationLink" title="@PageCounter" href="">@PageCounter</a>
}
}
//Set up Next and Last arrow links
if (Model.PageNumber < Model.PageCount) {
<a class="PaginationLink" title="Next" href="">Next ></a>
}
}
</div>
<div id="CommentsFormContainer">
<form id="CommentsForm" action="">
<div id="CommentsErrorBox"><ul></ul></div>
<fieldset id="CommentsFormFieldset">
<legend id="CommentsFormLegend" align="center">Add a Comment</legend>
<label for="Author" class="LabelAuthorMessage">Author: </label><input type="text" id="Author" name="Author" size="30" class="CommentInputs" />
<label for="Message" class="LabelAuthorMessage">Comment: </label><textarea id="Message" name="Message" cols="35" rows="5" class="CommentInputs"></textarea>
<input type="text" id="CharCount" value="0" readonly="readonly" />
<label for="CharCount" id="LabelCharCount">* Max 200 Characters</label>
<input type="submit" id="SubmitComment" value="Submit" name="SubmitComment" style="float: left; margin-left: 50px;" />
</fieldset>
</form>
</div>
Your problem is totally with your implementation.
The following occurs when the page loads which makes your form work sucessfully on the first submit…
Then, because you’ve enclosed it again within a submit handler, it’s reinitialized here…
… which breaks it for the next submit.
All you need to do is initialize it once (including all the options) and not inside a submit handler…
Refer to the source code of these official demos.
EDIT:
Again, you do not need a submit handler as it’s interfering with your form submission.
In other words, your validation is working fine but when you hit “submit”, your external submit handler function takes over completely so it’s no wonder that validation then starts failing.
As I mentioned in my original comments, the Validation plugin has a submit handler built in to handle everything including your ajax.
Remove all this completely…
Then inside your
validate()function, you’d simply add a submit handler as per the plugin documentation listed as the second option…