Ajax update after Delete action on Index view in ASP.MVC - asp.net

I'm trying to do an Ajax delete in a fairly standard Index view, i.e. I have a generated Index view with one added filter drop-down, of little relevance here. I have changed the free Delete Html.ActionLink on every row to an Ajax.ActionLink, and the delete and ajax update work, but whichever container div I try and update, I always somehow get some kind of nesting in the updated page, e.g. after a delete and update, I get duplicate Home and About links from the master page inside my content.
Here is my current action link that causes what I describe above:
<%: Ajax.ActionLink("Delete", "Delete", new { id = item.InstallationDBNumber }, new AjaxOptions { UpdateTargetId = "jobList" }) %>
... and here is where jobList is located, just outside the table used for the index list:
<div style="clear: both;">
</div>
<div id="jobList" class="index-list">
<table>
<tr>

You should post your code for your Delete action method on your controller. But from the sounds of it, you are returning Return View(myModel) instead of Return PartialView("partialViewName", myModel).
Create a partial view contianing the layout information for jobList and return that from your controller action method.

Related

activating a different <div> with a partial view in my Layout.html by getting the name of controller action or view

I'd like to get the name of my partial view in my layout page to determine which div is going to be active. Because of the design I cannot css this nicely so I went for a more sloppy approach.
In my _Layout.chtml The Renderbody loads my content. And here depending on which button I press, I get a map or a list.
These are both functions in my controller and what I would like to do is get the functionname or partial view so I can then decide which I want to show.
so I wanted to do something like this in my _Layout.chtml
#if ( get the controllername or view == mapname or listname)
{
<div>
#Html.Partial("tabMap")
</div>
}
else
{
<div>
#Html.Partial("tabList")
</div>
}
Any quick fix to do this ?
access the RouteData dictionary from the ViewContext Object
will be like this
#ViewContext.RouteData.Values["Controller"]
with the RouteData Dictionary you can get all the info needed about the controller , action and extra parameters names , depending on them output the data you want

Rendering partial view dynamically in ASP.Net MVC3 Razor using Ajax call to Action

I'm trying to create a single page form to create a 'work item'. One of the properties is a drop down for 'work item type'.
Depending on the work item type, the user may need to provide additional information in a name-value-pair style attributes grid (property sheet).
I would like to dynamically render the property sheet as soon as a work item type is selected or changed. Once the user provides all information, he would click submit to create the 'work item'.
This is what I have so far:
#using (Ajax.BeginForm("AttributeData", new AjaxOptions() { UpdateTargetId="AttributeDataCell" }))
{
<div style="float:left">
#{
Html.RenderPartial("CreateWorkItemPartialView");
}
</div>
<div id="AttributeDataCell" style="float:right">
#Html.Action("AttributeData", new {id = 1})
</div>
}
The AttributeData action in the controller simply renders the partial view:
public ActionResult AttributeData(int id = 0)
{
var attributes = _workItemDataService.ListWorkItemTypeAttributes(id);
return PartialView("EditWorkItemAttributesPartialView", attributes);
}
Now I would like to hook this up to the drop-down-list's selection event so that the partial view re-renders in the above table cell at every selection change. I would like to pass in the selected value as id.
One way is to force the form to submit itself (and thus re-render).
If that is the right approach, how do we go about it? Esp., how do we make only the property sheet to re-render?
If there is a better way to achieve the above, please indicate.
Thanks
You could subscribe to the .change() event of the dropdown and trigger an AJAX request:
$(function() {
$('#Id_Of_Your_Drop_Down').change(function() {
// This event will be triggered when the dropdown list selection changes
// We start by fetching the form element. Note that if you have
// multiple forms on the page it would be better to provide it
// an unique id in the Ajax.BeginForm helper and then use id selector:
var form = $('form');
// finally we send the AJAX request:
$.ajax({
url: form.attr('action'),
type: form.attr('method'),
data: form.serialize(),
success: function(result) {
// The AJAX request succeeded and the result variable
// will contain the partial HTML returned by the action
// we inject it into the div:
$('#AttributeDataCell').html(result);
}
});
});
});

Partial View Does Not Recognize Another Controller

I am creating a partial view for the login which will be using the default model (AccountModel) and controller (AccountController) which were added when a new MVC 3 project is created.
However, the partial view (Login) does not recognize the controller (AccountController). I am getting "The resource cannot be found" error when I hit the "Register" link. Below is the snippet of the code.
Please advice.
Thanks
_Layout.cshtml
<div>
<div id="SideBar">
<div id="LoginHeader">
Login
</div>
<div id = "Login">
#Html.Partial("UserControls/UserLogin", new BalanzLab.Models.LogOnModel())
</div>
</div>
</div>
UserLogin.cshtml
#model BalanzLab.Models.LogOnModel
#using (Ajax.BeginForm("LogOn", "AccountController", new AjaxOptions { UpdateTargetId = "AccountController" }))
{
if (Request.IsAuthenticated)
{
Html.DisplayFor(Context.User.Identity);
}
else
{
<div >User Name
#Html.TextBox(" ")
</div>
<div>Password
#Html.Password(" ")
</div>
<div>
#Html.ActionLink("Signup", "Register", "AccountController")
</div>
<p><input type="submit" value="Let me in!" /></p>
}
}
This has to do with where you have the UserLogin shared view and how you're referencing it.
First the how:
You're including the partial view from your _layout view. Therefore, it's in every page that uses that layout.
Now consider what you're doing here. When you click that Register link that's supposed to take you to the Account controller Register method, it's hitting the call to #Html.Partial:
#Html.Partial("UserControls/UserLogin", new BalanzLab.Models.LogOnModel())
and trying to include it in the current page. Since the UserLogin control is actually under a folder in the Home views directory, it's not in the standard search path of where the view engine will search. It will check within the Accounts directory of views (the current controller) and it will check the Shared views directory. Since it can't find the partial view in either location, you get your error. (which looks something like this)
The partial view 'UserControls/UserLogin' was not found or no view engine
supports the searched locations. The following locations were searched:
~/Views/Account/UserControls/UserLogin.aspx
~/Views/Account/UserControls/UserLogin.ascx
~/Views/Shared/UserControls/UserLogin.aspx
~/Views/Shared/UserControls/UserLogin.ascx
~/Views/Account/UserControls/UserLogin.cshtml
~/Views/Account/UserControls/UserLogin.vbhtml
~/Views/Shared/UserControls/UserLogin.cshtml
~/Views/Shared/UserControls/UserLogin.vbhtml
The cleanest solution is to move this partial view to the shared views directory. Since it's part of the _layout view, you almost have to do this to make this work as the partial will be included by every view that uses the layout.

