I am implementing a simple CRUD operating. I have List of data displayed in table with capability of add edit and delete. Add edit and delete operation takes place in Jquery dialog
When i am trying to add a new record I return the Json result as Success True/false depending on the form data entry.
Here is my code
[HttpPost]
public ActionResult AddUser(AddCEQRUser addUserInfo)
{
// perform insert operation
if (ModelState.IsValid && InsertSuccess)
return Json(new { success = true }, JsonRequestBehavior.AllowGet);
else
return Json(new { success = false }, JsonRequestBehavior.AllowGet);
}
Partial view for add
#using (Html.BeginForm("AddUser", "Admin", FormMethod.Post, new { id = "addUserForm" }))
{
#Html.AntiForgeryToken()
<fieldset>
<table class="headertable">
// form elements
<tr>
<td align="center" colspan="2">
<button name="button" value="SubmitUser" class="button" id="btnSubmitUser">
Submit
</button>
<button name="button" value="CancelAddUser" class="button" id="btnCancel">
Cancel
</button>
</td>
</tr>
</table>
</fieldset>
}
Ajax call on Submit button
$('#btnSubmitUser').click(function () {
$.ajax({
url: '#Url.Action("AddUser", "Admin", new { Area = "PrivateCEQRApplication" })',
type: 'POST',
dataType: 'json',
cache: false,
headers: headers,
data: {
FirstName: $('#txtFirstNameAdd').val(),
MiddleName: $('#txtMiddleNameAdd').val(),
LastName: $('#txtLastNameAdd').val(),
EmailAddress: $('#txtEmailAddressAdd').val(),
UserRole: $('#ddlUserRoleSelectedAdd').val()
},
beforeSend: function (xhr, settings) { xhr.setRequestHeader('__RequestVerificationToken', token); },
success: function (data) {
if (data.success) {
alert("The user has been added.");
$(".ui-dialog-content").dialog().dialog("close");
}
else {
//error handling
}
},
error: function (xhr, textStatus, errorThrown) {
alert("There was a problem with the operation. Please try again" + "Status: " + textStatus + "Error: " + errorThrown);
}
});
});
Irrespective of whether there is an error or not when ever I click the Submit button I get a json file with { success : true } to download By IE.
I have read quite a few article about this and how it says to set Content type application/json or text/html
If i set content type to application/json I still get prompted to download and if i set text/html a new page opens with { success : true }.
I also noticed if i put e.preventDefault(); in my btnSubmitUser click event I don't get prompted for download but then i loose the error handling.
All I want is for dialog to close if there is no error (json success true) by executing this code
alert("The user has been added.");
$(".ui-dialog-content").dialog().dialog("close");
and display error if any by executing the json success false block.
Your help will be greatly appreciated.
Thanks
As Adeneo says, you have to prevent the default action of the form submit to allow the javascript to complete. You can do this by adding event.preventDefault(); as the first line of your function (just below $('#btnSubmitUser').click(function () {) or by having the function return false.
Related
I'm trying to refresh a div when submiting a form, but I'm having a 404 error
jquery.min.js:2 POST Https://xxxx.com.ar/Home/#Url.Action(%22Pagination2%22,%22Home%22) 404 (Not Found)
This is my form:
<form action="~/Home/Pagination" method="post" id="ajax_submit_siguiente">
<button class="siguiente-imagen #ViewData["btnSiguiente"]" id="btnSiguientePaginacion" value="#item.getNumeroEntrega()" type="submit">
Siguiente
</button>
</form>
And this is my js:
$(document).ready(function () {
$("#ajax_submit_siguiente").submit(function (e) {
// prevent regular form submit
e.preventDefault();
var data = {
'paginacion': 'siguiente',
'entrega': $("#btnSiguientePaginacion").val()
}
$.ajax({
url: '#Url.Action("Pagination","Home")',
type: 'POST',
data: data,
success: function (result) {
console.log(result);
// refresh
$(" #container-galeria-imagenes").load(window.location.href + " #container-galeria-imagenes ");
},
error: function (err) {
console.log(err);
}
});
})
});
And this is my JsonResult...
[HttpPost]
public async Task<JsonResult> Pagination(string paginacion, string entrega)
{
List<PedidoViewModel> list;
// Working code....
return Json(list);
}
I'm very new with ajax, I read the documentation and was like this how to refresh a div after sending a submit...
since its a form submit rather than creating the object serialize the form and pass it to the server. also just to double confirm check the conversion of '#Url.Action("Pagination","Home")'is correct using the browser debugger tool and also make sure the routing is implemented correctly in Server side
$(document).ready(function() {
$('#myForm').submit(function(event) {
event.preventDefault(); // prevent the form from submitting normally
$.ajax({
type: 'POST',
url: '/my/url',
data: $('#myForm').serialize(),
success: function(response) {
$('#myDiv').html(response); // update the content of the div with the response
}
});
});
});
i am trying to use sweetAlert2 for my ajax, creating a form inside and then do its process and get the results back, but i am stuck at one point which is when i send the results how do i process the ajax inside it,
Here is my code as of now
Swal.fire({
title: 'Request PlayForm',
html: `<textarea name="da" id="da"></textarea>`,
confirmButtonText: 'Submit',
focusConfirm: false,
preConfirm: () => {
const textData = Swal.getPopup().querySelector('#da').value
if (da== '') {
Swal.showValidationMessage(`Please enter details.`)
}
return { da: da}
}
}).then((result) => {
Swal.fire(`
Email Sent Successfully -- this message should come when i get a success from my ajax else it will display error which i can get from ajax
`.trim())
})
You can do it like this.
Swal.fire({
title: 'Request PlayForm',
html: `<textarea name="da" id="da"></textarea>`,
confirmButtonText: 'Submit',
focusConfirm: false,
preConfirm: () => {
const textData = Swal.getPopup().querySelector('#da').value;
if(!textData || !textData.trim()) {
Swal.showValidationMessage(`Please enter details.`)
}
return textData;
}
}).then((result) => {
var myResult = result.value;
console.log("calling ajax");
$.ajax({
url: 'https://pokeapi.co/api/v2/pokemon/' + myResult,
//data: {'da':myResult}, <== use this if you're sending any data
type: 'get', // or post, depending what you do in the background,
// dataType: 'json' - data type of your response. It's optional,
// you can set it to something else, like text, or application/pdf,
//or something else
beforeSend: function() {
console.log("this is before send - we want to get some info " + myResult);
// disable buttons to prevent double clicks,
// or do something else
},
success: function(data) {
// Process the response - data
// Send mail if successful
if(data) {
Swal.fire(`
Email Sent Successfully -- this message should come
when i get a success from my ajax else it will display
error which i can get from ajax
`.trim());
console.log(data);
} else {
Swal.fire(`There was an error: ` /* your error here*/);
}
},
error: function(desc, err) {
Swal.fire(`
AJAX error! Description: ` + JSON.stringify(desc) + `,
error: ` + JSON.stringify(err));
}
});
// END AJAX
});
// END .then(...)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.3/jquery.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/sweetalert2#11"></script>
The variable myResult (you can name it whatever you like) stores the result of da / return of your preconfirm. You could process it later on, to see if it matches what you expect (for example, whether there were any illegal characters, or if you were expecting a number, or a certain format, but the user decided to be cheeky and type in something else, etc).
If the input was alright, you move on to the else part in the .then(...), and call your AJAX there. Read the comments in the code for more info.
I'm sending a post request without a form in asp.net. I'm getting error 400.
AJAX
function deteleCategorieBtn(id) {
if (confirm("Are you sure you want to delete ?")) {
$.ajax({
type: "POST",
url: 'categories/delete/' + id,
success: function () {
var dataTable = $('#kt_datatable').DataTable();
dataTable.ajax.reload(null, false);
},
error: function (request, error) {
console.log(request, error);
}
})
}
CONTROLLER
// POST: Categories/Delete/5
[Route("delete/{id?}")]
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Delete(int id)
{
var category = await _context.Categories
.FirstOrDefaultAsync(m => m.Id == id);
if(category != null){
_context.Categories.Remove(category);
await _context.SaveChangesAsync();
}
else
{
return Json(new { error = true, messages = "Categorie doesn't exist" }, new Newtonsoft.Json.JsonSerializerSettings());
}
return Json(new { success = true, messages = "Registered well" }, new Newtonsoft.Json.JsonSerializerSettings());
}
}
On the console, the url is correct
I tried changing the type from POST to DELETE in ajax part, and HttpPost to HttpDelete - Didn't work
I used the very same controller code successfully with a form that looks like that :
<form asp-action="Delete" asp-route-id="#item.Id" onclick="return confirm('Are you sure you want to delete ? ?');">
<button type="submit" value="Delete" class="btn btn-sm btn-clean btn-icon"></button>
</form>
EDIT :
Found this error message :
System.InvalidOperationException: The provider for the source IQueryable doesn't implement IDbAsyncQueryProvider. Only providers that implement IDbAsyncQueryProvider can be used for Entity Framework asynchronous operations.
You need to add an Antiforgery token while doing the ajax post.
Add an antiforgerytoken like below in your page
#Html.AntiForgeryToken()
This will be added in a hidden input field
While doing the ajax post, send the token like below
$.ajax({
type: "POST",
url: 'categories/delete/' + id,
beforeSend: function (xhr) {
xhr.setRequestHeader('XSRF-TOKEN',
$('input:hidden[name="__RequestVerificationToken"]').val());
},
success: function () {
var dataTable = $('#kt_datatable').DataTable();
dataTable.ajax.reload(null, false);
},
error: function (request, error) {
console.log(request, error);
}
});
When I submit my form, the page gets redirected to a new window with the raw json object instead of showing the alerts that I have set up for testing. I'm guessing that it has something to do with returning a Json result from the controller, but I'm not experienced enough with ajax or json to know why this is happening.
Partial View (named _FooterButtons)
<div class="row col-12">
<div class="col-12 footerbuttons">
<button type="button" onclick="submit()" id="submit-form" class="btn btn-primary" value="Print" style="display: inline-block">Print</button>
<input type="button" class="btn btn-secondary" value="Cancel" />
</div>
</div>
Main View
#using (Html.BeginForm("Daily", "Reports", FormMethod.Post, new { id = "reportForm", #class = "report-form col-9" }))
{
...
<partial name="../Shared/_FooterButtons" />
}
JavaScript
$(document).ready(function () {
$("#startdatepicker").datepicker();
$("#enddatepicker").datepicker();
// Add the listener only when everything is loaded
window.onload = function () {
// Get the form
let rform = document.getElementById('reportForm');
console.log(rform);
// Add the listener
rform.addEventListener('submit', function (e) {
// Avoid normal form process, so no page refresh
// You'll receive and process JSON here, instead of on a blank page
e.preventDefault();
// Include here your AJAX submit:
console.log("Form submitted");
$.ajax({
type: 'POST',
data: $('#reportForm').serialize(),
url: '#Url.Action("Daily","Reports")',
contentType: 'application/json; charset=utf-8',
success: function (data) {
if (data.success) {
alert("Data Success");
} else {
alert("Data Fail");
$('#errorsModal').modal('toggle');
$('#errorsModal .modal-body label').html(data.message);
}
}
});
});
};
});
Controller
[HttpPost]
public IActionResult Daily(Daily dailyReport)
{
var dr = new ReportDaily();
var rc = new ReportDailyCriteria();
dr.Preview(rc, IntPtr.Zero, out Notification notification);
//dr.CreateReportAsPDF(ReportCriteria(), #"C:/");
if (notification.HasErrors)
{
return Json(new
{
success = false,
message = notification.GetConcatenatedErrorMessage(Environment.NewLine + Environment.NewLine)
});
}
return Json(new { success = true });
}
Json object that gets returned in a new window
{"success":false,"message":"Must select a payment Source, County and/or Municipal.\r\n\r\nMust select at least one payment type.\r\n\r\nMust select at least one user.\r\n\r\n"}
You need to avoid the normal form process and you have 2 options:
First: Add return false to onclick event.
<button type="button" onclick="submit(); return false" id="submit-form" class="btn btn-primary" value="Print" style="display: inline-block">Print</button>
This first option will be executed only if button is clicked, but maybe not if ENTER key is pressed while typing on an input.
Second and better option: Add an event listener to your form:
<script>
// Add the listener only when everything is loaded
window.onload = function() {
// Get the form
let rform = document.getElementById('reportForm');
// Add the listener
rform.addEventListener('submit', function(e) {
// Avoid normal form process, so no page refresh
// You'll receive and process JSON here, instead of on a blank page
e.preventDefault();
// Include here your AJAX submit:
console.log("Form submitted");
$.ajax({
type: 'POST',
data: $('#reportForm').serialize(),
url: '#Url.Action("Daily","Reports")',
contentType: 'application/json; charset=utf-8',
success: function (data) {
if (data.success) {
alert("Data Success");
} else {
alert("Data Fail");
$('#errorsModal').modal('toggle');
$('#errorsModal .modal-body label').html(data.message);
}
}
});
});
};
</script>
Edit: Since you're using jQuery .ready(), things are a bit different:
$(document).ready(function () {
$("#startdatepicker").datepicker();
$("#enddatepicker").datepicker();
// Not really sure if window.onload inside .ready() was the problem,
// but it could be
// Get the form and add the listener
$("#reportForm").on('submit', function (e) {
// Avoid normal form process, so no page refresh
// You'll receive and process JSON here, instead of on a blank page
e.preventDefault();
console.log("Form submitted");
$.ajax({
type: 'POST',
data: $('#reportForm').serialize(),
url: '#Url.Action("Daily","Reports")',
contentType: 'application/json; charset=utf-8',
success: function (data) {
if (data.success) {
alert("Data Success");
} else {
alert("Data Fail");
$('#errorsModal').modal('toggle');
$('#errorsModal .modal-body label').html(data.message);
}
}
});
});
});
I used a method similar to what Triby has suggested, but instead of adding an event listener on the form submit, I added one onto the submit button click.
I am using Bootbox for my modals and I am having trouble in showing the form validation errors from an Ajax call to the modal. The callback function for the submit button on my modal calls the add_college function to submit the form via Ajax.
When there are validation errors, the modal is populated with validation errors. The problem is that the modal closes regardless if there are validation errors or not. I want the modal to not close only when there are no validation errors.
I know I can just return false in the callback function on my button when there are validation errors to not close it but I have no way of knowing if there are validation errors since I cannot return a value in the Ajax call since it is asynchronous. What is the proper way of doing it?
Here is my code:
$('#new-college-btn').click(function () {
bootbox.dialog({
title: "New College",
message:
''// <Insert long HTML form here>
,
buttons: {
add: {
label: "Add",
className: "btn btn-primary",
callback: function () {
var form_data = {
college_name: $('#college-name').val(),
college_initials: $('#college-initials').val(),
username: $('#username').val(),
password: $('#password').val(),
confirmation_password: $('#confirmation-password').val()
};
add_college(form_data);
}
},
cancel: {
label: "Cancel",
className: "btn btn-default"
}
}
}); // end bootbox dialog
});
function add_college(form_data) {
console.log(form_data);
$.ajax({
url: 'admin/add_new_college',
type: 'POST',
data: form_data,
dataType: 'JSON',
success: function (response)
{
if (response.error) { // there are form validation errors
// populate modal with validation errors here
} else {
// other data processing here
Result.success('College Successfully Added!');
}
},
error: function () {
console.log("fail");
}
});
}
If you want to control when the dialog closes, make sure the callback for your "submit" button always returns false. Then, in the done() (and probably fail()) callbacks for the ajax function, call bootbox.hideAll() to close the dialog (along with any other dialogs you may have opened).
If you want to only close the current dialog, do something along this line:
var dialog = bootbox.dialog({
/* rest of your options... */,
buttons: {
submit: {
label: "Submit",
callback: function() {
var data = [];
$.post('/url', data)
.done(function(result, status, jqxhr){
// if everything went well...
dialog.modal('hide');
})
.fail(function(jqxhr, status, error){
// etc.
});
return false;
}
}
}
});
Basically, create a reference to the dialog, which you can then use inside of the ajax callback.