Ajax.ActionLink not working MVC - asp.net-mvc

I have a grid, I need to add Details column to the grid and when the detail column is selected the details for that row should appear just below the current grid.
My Code :
<% Html.Grid(Model.InnerModel.StatusRecords)
.Empty("No data available")
.Attributes(new Hash(id => "resultsTable"))
.Columns(column =>
{
column.For(x => Ajax.ActionLink("Details", "BatchDetailsByStatus", "ReportsController", new { statusId = x.Status, jobNo = Model.InnerModel.JobNumber }, new AjaxOptions
{
HttpMethod = "GET",
UpdateTargetId = "StatusBatchDetailsDiv"})).Named("Details").DoNotEncode();
column.For(x => x.Status);
column.For(x => x.TotalCount).Named("Count");
}).Render(); %>
My Controller code:
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult BatchDetailsByStatus(int statusId, string jobNo)
{
var batchModel = BatchByStatus.GetBatchDetailsByStatus(statusId, jobNo);
return PartialView("BatchDetailsByStatus", batchModel);
}
I have a partailview BatchDetailsByStatus that gets all the required data to display.
But when I click on the Details link nothing happens, it does not work.
What am I missing out.
Thanks

Replaced ReportsController with Reports (controller name without Controller) in Ajax.ActionLink, and it worked

Related

Update DropDownListFor data source from controller MVC

