jQuery Ajax Form Submit Fails - asp.net-mvc

I am developing an MVC4 mobile app that uses several forms which are loaded into a section on the layout via ajax. I've got jQuery mobile set with Ajax turned off so I can manage the Ajax myself. Most of the forms work fine, the load and submit via ajax as they should. However, so far there is one form that refuses to fire the form submit and submit the form via ajax like the rest. First, the form is loaded when a user clicks to add a contact and this works fine:
// Handle the add contact button click
$('#btnAddNewContact').on('click', function (e) {
e.preventDefault();
// Make sure a location was selected first.
var locationID = $('#cboLocation').val();
if (locationID.length === 0) {
//$('#alertTitle').text('REQUIRED');
$('#alertMsg').html("<p>A Contact must be associated with a Location.</p><p>Please select or add a Location first.</p>");
$('#alertDialogDisplay').click();
} else {
SaveOpportunityFormState();
$.cookie('cmdLocationId', locationID, { path: '/' });
$.mobile.loading('show');
$.ajax({
url: '/Contact/Add',
type: 'GET',
cache: false,
success: function (response, status, XMLHttpRequest) {
$('section.ui-content-Override').html(response);
// Refresh the page to apply jQuery Mobile styles.
$('section.ui-content-Override').trigger('create');
// Force client side validation.
$.validator.unobtrusive.parse($('section.ui-content-Override'));
},
complete: function () {
$.cookie('cmdPreviousPage', '/Opportunity/Add', { path: '/' });
AddContactLoad();
ShowSearchHeader(false);
$.mobile.loading('hide');
},
error: function (xhr, status, error) {
// TODO - See if we need to handle errors here.
}
});
}
return false;
});
Notice that after successfully loading the form the AddContactLoad() function is fired. This works fine and here is that code:
function AddContactLoad() {
$('#contactVM_Phone').mask('(999) 999-9999? x99999');
$('#frmAddContact').on('submit', function (e) {
e.preventDefault();
if ($(this).valid()) {
$.mobile.loading('show');
$.ajax({
url: '/Contact/Add',
type: 'POST',
cache: false,
data: $(this).serialize(),
success: function (response, status, XMLHttpRequest) {
if (!response) { // Success
ReturnToAddOpportunity();
} else { // Invalid Form
$('section.ui-content-Override').html(response);
// Force jQuery Mobile to apply styles.
$('section.ui-content-Override').trigger('create');
// Force client side validation.
$.validator.unobtrusive.parse($('section.ui-content-Override'));
AddContactLoad();
$.mobile.loading('hide');
}
},
complete: function () {
},
error: function (xhr, status, error) {
// TODO - See if we need to handle errors here.
}
});
}
return false;
});
$('#btnCancel').on('click', function (e) {
e.preventDefault();
// See where add contact was called from.
var previousPage = $.cookie('cmdPreviousPage');
if (previousPage.indexOf("Detail") >= 0) {
ReturnToOpportunityDetails();
} else {
ReturnToAddOpportunity();
}
return false;
});
}
If I click the cancel button, that code is fired so I know this is working too. Here is my form code:
#using (Html.BeginForm("Add", "Contact", FormMethod.Post, new { #id = "frmAddContact" }))
{
#Html.ValidationSummary(true)
#Html.AntiForgeryToken()
-- Form Fields Here --
<div class="savecancel" >
<input type="submit" value="Save" data-mini="true", data-theme="b", data-inline="true" />
Cancel
</div>
}
As you can see the form is named frmAddContact and that is what the AddContactLoad() function is attaching the submit event to. To save my sole I cannot figure out why the form does not submit via the ajax post like every other form in the app. Am I missing some kind of initialization, I just don't know. If anyone can please help I'd really appreciate it!!

As it turns out, I had created a custom unobtrusive Ajax validator for a phone number then copied and pasted it to do the same with a zip code. Unfortunately in the process I forgot to rename a variable and thus an error was occurring in the validation script which caused the problem. In the mean time, if you're reading this, you might take a note of the code here and how to inject HTML into a page via Ajax and jQuery mobile. I've never found this in a book or on the web and it contains some very useful methodology and syntax. On the form submit the reason I'm checking for the empty response is I just return null from the controller to validate the form was valid and the save worked in which case I send them to a different HTML injection i.e. that page they originally came from. If null is not returned I inject that page with the HTML containing the original form and error markup so the user can make corrections then resubmit. I'm also calling a form load method that attaches handlers to the HTML once it's injected into the main page. Hope this helps somebody!

Related

JQuery-ui Tabs - reload page with completely new content not working

