we have a project (SmartAdmin template to be specific) where we are trying to reload the data in the partial view for the table on certain actions by users. I just can't quite figure out what to do with this with the setup we started with.
Datatable initialization code -
function setupInProgressTable(tabletSize, phoneSize) {
/* Data Tables */
var responsiveHelper_in_progress = undefined;
var breakpointDefinition = {
tablet: Number(tabletSize),
phone: Number(phoneSize)
};
/* In Progress */
$('#in_progress').dataTable({
"sDom": "<'dt-toolbar'<'col-xs-12 col-sm-6'f><'col-sm-6 col-xs-6 hidden-xs'C>r>" +
"t" +
"<'dt-toolbar-footer'<'col-sm-6 col-xs-12 hidden-xs'i><'col-xs-12 col-sm-6'p>>",
"autoWidth": true,
"preDrawCallback": function () {
// Initialize the responsive datatables helper once.
if (!responsiveHelper_in_progress) {
responsiveHelper_in_progress = new ResponsiveDatatablesHelper($('#in_progress'), breakpointDefinition);
}
},
"rowCallback": function (nRow) {
responsiveHelper_in_progress.createExpandIcon(nRow);
},
"drawCallback": function (oSettings) {
responsiveHelper_in_progress.respond();
},
"order": [[2, "asc"]]
});
}
MVC Controller action that builds up data and sends it to the partial
// GET: Tier2/InProgressTable
/// <summary>
/// Gets data to supply to the In Progress Table on draw
/// </summary>
/// <returns>ActionResult - _InProgressTable Partial View</returns>
[Authorize(Roles = "Tier2.Issues.Edit.All")]
public ActionResult InProgressTable()
{
var results = _api.Tier2.Issues.GetTier2Issue(resolved: false);
List<Tier2IssuesViewModel> viewModel = new List<Tier2IssuesViewModel>();
if (results.message == null)
{
// Get the corresponding issues for this table
var statuses = new int[] { 2, 4 };
var issues = results.data.Where(i => statuses.Contains(int.Parse(i.IssueStatus.id.ToString())));
// Set items for the view model
foreach (var item in issues)
{
var theIssueStatusList = GetIssueStatusList(); // Build up data for IssueStatusList
Tier2IssuesViewModel theModel = new Tier2IssuesViewModel();
theModel.Issue = item;
theModel.IssueStatusList = theIssueStatusList;
if (theModel.Issue.IssueStatus != null)
theModel.IssueStatusList.Where(m => m.Value == theModel.Issue.IssueStatus.id.ToString()).First().Selected = true;
viewModel.Add(theModel);
}
return PartialView("_InProgressTable", viewModel);
}
else
{
ModelState.AddModelError("", results.message);
}
return PartialView("");
}
Any ideas on where I should head with this?
In a nutshell, just change the way you populate the datatable. Instead of passing the data in a ViewModel, you can use the datatables API to populate it using Ajax.
A simple example:
The Controller method can be simplified as it's not handling any data:
public ActionResult InProgressTable()
{
return View();
}
Your View just needs an empty table:
<table id="in_progress">
<thead>
<tr>
<th>Id</th>
<th>Name</th>
</tr>
</thead>
<tbody></tbody>
</table>
You need a new Controller method that returns the data as json:
public ActionResult PopulateInProgressTable()
{
var results = _api.Tier2.Issues.GetTier2Issue;
// read into object array
var result = from r in results
select new object[]
{
r.Id,
r.Title
};
// Get the sEcho param
var _sEcho = request.QueryString["sEcho"];
// return data to datatable
return Json(new
{
_sEcho,
iTotalRecords = result.Count(),
iTotalDisplayRecords = result.Count(),
aaData = result
}, JsonRequestBehavior.AllowGet);
}
A few things to note here - datatables expects the json data in a specific format, so create a json object with the properties named as in the above example. sEcho is a parameter send in the request, you are simply returning it unaltered. iTotalRecords and iTotalDisplayRecords are used for paging, aaData is the actual data.
Finally you initialise the datatable in your javascript:
var oTable = $('#in_progress').DataTable({
'serverSide': true,
"ajax": {
"url": [your url] + '/PopulateInProgressTable'
},
'processing': true,
'columns': [
{
'data': 0
},
{
'data': 1
}
});
This needs to run after the partial view is created otherwise the table won't exist when the datatables initialisation code runs.
As mentioned earlier, this is a very simple example but it should be enough to get you started.
You need to set up the initial configuration in your partial view code. The data will need to be applied in a separate endpoint call.
To define the initial UI
return PartialView();
To return Data to your grid
return Json(Something.GetData(),JsonBehavior.AllowGet);
To setup the initial state of your PartialView and initially bind data, you should tie into the page load event and this is usually done in the jquery.load() function defined in your PartialView.
When your partial loads, make sure that you call a controller method to return data to your grid. You may also want to add a parameter to your grid data function to indicate user's intent? However, you can load and reload your grid by binding your grid to the result of a client side ajax function that returns the json payload.
success(data) { bindGrid(data); }
Related
This is similar to a previous issue that was resolved earlier. In this case, instead of rendering a table in the same view, I'd like to take the data retrieved and push to a new view:
Populate child area paths in a multiselect dropdown list
Select some of the items in the dropdown list
Take the selected items (as area path children) send back to controller
From controller use area paths as parameters to a method retrieving work items
Take workitem list and populate list in new view
Here is my view script
function GetSelectedAreaPathChildren3() {
alert("TEST1");
var selectedAreaPathItems = '';
$("#AreaPathMultiSelectDropdownList :selected").each(function () {
selectedAreaPathItems += this.value + ";";
});
var selectedIterationPathItems = '';
$("#IterationPathMultiSelectDropdownList :selected").each(function () {
selectedIterationPathItems += this.value + ";";
});
console.log(selectedAreaPathItems);
$.ajax({
url: '#Url.Action("WorkItemTable", "PbcAzureDevOps")',
type: "POST",
data: { selectedAreaPathItems, selectedIterationPathItems },
success: function () {
alert("BLAH!");
}
});
}
Here is my controller method
public async Task<IActionResult> WorkItemTable(string selectedAreaPathItems, string selectedIterationPathItems)
{
//Get the retrieved work items
List<WorkItemInfo> retrievedWorkItems =
await GetAllSelectedWorkItems(selectedAreaPathItems, selectedIterationPathItems);
return View(retrievedWorkItems);
}
Expected result:
retrievedWorkItems is populated and sent to view ("WorkItemTable") -- after sending to view, "WorkItemTable is shown on screen
Actual result:
retrievedWorkItems is populated and sent to view ("WorkItemTable") -- after sending to view, "WorkItemTable is NOT SHOWN (i.e. WorkItemTable does not pop up)
I recognize from my research that I can't get the view to show up from the script and have also tried adding the following to the view:
#using (Html.BeginForm("WorkItemTable", "PbcAzureDevOps", FormMethod.Post))
{
}
Can anyone help me to get the WorkItemTable to render... I can already see the data in the foreach part of the view, it just doesn't show.
So I figured a workaround... instead of pulling the selections from the dropdownlists using Ajax, I pulled the data from the dropdown via IFormCollection:
public async Task<IActionResult> WorkItemTable(IFormCollection collection)
{
List<string> selectedAreaPathItems = collection["apchildrenDropDown"].ToList();
List<string> selectedIterationPathItems = collection["ipchildrenDropDown"].ToList();
//Get the retrieved work items
List<WorkItemInfo> retrievedWorkItems =
await GetAllSelectedWorkItems(selectedAreaPathItems, selectedIterationPathItems);
return View(retrievedWorkItems);
}
In my web site I'm getting data from xml in first controller action method and display as dropdown (html select and option).When a user selects an item in first dropdown, selected item sent to the next view's controller as a parameter using jquery $.post. I have keep breakpoints and see what is going on. Data trasfer is success until second view . But display nothing. I have attached screenshot of my break points and codes.
This is my controllers.
public ActionResult First()
{
//get the location data
var Loc = getData("Location", "", "", "");
List<FirstData> Ilc = new List<FirstData>();
foreach(var val in Loc)
{
Ilc.Add(new Firstdata
{
Destination = val
});
}
ViewBag.Loc = Ilc;
return View();
}
this is how I pass data from first view to second action controller method
<script type:"text/javascript">
$(document).ready(function() {
$("#chk a").addCIass("btn btn-default");
$("#chk a").click(function () {
var url = '#Url.Action("Check","Cruise")';
$.post(url, { LocNane: $("#desti").val() }, function (data) {
//alert("succes");
});
});
});
</script>
this is how my second controller gets pass data[I made a breakpoint here]
public ActionResult Check(string LocName)
{
string d = LocNane;
var Nan = getData('Location',"Name",d,"");
List<Seconddata> nf = new List<Seconddata>();
foreach (var val in Nam)
{
nf.Add(new Seconddata
{
Naneof = val
});
}
ViewBag.Nn = nf;
}
and this is my second view and display data in break point
<body>
<div>
#foreach( var item in #VieuBag.Nm)
{
<h3>one</h3>
}
</div>
</body>
I put "#item.Nameof" inside the header tags , but it didn't work. so just to chek I put one. after go through the loop nothing display.what's the wrong.please help me with this.
The problem here is the success handler of $.post does not append/insert the returned html in any element. You can do something like this in success handler where divId is element Id in page where you want to show the returned html.
$("#divId").append(data);
I am new to both MVC and AngularJs so please excuse me if this is a stupid question. I have a dropdownlist in an Asp.net MVC View that is populated using AngularJs. When the user selects a Company in the dropdown list, I use the companyId to populate an unordered list. My problem, I need to use that same selected CompanyID in another controller and C# method. I have found some info on saving data in a service to reuse it, but I'm not sure if that is what I really need here (or if there is a simpler way to do it than creating a service), but if it is, I don't know how to save the value in a service.
Here is my View code:
{{company.vchCompanyName}}
Current Dashboard Modules:
{{m.vchRankingWidgetModuleHeaderText}}
Here is my Angular Controller code:
myApp.controller("CompanyController",
function($scope, $timeout, companyService)
{
getCompanies();
function getCompanies() {
companyService.getCompanies()
.success(function (data) {
$scope.companies = data;
})
.error(function (error) {
$scope.status = 'Unable to load customer data: ' + error.message;
});
};
$scope.getCurrentModules = function(){
companyId = $scope.company;
companyService.getCurrentModules(companyId)
.success(function (newdata){
$scope.currentModules = newdata;
});
}
});
Here is my Angular Service:
angular.module('dashboardManagement')
.service('companyService', ['$http', function ($http) {
this.getCompanies = function () {
return $http.get('/Home/GetAllCompanies');
};
this.getCurrentModules = function (id) {
return $http.get('/Home/GetCurrentModules?companyId=' + id);
};
}
]);
Any assistance is greatly appreciated!
I tried using the Service but I cannot get it to work. I need to show Business Units for a company if the Business Units checkbox is checked. I put the function "getBusinessUnits" on the ng-checked and tried to use the service to retrieve the CompanyID. My View looks like this:
<div ng-controller="BusinessUnitsController">
<input id="ckBusinessUnit" type="checkbox" ng-checked="getBusinessUnits()"/>Exclude by Business Units<br />
<ul>
<li ng-repeat="unit in businessUnits">{{unit.Description}}</li>
</ul>
</div>
My Controller looks like this:
myApp.controller("BusinessUnitsController",
function ($scope, $timeout, companyService) {
$scope.getBusinessUnits = function () {
companyId = companyService.selectedCompanyId;
companyService.getBusinessUnits(companyId)
.success(function (data) {
$scope.businessUnits = data;
});
};
});
The code in the Service is exactly as you suggested:
angular.module('dashboardManagement')
.service('companyService', [
'$http', function ($http) {
this.selectedCompanyId = null;
this.getCompanies = function () {
return $http.get('/Home/GetAllCompanies');
};
this.getCurrentModules = function (companyId) {
this.selectedCompanyId = companyId;
return $http.get('/Home/GetCurrentModules?companyId=' + companyId);
};
this.getBusinessUnits = function (companyId) {
return $http.get('/Home/GetBusinessUnits?companyId=' + companyId);
}
}
]);
I'm obviously missing something.
The CompanyService can be used to stock a selectedCompanyId as a property.
angular.module('dashboardManagement')
.service('companyService', ['$http', function ($http) {
this.selectedCompanyId = null;
this.getCompanies = function () {
return $http.get('/Home/GetAllCompanies');
};
this.getCurrentModules = function (companyId) {
this.selectedCompanyId = companyId;
return $http.get('/Home/GetCurrentModules?companyId=' + companyId);
};
}]);
Then you can access the selectedCompanyId everywhere in your others controller/directive by injecting companyService.
Note that it is like a Singleton with a single instance, so you can have only one selected company for your whole angular application.
if I understand well you need to save the select companyId in your View and then pass it to your controller(c#) right?
try this, add a new property in your angularjs controller
$scope.SelectedCompanyId = '';
then in your dropdownlist add this attribute
ng-model="SelectedCompanyId"
then add a new hidden input
<input type="hidden" name="CompanyId" value="{{SelectedCompanyId}}" />
now if in the model that are you using in your view have a property CompanyId, when you do the post back it will map the value, or just in your controller add a new parameter
[HttpPost]
public ActionResult YourActionName(YourModel model, int? CompanyId)
{
//you can access to the CompanyId
//int? CompanyId --> this is only if your model doesn't have a property called CompanyId
}
How can I update a dropdownlist in MVC3. I want to refill it with latest data filled by some other view, but I do not want to postback the view and want to achieve it with jquery.
I have a dropdownlist like:
#Html.DropDownListFor(m => m.Department, Model.Departments)
#Html.ValidationMessageFor(m => m.Departments)
<input type="button" value="Refresh" id="btnrefresh" />
I have written jquery code to call controller's method:
$("#btnrefresh").click(function () {
var ref = '#Url.Action("RefreshDepartments")';
var model = '#Model.ToJson()';
var data = { empModel: model };
$.getJSON(ref, data, function (result) { alert(result.message); });
return false;
});
And Here is the controller method:
public ActionResult RefreshDepartments(EmployeeModel empModel)
{
empModel.Departments = GetDepartments();
empModel.Roles = GetRoles();
return Json(new { message = "Updated successfully"}, JsonRequestBehavior.AllowGet);
}
How can I update the dropdownlist with latest values on clicking "Refresh" button without any postback?
Is it a good idea to pass the model to the controller and update the model properties? What other ways are possible ?
It doesn't look to me like you need the model to be posted to your controller for what you're doing. In addition, yes, you absolutely can do this with jquery! On a side note, you could also do it with an Ajax.BeginForm() helper method, but lets deal with your jquery example.
Rather than complexify your jquery with your #Url.Action, you can simply call the path itself.
$("#btnrefresh").click(function () {
var ref = 'ControllerName/RefreshDepartments';
$.each(result, function (index, val) {
$('#whateverYourRenderedDropdownListHtmlObjectis')
.append($("<option></option>")
.attr("value", val.Text)
.text(val.Text));
});
});
Now, for your controller...
public JsonResult RefreshDepartments()
{
return Json(GetDepartments, JsonRequestBehavior.AllowGet);
}
private SelectList GetDepartments
{
var deparments = GetDepartments;
SelectList list = new SelectList(departments);
return list;
}
This is an alternative to returning the model. It allows you to manipulate the raw JSON instead. Hope it helps!
You almost did it all! Why don't you send the data, I mean list, by RefreshDepartments action? You sent a message to view, so you can send the list similarly and instead of alerting the result you can fill the dropdownlist. something like this:
public ActionResult RefreshDepartments(EmployeeModel empModel)
{
return Json(new { departments = GetDepartments()}, JsonRequestBehavior.AllowGet);
}
$.getJSON(ref, data, function (result) {
$("#Department").html("");
for (var i = 0; i < result.departments.length; i++) {
var item = result.departments[i];
$("#Department").append(
$("<option></option>").val(item.Id).html(item.Name);
);
});
});
I've a method in a NamesModel which fetches all the names and returns a list of names:
public static List<NamesModel> GetAllNames()
{
List<NamesModel> names = new List<NamesModel>();
//
// code to fetch records
//
return names;
}
In my controller:
public ActionResult Index()
{
NamesModel model = new NamesModel();
model.GetAllNames();
return View(model);
}
In the view, I've got a textbox:
#Html.TextBox("search-name")
Now in my javascript, I want to fetch all names into a variable either from a model (from method) or from controller, for example:
<script type="text/javascript">
$(function () {
var names = ...........
$(document).ready(function () {
$('#search-name').autocomplete({
source: names
});
});
});
</script>
If I use hardcoding then it works but I want to use the names stored in the db. Is it possible?
hardcoding example:
var names = ["abc", "xyz"];
You could use Ajax and Json for this
For your controller:
[HttpPost]
public JsonResult GetAllNames()
{
List<NamesModel> names = new List<NamesModel>();
//
// code to fetch records
//
return Json(names);
}
Or for debugging so you can view the json in browser:
public JsonResult GetAllNames()
{
List<NamesModel> names = new List<NamesModel>();
//
// code to fetch records
//
var result = Json(names);
result .JsonRequestBehavior = JsonRequestBehavior.AllowGet;
return result ;
}
(note this is actually jquery but since you use document.ready you've allready included jquery)
in your javascript make a call to the method above:
$.getJSON(#Url.Content("~/ControllerName/GetAllNames/"), function (result) {
var ListWithNames = data;
});
The "source" options property can be a string wich points to the URL which return json data (http://api.jqueryui.com/autocomplete/#option-source)
The best solution to my problem is in this blog: http://theycallmemrjames.blogspot.co.uk/2010/03/jquery-autocomplete-with-aspnet-mvc.html
Thanks to everyone who tried to help me.