jquery validate not being honored - browser submitting form instead - javascript

I have seen #Sparky's answer and sample jsFiddle to this question, and to my mind I have the right html and javascript in place, but still the browser is submitting the form.
I have this html:
#using (Html.BeginForm("Create", "ClientWarehouseRequest", FormMethod.Post, new { #class = "form-horizontal" }))
{
<!-- many form inputs here -->
<div class="buttons-wrap">
<input type="hidden" name="SubmitButtonValue" id="SubmitButtonValue" />
<input class="k-button" type="submit" value="Post" name="SubmitButton" />
#Html.ActionLink("Cancel", "Index", controllerName: null, routeValues: null, htmlAttributes: new { #class = "k-button", style = "vertical-align: bottom;" })
<input class="k-button" type="submit" value="Save" name="SubmitButton" />
</div>
}
with this javascript:
$(document).ready(function () {
$('form').validate({
submitHandler: function (form) {
var postingWindow = $("#postingDialogWindow").data("kendoWindow");
postingWindow.title("Posting Client Request...");
postingWindow.open();
$.ajax({
url: form.action,
type: form.method,
data: $(form).serialize()
})
.success(function (result) {
if (result.success) {
window.alerts.info(result.message, true);
window.location.replace(result.redirecturl);
}
else {
window.alerts.error(result.error);
}
})
.fail(function (result) {
//window.alerts.error(result);
var result = $.parseJSON(result.responseText);
window.alerts.error(result.errorMessage);
})
.always(function (data) {
postingWindow.close();
});
return false;
},
invalidHandler: function (event, validator) {
alert('invalid');
}
});
}
Yet when I click on the of the submit buttons, the browser is submitting the form as a full postback. I need the form to submit via the $.ajax call inside the validate() function instead. What am I missing?

Related

How can I serialize a form in JavaScript asp.net

I am using some javascript to post my form but I dont want to have to submit each form field is there a way I can serlize this to an object in .net so that it will bring in all the form contents.
section Scripts {
<script>
function confirmEdit() {
swal({
title: "MIS",
text: "Case Created your Case Number is " + $("#Id").val(),
icon: "warning",
buttons: true,
dangerMode: true,
}).then((willUpdate) => {
if (willUpdate) {
$.ajax({
url: "/tests/edit/" + $("#Id").val(),
type: "POST",
data: {
Id: $("#Id").val(),
Name: $("#Name").val()
},
dataType: "html",
success: function () {
swal("Done!", "It was succesfully edited!", "success")
.then((success) => {
window.location.href = "/tests/index"
});
},
error: function (xhr, ajaxOptions, thrownError) {
swal("Error updating!", "Please try again", "error");
}
});
}
});
}
</script>
}
asp.net core will automatically bind json data using the [FromBody] attribute.
data: {
id: $("#Id").val(),
name: $("#Name").val()
},
and then in your controller
[HttpPost("/tests/edit/")]
public IActionResult Process([FromBody] MyData data){ ... }
where MyData is
public class MyData
{
public string Id {get;set;}
public string Name {get;set;}
}
section Scripts { function confirmEdit() {
swal({ title: "MIS", text: "Case Created your Case Number is " + $("#Id").val(), icon: "warning", buttons: true, dangerMode: true, }).then((willUpdate) => { if (willUpdate) {
var obj = { Id: $("#Id").val(), Name: $("#Name").val() }
$.ajax({ url: "/tests/edit/" + $("#Id").val(), type: "POST", data: JSON.Stringify(obj), dataType: "html", success: function () { swal("Done!", "It was succesfully edited!", "success") .then((success) => { window.location.href = "/tests/index" }); }, error: function (xhr, ajaxOptions, thrownError) { swal("Error updating!", "Please try again", "error"); } }); } }); } }
in c# use
public ActionResult FormPost(MyData obj)
Please refer to the following methods to submit the form data to action method:
using the serialize() method to serialize the controls within the form.
#model MVCSample.Models.OrderViewModel
<h4>OrderViewModel</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="Showsummary" asp-controller="Home" method="post" class="signup-form">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="OrderId" class="control-label"></label>
<input asp-for="OrderId" class="form-control" />
<span asp-validation-for="OrderId" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="OrderName" class="control-label"></label>
<input asp-for="OrderName" class="form-control" />
<span asp-validation-for="OrderName" class="text-danger"></span>
</div>
<div id="packages">
#for (int i = 0; i < Model.Packages.Count; i++)
{
<div class="form-group">
<label asp-for="#Model.Packages[i].Pid" class="control-label"></label>
<input asp-for="#Model.Packages[i].Pid" class="form-control" />
<span asp-validation-for="#Model.Packages[i].Pid" class="text-danger"></span>
<br />
<label asp-for="#Model.Packages[i].PackageTitle" class="control-label"></label>
<input asp-for="#Model.Packages[i].PackageTitle" class="form-control" />
<span asp-validation-for="#Model.Packages[i].PackageTitle" class="text-danger"></span>
</div>
}
</div>
</form>
</div>
</div>
<div>
<input type="button" id="summary" value="Summary" />
<div id="page_3">
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
$(function () {
$("#summary").click(function () {
console.log("calling summary");
event.preventDefault();
$.ajax({
type: "POST",
url: "/Home/Showsummary", //remember change the controller to your owns.
data: $("form.signup-form").serialize(),
success: function (data) {
console.log(data)
},
failure: function (response) {
console.log(response.responseText);
},
error: function (response) {
console.log(response.responseText);
}
});
});
});
</script>
Code the the action method:
[HttpPost]
public PartialViewResult Showsummary(OrderViewModel model)
{
try
{
//...
return PartialView("OrderSummary", model);
}
catch
{
return PartialView("OrderSummary", model);
}
}
After clicking the button, the result like this:
As we can see that, we could get the element's value in the form and even the nested entity.
Note: Only "successful controls" are serialized to the string. No submit button value is serialized since the form was not submitted using a button. For a form element's value to be included in the serialized string, the element must have a name attribute. Values from checkboxes and radio buttons (inputs of type "radio" or "checkbox") are included only if they are checked. Data from file select elements is not serialized.
Create a JavaScript object, and post it to action method.
Change the JavaScript script as below:
$(function () {
$("#summary").click(function () {
console.log("calling summary");
event.preventDefault();
//create a object to store the entered value.
var OrderViewModel = {};
//using jquery to get the entered value.
OrderViewModel.OrderId = $("input[name='OrderId']").val();
OrderViewModel.OrderName = $("input[name='OrderName']").val();
var packages = [];
//var count = $("#packages>.form-group").length; //you could use it to check the package count
$("#packages>.form-group").each(function (index, item) {
var package = {}
package.Pid = $(item).find("input[name='Packages[" + index + "].Pid']").val();
package.PackageTitle = $(item).find("input[name='Packages[" + index + "].PackageTitle']").val();
packages.push(package);
});
//add the nested entity
OrderViewModel.Packages = packages;
$.ajax({
type: "POST",
url: "/Home/Showsummary", //remember change the controller to your owns.
data: OrderViewModel,
success: function (data) {
console.log(data)
$('#page_3').html(data);
},
failure: function (response) {
console.log(response.responseText);
},
error: function (response) {
console.log(response.responseText);
}
});
});
});
By using the above code, I could also get the submit entity, you could refer to it.

Call Action Method on button click ASP.NET MVC

I am trying to get user input in button click.
When user insert number and press Check, it needs to return xml data type.
So in my controller I create function which will return a data for passing ID
[ResponseType(typeof(AKONTA))]
public IHttpActionResult GetAKONTA(string id)
{
AKONTA aKONTA = db.AKONTAS.Find(id);
if (aKONTA == null)
{
return BadRequest("Ne postoji A_KONTO pod tim rednim brojem");
}
return Ok(aKONTA);
}
And In my View I have following
<br /><br />
<form>
<div class="form-group">
<label>A_KONTO</label>
<input type="text" class="form-control" aria-describedby="AKONTO BROJ" placeholder="Unesite broj AKONOTO">
</div>
<div class="form-group">
<a asp-action="Index" class="btn btn-primary" id="aKonto" action="#Url.Action("GetAKONTA", "Akontas")">Provjeri</a>
</div>
</form>
And I want to create in btn click when user pass ID it needs to return XML data format.
SO far I create a JS function, but I don't know JavaScript and don't know the logic how to pass Controller Action Result to JS.
<script>
$(document).ready(function () {
$('#aKonto').click(function () {
document.getElementById("aKonto").onclick = function () {GetAKONTA()};;
});
});
</script>
If someone can help me I would be very thankful.
Cheers !
UPDATE
function aKontoSubmit() {
$.ajax({
type: "GET",
url: 'api/Akontas',
//data: { id: id },
dataType: "xml",
success: function (result) {
// action to do after form submit
},
error: function () {
alert("Ne postoji AKONTO pod tim rednim brojem");
}
});
}
**routeConfig**
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
namespace AkontasWebApi
{
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
}
Add Reference of Jquery, to try the ajax call method.
function aKontoSubmit() {
$.ajax({
type: "POST",
url: '/Akontas/GetAKONTA',
data: $('form').serialize(),
dataType: "json",
success: function (result) {
// action to do after form submit
},
error: function () {
alert("Error while inserting data");
}
});
}
Change you Link Code as Below
<a asp-action="Index" class="btn btn-primary" id="aKonto" onClick='return aKontoSubmit() '>Provjeri</a>
Or Else You Can try if you are using ASP.Net MVC Core Development
<form asp-action="GetAKONTA" asp-controller="Akontas" method="post">
<div class="form-group">
<label>A_KONTO</label>
<input type="text" class="form-control" aria-describedby="AKONTO BROJ" placeholder="Unesite broj AKONOTO">
</div>
<div class="form-group">
<input class="btn btn-primary" id="aKonto" type = "submit" value = "Provjeri" />
</div>
</form>
After a couple hours of debugging and searching I found that I forget to put
window.location.href = "http://localhost:57285/api/Akontas/" + $('#AkontasId').val();
This is location where should redirect if item exsist in database
And URL call need to be modified as well
URL: "/api/Akontas/GetAKONTA",
function aKontoSubmit() {
$.ajax({
type: "GET",
URL: "/api/Akontas/GetAKONTA",
data: { id: $('#AkontasId').val() },
contentType: "data/xml; charset=utf-8",
success: function (result) {
window.location.href = "http://localhost:57285/api/Akontas/" + $('#AkontasId').val();
},
error: function () {
alert("Ne postoji AKONTO pod tim rednim brojem");
}
});
}

Invisible google captcha v2 is not working properly

The following code is working fine when the form is submitted correctly with all valid data in the first attempt. If there is any server side error after submitting the form then when user resubmits the form the recaptcha does not reset.
Following is the sample code:
html-form
<script src="https://www.google.com/recaptcha/api.js"></script>
<div>
<form name="signupForm" method="POST" action="/signup">
<div class="form-group mobile-number">
<input type="tel" id="mobileNo" class="form-control" name="mobileNumber" maxlength="10"
autofocus>
<label for="mobile"> Your Mobile no. </label>
</div>
<div class="g-recaptcha"
data-sitekey="{key}"
data-callback="setResponse"
data-badge="inline"
data-size="invisible">
</div>
<input type="hidden" id="captcha-response" name="captcha-response"/>
<button id="submitButon" type="submit">Sign me up!</button>
</form>
</div>
javascript
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script>
function setResponse(response) {
document.getElementById('captcha-response').value = response;
submitForm();
}
function submitForm() {
var $form = $("form");
var data = JSON.stringify($form.serializeObject());
var myJsonObject = JSON.parse(data);
data = JSON.stringify(myJsonObject);
$.ajax({
type: "POST",
url: "dummy url",
contentType: "application/json",
xhrFields: {withCredentials: true},
data: data,
success: function (data, textStatus, request) {
// success
},
error: function (xhr, err) {
// logics here
grecaptcha.execute();
setResponse;
}
});
}
</script>
<script>
jQuery(document).ready(function () {
//homepage form
$('form[name="signupForm"]').validate({
onfocusout: function (element) {
$(element).valid();
},
rules: {
mobileNumber: {
required: true,
minlength: 10,
maxlength: 10
}
},
// Specify validation error messages
messages: {
mobileNumber: "A valid mobile number is of 10-digit",
},
//submit handler
submitHandler: function (form) {
submitForm();
}
});
});
</script>
I think the error is in ajax call but not able to figure out why the captcha is not resetting again.

How to know if Ajax Post was a success?

Current Code Example:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> ActionName(ViewModel model)
{
if (!ModelState.IsValid)
{
return PartialView(model);
}
var result = //something
if (result.Succeeded)
{
return PartialView(model);
}
AddErrors(result);
return PartialView(model);
}
Form Html
#model ViewModel
#using (Html.BeginForm("ChangePassword", "Manage", FormMethod.Post, new { #id = "Form"}))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary("", new { #class = "text-danger" })
//Controls
<div class="form-group">
<input type="submit" value="Save" data-loading-text="Loading..." class="btn btn-default" />
</div>
}
JQuery code Template:
$("#Form").on('click', ".btn", function (e) {
e.preventDefault();
$.ajax({
url: "Something/ActionName",
//datatype: "text",
data: $('#Form').serialize(),
type: "POST",
success: function (data) {
$("#Form").html(data);
},
error: function (result) {
alert(result);
}
});
});
Now how can I know if an AJAX POST was a success and at the same time also returning the Partial View? Return PartialView to reset Form controls and clear error incase there were on the last post.
We can create a Json result with a var and RenderPartialView as string value. Please see MVC Return Partial View as JSON :
if (data.Result == "Success") {
alert("Data Saved");
}
$("#Form").html(data);
However, is there an easier option I am missing?