I'm loading in a report and displaying it with jquery-ui in tab format. The report is returned by an ajax call in json, and a function is formatting it into HTML. Example code below:
<div id="reportdiv">
</div>
<script>
function displayreport(objectid)
{
$( "#reportdiv" ).hide();
$( "#reportdiv" ).html("");
$.ajax({
type: "GET",
headers: { 'authtoken': getToken() },
url:'/reportservice/v1/report/'+objectid.id,
success: function(data){
if(data == null)
{
alert("That report does not exist.");
}
else
{
var retHTML = dataToTabHTML(data.config);
$("#reportdiv").html(retHTML).fadeIn(500);
$(function() {
tabs = $( "#reportdiv" ).tabs();
tabs.find( ".ui-tabs-nav" ).sortable({
axis: "x",
stop: function() {
tabs.tabs( "refresh" );
}
});
});
}
}
});
}
</script>
This works fine the first time displayreport is called. However, if the user enters another value and runs displayreport again, the "tabs" format is completely lost (the tabs are displayed as links above my sections, and clicking on a link takes you to that section further down the page).
I figured completely re-setting the reportdiv html at the beginning of the function would bring me back to original state and allow it to work normally every time. Any suggestions?
After more testing, found that destroy was the way to go. If I've set up tabs already, run the destroy, otherwise, skip the destroy (http://jsfiddle.net/scmxyras/1/) :
if(tabs!=undefined)$( "#reportdiv" ).tabs("destroy");

How to keep reCaptcha on screen after failed input

