ASP MVC + AJAX, trying to Update a div asynchronously - asp.net-mvc

I'm new to Asp MVC, and I'm trying to accomplish a little async update (I'm using MVC3 RC2, with Razor, but I can manage with ASPX solutions too).
I have a Master page, which renders a shopping cart box on every page by calling Html.RenderAction("Cart","Shop"). The Cart action of the ShopController calls the database, etc, and outputs the results. This works.
First problem: if I put an ActionLink in this partial view (like Html.ActionLink("Remove")), then even if I call PartialView() from the Remove action, it renders only the shopping cart, and nothing else (in essence, my page disappears).
Second problem: There is a div called "cartContent" inside this partial view. I want to be able to put a link ANYWHERE (not just on the Master page or in the partial view), which when pressed calls a controller Action, and then updates ONLY the cartContent div based on the results. I've tried Ajax.ActionLink but it does the same as Html.ActionLink, even though I imported the Microsoft.MvcAjax js libs.
Also, if I solve the first problem, I want that to be async as well.
What solution do I use? I've tried setting UpdateTargetID to "cartContent", I've tried wrapping the cartContent into an Ajax.BeginForm, nothing. Do I HAVE to use jQuery (which I know nothing of)? Do I serialize some response to JSON, and update the div manually in Javascript? (I'm not really good at JS, I'm coming from the C# side of things)

You put a link wherever you want:
#Html.ActionLink("remove item", "remove", "somecontroller",
new { id = Model.Id }, new { #class = "remove" })
And then in a separate javascript file:
$(function() {
$('.remove').click(function() {
// when the link is clicked
// perform an ajax request:
$.ajax({
url: this.href,
type: 'delete',
success: function(result) {
// when the AJAX call succeed do something with the result
// for example if the controller action returned a partial
// then you could show this partial in some div
$('#someDivId').html(result);
}
});
// don't forget to cancel the default action by returning false
return false;
});
});
Remark: if the div you are updating contains also the link then you might need to use the .live() function or the click event handler will not work the second time because the DOM will be modified:
$('.remove').live('click', function() {
...
});

Related

Navigating to different views in Single Page Application

I'm developing Single page web application for which I will be using the MVC and knockout. In the _Layout.cshtml, I will have the menu bar using which user can view different views. When I click on the items in menu, I will be calling controller method and being a single page application, I will have to return partial view. However, I'm confused how I can load returned partial view exactly in my view area. If I use Ajax.BeginForm, I can specify the UpdateTargetID in which I need to update my partial view but as with menu item click, it will just be server method call. So I wonder how I can update the partial view inside view area?
Do you think writing following javascript function for each menu items is what I need to do?
$('#menuitemId').click( function() {
$.ajax({
type: 'POST',
url: '#Url.Content("~/ControllerName/ActionName")',
data: objectToPass,
success: function (data) {
$('#divid').innerHTML = data; // data is partial view returned from controller
}
});
}
Also, can someone point me/share working demo/good documents of Single page web application with MVC and knockout?
That looks fine to me.
You could also make it simpler like this:
$('#menuitemId').click( function() {
$('#divid').load('#Url.Content("~/ControllerName/ActionName")' + menuItemId);
});

How to execute Action method on click through scripts

In my app I have a button. By clicking this button I want to execute an action method.
This action method does not have any view.
My requirement is: "call this action method in on click event"
How can I execute the the method on the click event?
my Onclick event is
$('#Delete').click(function () {
#* #(Url.Action("Delete", new { id="cera123"}))*#
$.ajax({
url: '#(Url.Action("Delete", new { id="cera123"}))',
type: "GET",
success:function () {
alert('deleted');
}
});
my action method is
public ActionResult Delete(string id)
{
obj.EmpLi.RemoveAll(x => x.EmployeeId == id);
return RedirectToAction("Index", obj);
}
delete action is performed but i an see the result after voluntarily refreshing the page even though i gave RedirectToAction("Index")
thanks
$(function(){
$("#yourbutonId").click(function(){
$.get("/controller/action/id",function(data){
//data is what your action return
});
});
});
nilesh is right $.ajax is js,and $.get is sample use base on $.ajax
or $.post
to make these code work,you should ref jquery.js
Some background info...
If you come from the webforms and code-behind world is common to you that an HTML element calls a script in the code, but actually what asp.net webforms does is an http call to the script on the server. If you had an updatepanel, asp.net webforms would have done the same call via ajax.
That's the reason why in asp.net webforms the elements have the preceding asp: on their branded html tags. That way asp.net can convert their branded elements to real HTML elements.
The answer
The only way to execute the code of an action from an HTML element on-click event in asp.net MVC is by calling the URL that gets to that method. Either via ajax or by a request from the browser, an http request needs to be done.
With javascript you can listen when an element's on-click event is fired and then do some logic. If you're using jquery you can use the $.ajax() or $.get() methods to make a call to your action URL.

ASP.NET MVC 3 : How to force an ActionLink to do a HttpPost instead of an HttpGet?

Is it possible to force an #Html.ActionLink() to do a POST instead of a GET? If so, how?
ActionLink helper method will render an anchor tag, clicking on which is always a GET request. If you want to make it a POST request. You should override the default behviour using a little javacsript
#ActionLink("Delete","Delete","Item",new {#id=4},new { #class="postLink"})
Now some jQuery code
<script type="text/javascript">
$(function(){
$("a.postLink").click(function(e){
e.preventDefault();
$.post($(this).attr("href"),function(data){
// got the result in data variable. do whatever you want now
//may be reload the page
});
});
});
</script>
Make sure you have an Action method of HttpPost type to handle this request
[HttpPost]
public ActionResult Delete(int id)
{
// do something awesome here and return something
}
I suppose that if you need something like that is for an Action that will be doing something "permanent" on server side. For instance, deleting an object in database.
Here is a complete example of doing a delete using a link and posting:
http://www.squarewidget.com/Delete-Like-a-Rock-Star-with-MVC3-Ajax-and-jQuery
From the previous link (recomended reading anyway):
A delete link in your view:
#Ajax.ActionLink("Delete", "Delete", "Widget",
new {id = item.Id},
new AjaxOptions {
HttpMethod = "POST",
Confirm = "Are you sure you want to delete this widget?",
OnSuccess = "deleteConfirmation"
})
A bit of JS:
function deleteConfirmation(response, status, data) {
// remove the row from the table
var rowId = "#widget-id-" + response.id;
$('.widgets').find(rowId).remove();
// display a status message with highlight
$('#actionMessage').text(response.message);
$('#actionMessage').effect("highlight", {}, 3000);
}
What I would do is wrap your html around a form
#using(Html.BeginForm("YourAction","YourController", FormMethod.Post)){
<button>Hello</button>
}
Instead of using a link you might want to use a button.
If you really want to use a link, you might need some javascript
Something like this:
$("#idOfYourLink").click(function(){
var form = $(this).parents('form:first');
form.submit();
});
It's not possible to have a <a> element perform a POST to a web server.
You can use Javascript to capture the click event, stop the navigation, and perform an AJAX POST to the server, but if the user has Javascript disabled nothing will happen.
Do you have to use a <a> element, or just something that resembles a <a> element?
Also worth mentioning is to have a look at AjaxLink. It allows you to easily use a <a> element to perform an AJAX POST.
If you think... there is no tag for link in HTML that does a POST. And that's why you can't force a link to do a POST (and it doesn't make any sense).
To use "POST", ou should "POST" something. And that something should be a form, or you can do a POST using a javascript function for AJAX.
Anyway, if you need to POST without post anything you should review your resourcemodel, something stinks.

View Master Page and PostBack

I have a dropdown list on my master page that needs to postback after being changed. After the postback, whatever page initiated the postback needs to be re-displayed.
My question is where do I handle this? Obviously I do not want to have to modify every Action in my project... My guess is to maybe postback to some other fixed action and have that action redirect back to the page that is the referrer. Am I correct? Any thoughts?
Thanks.
Jason
In Site.Master, I ended up wrapping the dropdown within its own form that posted back to a dedicated controller/action.
<% Using Html.BeginForm("ChangeRole", "Home")%>
<div id="roleSelector">Change Role: <%=Html.DropDownList("Role", DirectCast(ViewData.Item("Roles"), SelectList), New With {.onchange = "this.form.submit();"})%></div>
<% End Using%>
In the controller I used the following code to change the mode and then redirected back to the referring URL.
<AcceptVerbs(HttpVerbs.Post)> _
Public Function ChangeRole() As ActionResult
Me.CurrentUser.SetRole(DirectCast([Enum].Parse(GetType(Models.ApplicationRoles), Me.Request.Item("Role")), Models.ApplicationRoles))
Return Redirect(Request.UrlReferrer.ToString())
End Function
I am unsure if this is the recommended way but I have been unable to think of another solution.
When you post back from the dropdown list change what are you doing? Can you maybe handle this in a jQuery call thus eliminating the need to re-display the page at all?
Calls to Action Methods can be asynchronous as griegs says, as such, you can post whatever information you need from the radio buttons to an action method without needing to reload the page.
If you need to update a part of the page, you can replace it with the contents of a rendered action method. If you use the jQuery ajax methods, you can post specific information to your methods.
For example, something like this:
$(document).ready(function()
{
$("#myRadioButton").change(function()
{
//Post to your action method, with the value of the radio button, function to call on success
$.post('yourActionMethodUrl', $(this).val(), function()
{
//Update some part of the page
});
});
});
This is based on memory, so you may need to check the syntax.

ASP.Net MVC Ajax call that returns JsonResult

I'm starting to learn ASP.Net MVC (the release candidate), and I'm having a little trouble. I might just be being picky, but I thought I'd ask.
I want to use the built-in (extended) ASP.Net Ajax methods to make a call to my controller, called "GetNames," that returns a JsonResult object. I've seen examples that use the $.getJSON() jQuery method, but I would instead prefer to do something like this:
<%using ( Ajax.BeginForm("GetNames", new AjaxOptions() { OnSuccess = "GetNamesSuccess", OnBegin = "GetNamesBegin", OnComplete = "GetNamesComplte", OnFailure = "GetNamesFailure" } ) ) { %>
<%=Html.TextBox("DummyData") %>
<input type=submit />
<% } %>
<script type="text/javascript">
function GetNamesSuccess()
{
alert("Success");
}
function GetNamesBegin()
{
alert("Begin");
}
function GetNamesComplete()
{
alert("Complete");
}
function GetNamesFailure()
{
alert("Failure");
}
</script>
When I click the Submit button, I get none of the alerts, and I get prompted to download a file containing the text of Json object, which I believe indicates that at least the controller method is working fine. But that's not the intended behavior for me... Ideally, Ajax.BeginForm would set it up such that the Json object would get passed to either the OnSuccess or the OnComplete method.
Is there a way to accomplish that?
Have you included both the MicrosoftAjax.js and MicrosoftMvcAjax.js javascript files in your view page? It sounds to me like it is actually posting the form instead of using Ajax. I've had this problem when I was missing the MicrosoftAjax.js include because the Ajax postback failed due to missing javascript classes and thus it invoked the normal form post.
On a related note, you should check to see if the request is Ajax or not in the controller and return a ViewResult (or Redirect) instead of Json if it's not. If someone has javascript turned off or you have errors on your page you want it to gracefully degrade and handle it as a normal postback rather than return Json.

Resources