Partial View on Submit using Ajax call

Here is my jquery code:
<script type="text/javascript">
$("#submitfileform").submit(function () {
$.ajax({
type: 'POST',
contentType: 'application/html;charset=utf-8',
dataType:'html',
success:function (result) {
$('#tablepartialview').html(result);
},
error:function (xhr, status) {
alert(status);
}
})
});
</script>
and here is html.beginform,
#using (Html.BeginForm("PropertyColumnMap", "ImportFile", FormMethod.Post, new { enctype = "multipart/form-data", #class = "form single-col",id="submitfileform"}))
{
<input type="file" name="uploadFile" id="uploadFile" value=""/>
<select id="assetlist" name="assetlist">
<option>...</option></select>
<input class="btn btn-primary" type="submit" value="Submit" id="submitfile"/>
}
<div id="tablepartialview">
</div>
What happens is, on submit, I get the partial view of the same page 'Index' in div-'tablepartialview', instead of another page 'PropertyColumnMap', which I want. After the ajax call is done,it redirects to action 'PropertyColumnMap', and then I get the view for PropertyColumnMap.
public ActionResult PropertyColumnMap(FormCollection f, HttpPostedFileBase uploadFile)
{
String fileid = Import(uploadFile);
var excel = new ExcelQueryFactory(Session[fileid].ToString());
excel.DatabaseEngine = DatabaseEngine.Ace;
var workSheetName = excel.GetWorksheetNames().Last();
var assetname = f["assetlist"].ToString();
Mapping(assetname, workSheetName, fileid);
return PartialView("PropertyColumnMap");
}
If its possible please include following js to your project
http://malsup.github.com/jquery.form.js
Then you can use
$("#submitfileform").ajaxSubmit({
type: 'POST',
success:function (result) {
$('#tablepartialview').html(result);
},
error:function (xhr, status) {
alert(status);
}
});
As you are using MVC, just switch your Html.BeginForm to use the Ajaxified Ajax.BeginForm instead.
It allows for many options including specifying the id of the target element to update (e.g. 'tablepartialview').
e.g.
#using (Ajax.BeginForm("PropertyColumnMap", "ImportFile", new AjaxOptions(){ HttpMethod = "POST", UpdateTargetId = "tablepartialview"}, new { enctype = "multipart/form-data", #class = "form single-col", id = "submitfileform" }))
{
<input type="file" name="uploadFile" id="uploadFile" value="" />
<select id="assetlist" name="assetlist">
<option>...</option>
</select>
<input class="btn btn-primary" type="submit" value="Submit" id="submitfile" />
}
<div id="tablepartialview">
</div>
You probably have to install the Ajax unobtrusive NuGet package to provide the wiring, but it is quite simple and does not require you to write any extra JQuery for the view.

Categories