I have an asp.net MVC site with a bootstrap modal that has a reCaptcha form on it. It correctly validates the input upon submit, but if it's not valid, upon rendering the view so they can try again, the captcha disappears and the javascript console shows this error: "Failed to execute 'write' on 'Document': It isn't possible to write into a document from an asynchronously-loaded external script unless it is explicitly opened." I have to refresh the page and reopen the modal to see the Captcha again.
Snippet of code containing the Captcha (public/private keys are in web.config):
<input type="hidden" name="ProductID" value="#Model.ProductID" />
<input type="hidden" name="UserTypeID" value="#Model.User.UserTypeID" />
#Html.Recaptcha(theme: Recaptcha.Web.RecaptchaTheme.Clean)
<div id="request-error-summary">
#Html.ValidationSummary(false, "All fields are required.")
</div>
Controller code upon submitting form:
public PartialViewResult SubmitRequest(RequestKitModel kitModel)
{
/* code removed for brevity */
RecaptchaVerificationHelper recaptchaHelper = this.GetRecaptchaVerificationHelper();
if (String.IsNullOrEmpty(recaptchaHelper.Response))
{
ModelState.AddModelError("", "Captcha answer cannot be empty.");
return PartialView("_Request", kitModel);
}
RecaptchaVerificationResult recaptchaResult = recaptchaHelper.VerifyRecaptchaResponse();
if (recaptchaResult != RecaptchaVerificationResult.Success)
{
ModelState.AddModelError("", "Incorrect captcha answer.");
return PartialView("_Request", kitModel);
}
/* code to ruun upon success of captcha input */
//close modal and return to results
return PartialView("_Confirmation");
}
Jquery Ajax call to SubmitRequest... I think the way I'm loading the partial view may be the culprit.
if ($('#request-form').valid()) {
$.ajax({
url: "/SubmitRequest",
type: "POST",
data: $("#request-form").serialize(),
success: function (data) {
//show the confirmation (thanks) modal
$("#request-modal .modal-content").html(data);
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
window.location.href = '#Url.Action("Error")';
}
});
}
UPDATE: I changed it to use recaptcha_ajax.js since I am loading it after an ajax request. Now I get this error: "cannot set property 'innerhtml' of null" from the recaptcha_ajax.js file (cannot tell which object it's throwing this error on). Instead of calling Html.Recaptcha in the razor file, I now have this:
<script type="text/javascript" src="http://www.google.com/recaptcha/api/js/recaptcha_ajax.js"></script>
<div id="recaptcha1"></div>
And the updated AJAX call:
$.ajax({
url: "/SubmitRequest",
type: "POST",
data: $("#request-form").serialize(),
success: function (data) {
//show the confirmation (thanks) modal
$("#request-modal .modal-content").html(data);
Recaptcha.create("6LedL_sSAAAAAJuozIfRiVfNOCHs-jlTn6NM4c-T",
"recaptcha1",
{
theme: "white",
callback: Recaptcha.focus_response_field
}
);
console.log("done loading html");
console.log('captcha control: ' + $("#recaptcha1").length);
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
window.location.href = '#Url.Action("Error")';
}
});
Try and put the javascript reference
<script type="text/javascript" src="http://www.google.com/recaptcha/api/js/recaptcha_ajax.js"></script>
in your main layout, I got the same error you did because the javascript library wasn't fully loaded.
You should also check that the div exists in the callback.
I hope this helps,
Salvador

HTML reponse after Ajax call is stripped of some tags

I am making an ajax call to a action in a controller which returns a partial view. The partial view is a row that will be appended or it will replace an existing row from a grid of items (depending if I am adding or editing a row item).
In the Network tab from Google Chrome I am getting the correct string of HTML like:
<tr class="" data-id="1c4daceb-2afb-413b-8adc-d20b4d8969e5">
<td><img style="width:100px; height:100px;" src="http://localhost/Project/6b39488b-db2d-495e-957c-ede0eb462292.png" data-id="1c4daceb-2afb-413b-8adc-d20b4d8969e5"/></td>
<td>bvcbvX</td>
<td>6b39488b-db2d-495e-957c-ede0eb462292.png</td>
</tr>
but in my Ajax success function:
function onDataEdited(data, status, xmlhttp) {
alert(data);
}
I get the row stripped of and tags, like this:
<img style="width:100px; height:100px;" src="http://localhost/Project/6b39488b-db2d-495e-957c-ede0eb462292.png" data-id="1c4daceb-2afb-413b-8adc-d20b4d8969e5"/>
bvcbvX
6b39488b-db2d-495e-957c-ede0eb462292.png
So something from jquery strips my tags leaving only the content.
The call to the action is done through Ajax like this:
function MakeAjaxCall() {
$('#myForm').ajaxForm({
iframe: true, ---> here is needed since I am adding a file upload from my form
beforeSubmit: function () {
if (!$('#myForm').valid())
//process validation
return $('#myForm').valid();
},
success: function (data, status, xmlhttp) {
if (xmlhttp.getResponseHeader('ErrorHeader') == null ||
xmlhttp.getResponseHeader('ErrorHeader') == "") {
//process success
}
else {
//process error
}
},
error: function (xhr, textStatus, errorThrown) {
alert(xhr);
}
});
}
Can anyone tell me how to get my response data without being stripped of and tags?
I am using this jquery plugin (malsup.com/jquery/form) for making the form "ajaxified" in order to submit a form that contains files through Ajax.
The 'ajaxForm' method from this plugin has as dataType only 'xml', 'json', 'script' and null - (which I am using) and the response is stil stripped of tags for 'xml'. If I set 'json' or 'script' it throws a client side errors specifying that it cannot parse the response (is trying to parse it as a script when it is html).
Could be an issue with the dataType: http://malsup.com/jquery/form/#options-object ?

MVC3 Ajax.BeginForm hooking submit event before validation

I am using an Ajax.BeginForm with unobtrusive validation. I want to give the user the option to save the data with a minimum number of validated fields (which might be zero) but allow some required fields to be saved when empty.
I think my requirements are:
add an event handler to the submit button
perform the validation manually
identify which fields have failed validation because they are empty
identify which fields have failed validation the data is in error
I can catch the submit event and validate the form by adding the following at "document ready"
$(document).ready(function () {
$('#submit-11').click(function () {
if (!$("#form0").valid()) {
alert("woops");
return false;
}
return true;
});
My problem now is how to identify which fields have failed validation and the reason for failing.
I can find nothing on Google (although that may be a function of my search skills rather than the problem.)
Thanks in advance.
have you tried
event.preventDefault();
just after the submit click?
http://api.jquery.com/event.preventDefault/
Now regarding your larger question. I think you can do all of that with jquery
here's an example
$(document).ready(function () {
//form validation rules, including custom rules you'd like
$("#form").validate({
rules: {
fieldOne: { required: true },
fieldTwo: { required: function () { /*custom validation*/return true; } }
},
messages: {
fieldOne: { required: "error" },
fieldTwo: { required: "error" }
}
});
//handle submit click
$("#btnSubmit").click(function (event) {
event.preventDefault(); //stops form from submitting immediately
if ($("#form").valid()) { //perform validation
//submit your data if valid
$.post("/your/action", $form.serialize(), function (data) {
//do something with the result
});
}
});
});
UPDATE:
So maybe you should be doing this, when you add the validate handler to the form you can implement the submitHandler and the invalidHandler.
Now what you really should be looking at is the invalidHandler
$(document).ready(function(){
$("#form").validate({
rules : {
field : {required : true}
},
messages : {
field : {required : ""}
},
submitHandler: function(form) {
form.submit(); //if all is good
},
invalidHandler: function(form, validator){
console.log(validator.errorList); //if something went wrong
}
});
this function receives the validator which in turns has the errorList containing all the fields (and messages) that failed.
Test this code with chrome's developer tools, for instance, and you'll see what's in the errorList.

Previous ajax request changes the post URL for next form submit

I am making a jQuery ajax request in a asp.net mvc page:
$.ajax({
type: "POST",
url: "/Home/Go",
data: dataObj,
success: function (data) {
// update html here
}
}
});
This call is within a page, which has a form and other elements which submit to other url (lets say "/Home/Do"). Now after the ajax call returns, If I click on any other element the form still submits to url1 instead of url2
Note I tried adding a "return false" statement to click event handler where the ajax call is made. But even this did not help
The ajax call is made within the jQuery dialog:
$('#myDialog').dialog({ buttons:
[
{
text: 'Next',
click: function () { HandleNext(); return false; }
}
],
title: 'Dialog-Title'
});
function HandleNext()
{
$.ajax({
type: "POST",
url: "/Home/Go",
data: dataObj,
success: function (data) {
// update html here
}
}
});
return false;
}
Anybody faced a similar issue? any solutions?
return false in the click handler is mandatory for ALL ajax requests. The web browser will visit the url otherwise. In other words: The ajax request is made first and then a regular request.
No urls can automagically be replaced with other urls. You either do it in your javascript code, or in your action/view.

Resources