How to send the data to one page to other page using asp.net mvc

I have two pages with two grids,
in my first page I have 10 editable rows. and I have one next button.
I need to get all these 10 rows edited values to the next page to store the edited values to the other variable ID's in the next page. what is the best way to use this type of situations
Thanks
Have your editable rows inside of a <form> in the first view
// BeginForm will render a <form> around the rowmodel HTML
using (Html.BeginForm('PostToMe', 'MyController')) {
foreach (RowModel row in Model) {
// HTML to render out a row
}
}
then send each row as an instance of a view model type with properties that match the data for each row
public class RowModel
{
// properties here
}
Finally post a collection of those types to the controller action. e.g.
public class MyController : Controller
{
[HttpPost]
public ActionResult PostToMe(IList<RowModel> rows)
{
// do something with rows
}
}
In ASP.NET MVC there is no notion of Page. There are controllers, actions and views. So probably what you are talking about is how to have a view send information to a controller action. Well there are couple of ways. One consist in generating an HTML <form> in this view, filling it with input elements and pointing this form action attribute to the target action:
<% using (Html.BeginForm("TargetAction", "SomeController")) { %>
... some input fields, maybe in a grid, whatever
<input type="submit" value="GO" />
<% } %>
If you want to select a particular row in the grid then you could generate a form on each row in this grid and use the item id as hidden field.

ASP.NET MVC Submitting Form Using ActionLink

I am trying to use link to submit a form using the following code:
function deleteItem(formId) {
// submit the form
$("#" + formId).submit();
}
Basically I have a grid and it displays a number of items. Each row has a delete button which deletes the item. I then fire the following function to remove the item from the grid.
function onItemDeleted(name) {
$("#" + name).remove();
}
It works fine when I use a submit button but when I use action link the JavaScript from the controller action is returned as string and not executed.
public JavaScriptResult DeleteItem(string name)
{
var isAjaxRequest = Request.IsAjaxRequest();
_stockService.Delete(name);
var script = String.Format("onItemDeleted('{0}')", name);
return JavaScript(script);
}
And here is the HTML code:
<td>
<% using (Ajax.BeginForm("DeleteItem",null, new AjaxOptions() { LoadingElementId = "divLoading", UpdateTargetId = "divDisplay" },new { id="form_"+stock.Name }))
{ %>
<%=Html.Hidden("name", stock.Name)%>
<a id="link_delete" href="#" onclick="deleteItem('form_ABC')">Delete</a>
<% } %>
</td>
My theory is that submit button does alter the response while the action link simply returns whatever is returned from the controller's action. This means when using submit the JavaScript is added to the response and then executed while in case of action link it is simply returned as string.
If that is the case how can someone use action links instead of submit buttons.
UPDATE:
Seems like I need to perform something extra to make the action link to work since it does not fire the onsubmit event.
http://www.devproconnections.com/article/aspnet22/posting-forms-the-ajax-way-in-asp-net-mvc.aspx
My guess is the MS Ajax form knows how to handle a JavaScriptResponse and execute the code whereas your plain old Action link, with no relationship to the AjaxForm, does not. I'm pretty sure the MS ajax library essentially eval()s the response when it sees the content type of javascript being sent back.
Since you have no callback in your deleteItem() method there is no place for the script to go. To fix you'll have to manually eval() the string sent back which is considered a bad practice.
Now I'm not familiar with the MS Ajax library to be certain of any of this but what your doing is possible. I'd do things differently but don't want to answer with a "my way is better" approach ( especially because your blog has helped me before ) but I'd like to show this can be easier.
I'd ditch the form entirely and use unobtrusive javascript to get the behavior you want. IN psuedo jqueryish ( don't know ms ajax ) code:
function bindMyGrid() {
$('.myDeleteLink').onclicksyntax( function() {
//find the td in the row which contains the name and get the text
var nameTdCell = this.findThisCellSibling();
//do an ajax request to your controller
ajax('myUrl/' + nameTdCell.text(), function onSuccessCallback() {
//get the tr row of the name cell and remove it
nameTdCell.parent().remove();
});
});
}
This also gains the benefit of not returning javascript from your controller which some consider breaking the MVC pattern and seperation of concerns. Hope my psuedo code helps.
Try without the UpdateTargetId property in the AjaxOptions (don't specify it)
new AjaxOptions() { LoadingElementId = "divLoading" }
What about just change look of a standard or using some css class? It'll look like a link and you'll avoid some problems you get with anchors - user will be able to click on it by a mouse wheel and open that link in a new tab/window.

Resources