Ajax post causing 2 actions to run - c#

I'm new to MVC, and this problem has been driving me up the wall. I have some javascript that triggers a jquery ajax post when the user press the tab or enter key in the textboxes on my form:
<script type="text/javascript">
$(document).ready(function () {
$('#RmaNumber, #SerialNumber').keydown(function (event) {
if (event.keyCode == 13 || event.keyCode == 9) {
var ri = {
RmaNumber: $('#RmaNumber').val(),
SerialNumber: $('#SerialNumber').val(),
ControlName: event.target.id
}
$.ajax({
type: "POST",
url: "/Invoice/BarcodeScan",
contentType: "application/json; charset=utf-8",
data: JSON.stringify(ri),
dataType: "json",
success: function (data) {
$('#TerminalType').text(data.TerminalType);
}
});
}
});
});
</script>
Here is what my controller looks like. I removed the code to keep things simple:
public ActionResult Index()
{
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Index(RepairInvoice ri)
{
}
[HttpPost]
public ActionResult BarcodeScan(string RmaNumber, string SerialNumber, string ControlName)
{
}
The ajax postback causes both the BarcodeScan and Index action to fire. I only want the Index action with the [AcceptVerbs(HttpVerbs.Post)] above it to fire if a button is pressed on my form. Is this possible, or am I on the wrong track?

Since the comments helped, I'll add as an answer for future visitors...
I can't help but notice that one of the key inputs you're looking for is the return key. Depending on how the HTML for the form and the input is set up, the return key may also be causing the form to POST as normal. So essentially:
The JavaScript code is invoking a POST to the BarcodeScan action
The HTML form is invoking a POST to the Index action
The result of the former is being ignored by the browser, since the page is being re-loaded in its entirety. But regardless of the result, the action was still invoked.
There are a couple of ways to address this:
If there is a submit input that you're otherwise using as just a button, you can change it to a button and leave the form without a submit. This works well for forms which should be JavaScript-driven only and not have a default POST action, but it's hard to tell if that applies here without knowing more.
The JavaScript code can stop the DOM event in its tracks by calling preventDefault(). Most jQuery functions have a parameter for the event, and you'd call that function on the event. This would tell the DOM to end the event so it doesn't "bubble up" to the form, the document, etc.

Related

How to pass jQuery variable value to c# mvc?

How to pass jQuery variable value to c# mvc ?
I need to fetch the value of the variable btn in mvc code behind.
$('button').click(function () {
var btn = $(this).attr('id');
alert(btn);
$.ajax({
type: 'GET',
url: '#Url.Action("ActionName", "ControllerName")',
data: { id: btn },
success: function (result) {
// do something
}
});
});
Based on the variable value (Submit Button (or) Preview Button), my model will have Required validation on certain fields.
In my controller , i am calling as
[HttpGet]
public ActionResult ActionName(string id)
{
var vm = id;
return View(vm);
}
Though , ActionResult in controller is not invoked.
Jquery : alert(btn); -- is calling. I can see the alert window showing with the id. However, I am not able to retrieve the id in the controller.
You need to use jQuery.ajax() (or its shortened form jQuery.get()/jQuery.post()) with GET/POST method and set up a controller action with an argument to pass button ID:
jQuery (inside $(document).ready())
$('button').click(function () {
var btn = $(this).attr('id');
var url = '#Url.Action("ActionName", "ControllerName")';
var data = { id: btn };
// if controller method marked as POST, you need to use '$.post()'
$.get(url, data, function (result) {
// do something
if (result.status == "success") {
window.location = '#Url.Action("AnotherAction", "AnotherController")';
}
});
});
Controller action
[HttpGet]
public ActionResult ActionName(string id)
{
// do something
return Json(new { status = "success", buttonID = id }, JsonRequestBehavior.AllowGet);
}
[HttpGet]
public ActionResult AnotherAction()
{
// do something
return View(model);
}
If you want to pass retrieved button ID from AJAX into other action method, you can utilize TempData or Session to do that.
It is a nice coincidence that you use the word "fetch" to describe what you want to do.
jQuery runs in the browser as a frontend framework. Meaning that it runs on the client`s computer. Your MVC-C#-Code lies on the server. Therefore, if you want to send data between those two computers, you need to use the http protocol.
1. Ajax and REST:
Using an ajax call using http methods (post or put) to push your variable value as JSON to the backend`s REST api (route).
For this option, you might want to have a look at the fetch function of javascript.
2. HTML Forms
Use a html form where you store the variable value inside one input element. A form submission will perform a http post (by default) request to the backend as well and use all input element values as post parameters.
There are many ways to accomplish what you are looking to do, but I'll stick to using your code sample.
So what you need to do is utilize the .ajax call in jquery to send data from your view to your controller. More on that here: http://api.jquery.com/jquery.ajax/
Using your code, you'd put the .ajax call within your logic flow of what to do based on which button is clicked.
$("button").click(function ()
{
var btn = this.id;
if (btn == "previewButton")
{
$.ajax({
url: "/MyApp/MyAction",
type: "POST",
data: { btnId: btn },
dataType: "json",
async: true,
cache: false
}).success(function(data){
// do something here to validate if your handling worked
}).error(function(){
// Do something here if it doesnt work
});
}
}
You'll see that there is a URL. In my example i've chose MyApp as my controller and MyAction as the method of the controller in which we are posting values to. The ajax call posts 1 parameter with a property of btnId. If you need to pass more data, the property name in the jquery call should correspond with an argument of the actions method signature within the controller.
So my controller looks like
public MyAppController : Controller
{
[HttpPost]
public JsonResult MyAction(string btnId)
{
Debug.WriteLine("btnId: {0}", btnId);
return Json(new{ ButtonId= btnId });
}
}
This would be one way to handle passing values from your view to your controller using .ajax calls with jquery.
My preferred way is to use the Html helpers of Ajax.BeginForm which could be another option for you.
https://www.aspsnippets.com/Articles/ASPNet-MVC-AjaxBeginForm-Tutorial-with-example.aspx

Asp.net MVC Checkbox Event HTTPPOST ServerSide

net mvc5 form and Using checkbox.
My condition is i need to Call HTTPPOST action immedaitely after selecting the checkbox(true)
Its something like HTTPPOST action should be called immediately after selecting the checkbox.
I need to pass Model as well to the HTTP Post.
can you please let me know whats the desired way to get this done ?
I'd recommend using jquery to achieve this. Assuming your checkbox is nested in a form, you can use:
$(function () {
$('#CheckBoxName').change(function () {
$(this).closest("form")[0].submit();
});
});
This will trigger a postback, calling the appropriate HttpPost method and sending the model as a parameter.
You should use javascript to react on a change of the checkbox then posting via ajax.
Here is an exemple :
$('#checkbox').change(function(){
if (this.checked){
var jsonModel = '#Html.Raw(Json.Encode(Model))';
$.ajax({
type: 'post',
url: '#Url.Action("UrlOfPostAction")',
data: { Model: jsonModel},
dataType: 'json',
success: function (res) {
//Do something
}
//manage errors
});
}
});

How to refresh my Partial View after Ajax Post in MVC?

So basically I'm trying to show some Profile Data in my MVC Application.
Right now, everytime I click on a date on my Telerik Kendo Calendar, I can refresh the whole page and update the data I want.
However, instead of refreshing the whole I just want to refresh the partial views that shows only the data that updates after selecting the date.
Index.cshtml
<!--CODE-->
#Html.Partial("_WorkingTimeData")
<!--CODE-->
_WorkingTimeData.cshtml
var workedTime = ViewData["WorkedTimeToday"];
var hoursPerDay = ViewData["HoursPerDayContract"];
<p>You worked #workedTime hours</p>
<p>Hours Per Day (Contract) #hoursPerDay Hours</p>
Yes, right now I'm ViewDatas and it works.
This is the ajax code in Index.cshtml
$.ajax({ url: '/Profile/Index',
dataType: "json",
type: "POST",
data: JSON.stringify(10),
success: function(returl){
alert('It worked');
location.href=returl.Url;
},
error: function(jqXHR,responseText,textStatus){ alert(jqXHR.responseText) } });
Controller
[HttpPost]
public ActionResult Index(string number){
//THINGS TO DO
var redirectUrl = new UrlHelper(Request.RequestContext).Action("Index", "Profile");
return Json(new { Url = redirectUrl });
}
Well I'm very new to this, and I've been doing my research. However I still have some questions:
- Do I need to create a post method for _WorkingTimeData instead of Index like I have?
- Do I need to create a ViewModel for the Partial View?
Thanks
EDIT NUMBER 2 FOR VISHAL:
This didn't work at all, not even an alert, because, strangely, it doesn't recognise the calendar...
$("#calendar").kendoCalendar({
change : function() {
$.ajax({
url: "/Profile/WorkingTimeData",
type: "get"
}).done(function(data) {
$("#profile-timeline").html(data);
});
}});
It says $("#calendar").kendoCalendar is not a function (Telerik says that it's this way)
As for this, it reached the controller but didn't update anything:
function change() {
alert("Escolheste outro dia");
var calendar = $("#calendar").data("kendoCalendar");
var current = calendar.current();
alert(current);
$.ajax({
url: "/Profile/WorkingTimeData",
type: "get"
}).done(function(data) {
$("#profile-timeline").html(data);
});
}
I think it's because of the profile-timeline... It's a div in my view
Do I need to create a post method for _WorkingTimeData?
Yes, you need to create. But, Get would be fine too.
Do I need to create a ViewModel for the Partial View?
Not needed. If required you can create.
But, by looking at your partial view you are just using ViewData[""]. So, you need not to create any ViewModel.
Just create a method in Controller returning _WorkingTimeData PartialView.
And call that method by JQuery ajax on your DatePicker change event and replace the contents of the Div.
For example.
Controller
public PartialViewResult WorkingTimeData()
{
ViewData["WorkedTimeToday"]="NEW VALUE";
ViewData["HoursPerDayContract"] = "NEW VALUE";
return this.PartialView("_WorkingTimeData");
}
JavaScript
$("DATEPICKERELEMENT").change(function() {
$.ajax({
url: "/CONTROLLER/WorkingTimeData",
type: "get"
}).done(function(data) {
alert(data);
$("#divisionIdContainingPartialView").html(data);
}).fail(function() {
alert('error');
});
});
I wrote a post that details why you need to break the logic of thinking about partial views client-side. If you're interested you can find it here.
The TL;DR version is simply, all you have client-side is HTML. There's no knowledge about what was or was not rendered to the response via a partial view. As a result, the real question is "How do I change a portion of my HTML page based on an AJAX response?". In the simplest form, you simply select some element on the page and then alter its inner HTML. You can do that with some custom HTML created client-side or you can actually pass back an HTML document as your AJAX response and then insert that.

POST and GET executing simultaneously in MVC 4

I am trying to edit a field after clicking an item from a table.
I added an on clcik event to every object in the table like this :
onclick="itemEdit(this)
And my javascript function looks something like :
function itemEdit(e) {
console.log($(e).attr("id"));
var itmId = $(e).attr("id");
$.ajax({
url: '#Url.Action("Index", "Scraping")',
data: {itemId: itmId},
type: 'POST',
success: function(data) {
alert(data);
}
});
}
And what I do in my Index method is to load the clicked item in a more detailed manner on the top of the page like this :
public ActionResult Index(string itemId)
{
if (itemId != null)
{
im.loadItem(itemId.ToString());
}
else
{
if (im.lstEditModel.Count == 0)
{
im.loadLists();
}
}
return RedirectToAction("Index");
}
The problem I am having is that whenever I click an item, the index method executes twice..and thus creating a mess. Any help?
I don't see an [HttpPost] mark on that method, but at the end of the method, you are redirecting to another Index action... you normally would return some sort of JSON data rather than return RedirectToAction("Index");... this statement would be doing what you are describing, calling your Get Action.
From MSDN:
Returns an HTTP 302 response to the browser, which causes the browser to make a GET request to the specified action.
Try to stop event bubbling.
function itemEdit(e) {
e.stopPropagation();
console.log($(e).attr("id"));
var itmId = $(e).attr("id");
$.ajax({
url: '#Url.Action("Index", "Scraping")',
data: {itemId: itmId},
type: 'POST',
success: function(data) {
alert(data);
}
});
}
Please ignore this, by mistake I forgot to put href="#" when adding the onClick event causing the browser to reload my javascript code. I had typed href=""

Including an array with a serialize form - jquery

I currently have a form that I am trying to perform a post on (serializing the form), however I also want to include several checkboxes (but I don't want to include them in the form itself)
I have tried using jQuery's .post, but was unable to accomplish what I needed, any help would be greatly appreciated.
(I am using asp.net MVC 2.0 - and I figured this event would be attached to a button click)
There are several ways to accomplish this, I'll demonstrate two for you, along with an example of a Controller Action to accept the data:
Your Controller Action:
[HttpPost]
public ActionResult YourActionName(YourModel formModel, bool[] checkboxes)
{
...
}
.post Method:
//Serialize Form Data
var data = $("#yourForm").serializeArray();
//Iterates through all your checkboxes - with a specific class
$(".yourCheckboxClass").each(function ()
{
data.push({name : "checkboxes", value : $(this).val()});
});
.ajax Method:
//Build array of checkbox values
//You can use an .each here, or whatever other method you prefer
$.ajax({ type: "POST",
url: "<%= Url.Action("Action","Controller") %>",
datatype: "json",
traditional: true,
data: {
'formModel': $('#yourForm').serialize(),
'checkboxes': yourCheckboxArray
}
});
I hope this helps you accomplish what you need.
Would something like this work for you? (assuming the button is the submit button on the form)
$("#triggerButton").bind("click.me", function(e) {
var $form = $(this).closest("form");
$(".other-checkbox-class").appendTo($form);
});

Categories

Resources