I have a DropDownListFor that takes data source from controller. Is there a way to update it since i'm adding new values that i want then to be displayed on the same page.
View:
#Html.DropDownListFor(m => m.Id, MyController.GetIds(Model.Id).Select(g => new SelectListItem { Text = g.Text, Value = g.Value }), #Resource.System_Choose, new
{
#class = "form-control selectpicker",
data_live_search = "true"
})
Controller:
public static List<SelectListItem> GetIds(int Id)
{
var retVal = new List<SelectListItem>();
return retVal;
}
Make your View deal with Model that has property of type List<SelectListItem>() and return this property ready to be binded and displayed in DropDown.
There are some ways to achieve the goal,
Use only javascript to append the new value to select options. (If the new value doesn't send to backend)
Ajax and get the new list.
A sample for case 2, we can put the DropDownList to a partialview and use ajax to get the latest DropDownList in the partialview.
Controller :
public ActionResult QueryNewList()
{
return PartialView("~/Views/Home/_urPartialView.cshtml", viewModel);
}
Html:
<div id="myDiv"></div>
Js:
$.ajax({
dataType: "html",
url: "QueryNewList",
success: function (html) {
$("#myDiv").html("");
$("#myDiv").append(html);
}
})

asp.net mvc fill a dropdownlist according to the item selected in an author

i'm a total beginner in asp.net mvc and am trying to change the items in a dropdownlist according to the item selected in an author one (they are filled from a database)
<% using (Html.BeginForm("Index", "Home", FormMethod.Post, new { id = "TheForm" }))
{
Filiere: <%= Html.DropDownList("filiere", (SelectList)ViewData["filiere"], new { onchange = "this.form.submit();" })%>
Module:<%= Html.DropDownList("module",(SelectList)ViewData["module"])
}
%>
public ActionResult Index(int? fil)
{
var fi = db.filiere.Select(f => new {f.id,f.nom });
ViewData["filiere"] = new SelectList(fi.AsEnumerable(), "id", "nom");
List<module> mod;
if (fil == null)
mod = db.module.ToList();
else
{
mod = (from module in db.module
where module.id_filiere == fil
select module).ToList();
}
ViewData["module"] = new SelectList(mod.AsEnumerable(),"id","nom");
return View();
}
Try to create one more method in controller who accept the author information and return the list which you want to display in drop-down.
then simply put ajax call on author change event call the controller method for data and also pass current author information and on success bind result what you get from controller method to drop-down.

Updating a Partial View From A Link In Its Own WebGrid

This is pretty much my third day developing MVC and I have what I hope will be a simple question. Basically I have a WebGrid within a partial view, which has a column that performs an update via a controller.
The controller then returns the updated partial view successfully, but the it replaces the whole page with the results instead of just the partial view.
Here's the partial view:
#model Site.Models.UsersForCompanyModel
#{
ViewBag.Title = "Admin User Management Grid";
}
#{
var grid = new WebGrid(
Model.Users,
ajaxUpdateContainerId: "divUserGrid",
fieldNamePrefix: "gridItems_",
pageFieldName: "paging",
sortFieldName: "sortField"
);
grid.Pager(WebGridPagerModes.All);
var userColumns = new List<WebGridColumn>
{
new WebGridColumn {ColumnName = "Email", Header = "E-Mail", CanSort = true},
new WebGridColumn {Header = "Lock", Format = user => user.isAdmin ? Html.Raw("n/a") : Html.ActionLink(user.IsLocked ? "Unlock" : "Lock", "ToggleLock", new {userId = user.Id, companyId = Model.CompanyId}) },
};
<div id="divUserGrid">
#grid.GetHtml(
htmlAttributes: new { id = "userGrid" },
tableStyle: "table table-striped table-bordered",
columns: userColumns
)
</div>
}
...and here's the controller code:
public ActionResult GetUsersForCompany(string companyId)
{
using (var service = new ManagementService())
{
var model = GetUsersForCompany(companyId, service);
return PartialView("AdminUserManagement_Grid", model);
}
}
public ActionResult ToggleLock(string companyId, string userId)
{
using (var service = new ManagementService())
{
var user = service.GetUserById(userId);
service.LockUser(userId, !user.IsLocked);
return GetUsersForCompany(companyId);
}
}
What's the easiest way to go about updating the partial view with the results returned from ToggleLock()?
Is there a way to do it declaratively via Html.ActionLink or Ajax.ActionLink?
The easiest way is to put your partial view in container div like below
<div id="PartialViewDivId">
#{ Html.RenderAction("GetUsersForCompany",model.CompanyId);}
</div>
Then use jQuery to load the updated view
On some click event
var companyId= read company id
var userId= read user id
var url = "mycontroller/ToggleLock?companyId="+companyId+"&userId"+userId;
$("#PartialViewDivId").load(url)
Thanks, Kartikeya. Partial credit for the answer, though I found a declarative way that didn't require manual HTML/event wiring and custom javascript.
The key was simply switching to an Ajax.ActionLink (instead of using Html.ActionLink), then setting my partial view placeholder ID (I had a div setup similar to Kartikeya's example) and a few other parameters in the AjaxOptions of the control, like this:
new WebGridColumn {Header = "Lock",
Format = user => user.isAdmin ? Html.Raw("n/a") :
Ajax.ActionLink( user.IsLocked ? "Unlock" : "Lock",
"ToggleLock",
new{userId = user.Id, companyId = Model.CompanyId },
new AjaxOptions
{
UpdateTargetId="userGridPlaceholder", // <-- my grid placeholder
InsertionMode = InsertionMode.Replace,
HttpMethod = "GET"
})

Telerik MVC Grid Edit Template DropDownList problem

I am getting a null value passed to my ajax .Update("_SaveAjaxEditing", "AptProfile") in my controller when using the dropdownlist client Edit Template.
property in my FormViewModel that my grid is bound to:
[UIHint("BuildingsGrid"), Required]
[DisplayName("Building ID")]
public int BuildingID
{
get;
set;
}).
Here is my view:
<%= Html.Telerik().Grid<PayRent.Models.AptProfileFormViewModel1>()
.Name("Profiles")
.DataKeys(dataKeys => dataKeys.Add(c => c.AptProfileID))
.ToolBar(commands => commands.Insert())
.DataBinding(binding =>
{
binding.Ajax()
.Select("GetProfiles", "AptProfile")
.Insert("_InsertAjaxEditing", "AptProfile")
.Update("_SaveAjaxEditing", "AptProfile")
.Delete("_DeleteAjaxEditing", "AptProfile");
})
.Columns(columns =>
{
columns.Bound(o => o.AptProfileID);
columns.Bound(o => o.BuildingID);
columns.Bound(o => o.AptID);
columns.Bound(o => o.AptRate);
columns.Bound(o => o.AptSize);
columns.Bound(o => o.MoveInDate);
columns.Command(s =>
{
s.Edit();
s.Delete();
});
})
.Editable(editing => editing.Mode(GridEditMode.InLine))
.ClientEvents(events => events.OnEdit("onEdit"))
.Pageable()
%>
</p>
<script type="text/javascript">
function onEdit(e) {
// $(e.form).find('#BuildingsGrid').data('tDropDownList').select(function (dataItem) {
// return dataItem.Text == e.dataItem['BuildingGrid'];
// });
}
</script>
My EditTemplate:
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
<%= Html.Telerik().DropDownList()
.Name("BuildingsGrid")
.BindTo(new SelectList((IEnumerable)ViewData["Buildings"], "BuildingID", "Name"))
%>)
Here is my Controller:
[AcceptVerbs(HttpVerbs.Post)]
//[CultureAwareAction]
[GridAction]
public ActionResult _SaveAjaxEditing(int id, int? BuildingGrid)
{
ApartmentProfileRepository repo = new ApartmentProfileRepository();
AptProfile profile = repo.Get(id);
TryUpdateModel(profile);
repo.Save();
return View(new GridModel(GetAllProfiles()));
}
If you want to keep everything Ajax-ified, you have do it without using the viewbag. My combobox is in a separate editor template. All you have to do is return the SelectList as a JsonResult. That said, I only recommended doing it that way if you expect the data in that combobox to change while the user is on the page, because it calls the server method every time the combo is opened.
In my example below, because the user can add a Category on the same page as they're selecting a Category, I need it to hit the server each time. But on other pages, I use server-side binding (via the ViewBag/ViewData) so that it only hits the server once.
My editor template:
#(Html.Telerik().ComboBox()
.Name("YourNameGoesHere")
.DataBinding(binding => binding.Ajax().Select("SelectCategoriesForComboBox","Shared")))
Then in the controller:
public EquipmentEntities db = new EquipmentEntities();
public List<SelectListItem> CategoryList
{
get
{
var m = db.Categories
.Select(e => new{ Id = e.Id, Name = e.Name })
.OrderBy(e => e.name);
List<SelectListItem> sl = new SelectListItem(m.ToList(), "Id", "Name").ToList();
//insert a blank item as the first entry
sl.Insert(0, (new SelectListItem { Text = "", Value = string.Empty }));
return sl;
}
}
[HttpPost]
public ActionResult SelectCategoryForComboBox()
{
return new JsonResult { Data = CategoryList };
}
Maybe I'm a little bit late, but hopefully it helps someone out.
First, you need to match up the name of your column in the view with the name of your edit template and controller action parameter. I don't think the int parameter needs to be nullable in the controller action.
Then in your controller action you need to set the ViewData["Buildings"] for the edit template; then select the current value in your profile object before returning the view.
e.g.
public ActionResult _SaveAjaxEditing(int id, int BuildingsGrid)
{
ApartmentProfileRepository repo = new ApartmentProfileRepository();
AptProfile profile = repo.Get(id);
// Save the building ID in the profile
profile.BuildingID = BuildingsGrid;
TryUpdateModel(profile);
repo.Save();
// Load the Building objects into the ViewData
ViewData["Buildings"] = GetBuildings();
return View(new GridModel(GetAllProfiles()));
}

Update drop down using Ajax.ActionLink

I am trying to update the dropdown list:
View:
<div class="editor-field">
Names: <%: Html.DropDownList("names", (SelectList)ViewData["Names"]) %>
<%:Ajax.ActionLink("Refresh", "GetNames", new AjaxOptions { UpdateTargetId = "names", HttpMethod = "GET" })%>
</div>
Controller:
[HttpGet]
public ActionResult GetNames()
{
List<String> names = this.GenerateNames();
return Json(new SelectList(names));
}
The flow is the following: when user makes the first request, the list is updated from viewdata, then user presses refresh and the dropdown is populated usin ajax request.
I tried to return both JSON result - the dropdown is not updated. When returning SelectList the dropdown just gets cleared.
How can I accomplish this task?
You could put this drop down into a partial (Names.ascx):
<%# Control Language="C#"
Inherits="System.Web.Mvc.ViewUserControl<YourApp.Models.SomeViewModel>" %>
Names: <%: Html.DropDownList(x => x.SelectedName, Model.Names) %>
And then in your main view use this editor template:
<div class="editor-field">
<span id="names"><% Html.RenderPartial("Names"); %></span>
<%: Ajax.ActionLink("Refresh", "Names",
new AjaxOptions { UpdateTargetId = "names", HttpMethod = "GET" }) %>
</div>
And you controller action could look like this:
public ActionResult Names()
{
var model = new SomeViewModel
{
// TODO: fetch the names from db:
Names = new SelectList(new[] {
new { Id = "1", Text = "name 1" },
new { Id = "2", Text = "name 2" },
new { Id = "3", Text = "name 3" },
}, "Id", "Text")
}
return View(model);
}
Just update the viewdata again so the view can use the same code to update itself for the second shot, being the Ajax return. And u don't need to use Json for that. Let me know how it goes.

Resources