How to prefilter a jQuery DataTable? - c#

I need to create a datatable that only displays records that have only one Activity Phase equal to "Waiting". Currently, the following solution displays all records, some of which have multiple Activity Phases. The first Activity Phase in the workflow is "Waiting".
Actions:
public JsonResult LoadWaitList()
{
return Json(new { data = GetWaitList() }, JsonRequestBehavior.AllowGet);
}
private IEnumerable GetWaitList()
{
var waitList = from a in _db.Applications
select new
{
a.AppNumber, ApplicationType = a.ApplicationType.Label,
ActivityPhases = a.ApplicationActivityPhas.Select(p => p.ActivityPhas.ActivityPhase).ToList(),
a.Id
};
return waitList;
}
DataTable:
$("#WaitListDataTable").DataTable({
ajax: {
url: '#Url.Action("LoadWaitList", "Application")',
datatype: "json",
type: "GET"
},
columns: [
{
data: "AppNumber",
render: function (data, type, row) {
var applicationDetails = '#Url.Action("Details", "Application")/' + row.Id;
return '' + data + '';
}
},
{ data: "ApplicationType" },
{ data: "ActivityPhases" },
{ data: "Id" }
]
});
Index Table:
<div class="pt-2">
<table class="table table-bordered table-sm" id="WaitListDataTable">
<thead class="table-info">
<tr>
<th>Application Number</th>
<th>Application Type</th>
<th>Activity Phase</th>
<th>Id</th>
</tr>
</thead>
</table>
</div>

Since "Waiting" is the first activity phase in the workflow, to display application records that only have one activity phase equal to "Waiting", I added the following:
public JsonResult LoadWaitList()
{
return Json(new { data = GetWaitList() }, JsonRequestBehavior.AllowGet);
}
private IEnumerable GetWaitList()
{
var waitList = (from a in _db.Applications
select new
{
a.AppNumber, ApplicationType = a.ApplicationType.Label,
ActivityPhases = a.ApplicationActivityPhas.Select(p => p.ActivityPhas.ActivityPhase).ToList(),
a.Id
}).Where(p => p.ActivityPhases.Count() == 1);
return waitList;
}

Related

How to split list of values in a jQuery datatable?

I have a datatable that includes a column that has a list of values. For example, Activity Phase Dates has a list of comma-separated dates. I cannot use render: function (data) { return moment(data).format("MM/DD/YYYY"); because a list of dates is not a valid date.
How can I split this list of dates to then apply render: function (data) { return moment(data).format("MM/DD/YYYY");? I have tried split(','), but it does not work. Most likely because this list of values is not a string. I also tried replace(',', ' '), but also did not work for probably the same reason.
Actions:
public JsonResult LoadApplications()
{
return Json(new { data = GetApplications("") }, JsonRequestBehavior.AllowGet);
}
private IEnumerable GetApplications(string keyword)
{
var applications = from a in _db.Applications
where a.AppNumber.ToString().Contains(keyword)
|| a.NonCityMortgageDate.ToString().Contains(keyword)
|| a.ApplicationActivityPhas.Any(d => d.ActivityPhaseDate.ToString().Contains(keyword))
select new
{
a.AppNumber, a.NonCityMortgageDate,
ActivityPhaseDates = a.ApplicationActivityPhas.Select(d => d.ActivityPhaseDate).ToList(),
a.Id
};
return applications;
}
DataTable:
$(document).ready(function () {
$("#ApplicationDataTable").DataTable({
ajax: {
url: '#Url.Action("LoadApplications", "Application")',
datatype: "json",
type: "GET"
},
columns: [
{
data: "AppNumber",
render: function (data, type, row) {
var applicationDetails = '#Url.Action("Details", "Application")/' + row.Id;
return '' + data + '';
}
},
{
data: "NonCityMortgageDate",
type: "date",
render: function (data) {
if (data != null) {
return moment(data).format("MM/DD/YYYY");
}
else {
return "";
}
}
},
{
data: "ActivityPhaseDates",
type: "date",
render: function (data) {
return moment(data).format("MM/DD/YYYY");
}
},
{ data: "Id" }
]
});
});
Index:
<div class="pt-2">
<table class="table table-bordered table-sm" id="ApplicationDataTable">
<thead class="table-info">
<tr>
<th>Application Number</th>
<th>Non City Mortgage Date</th>
<th>Activity Phase Dates</th>
<th>Id</th>
</tr>
</thead>
</table>
</div>
The following is a solution:
{
data: "ActivityPhaseDates",
render: function (data) {
var activityPhaseDates = "";
for (var i = 0; i < data.length; i++) {
activityPhaseDates += moment(data[i]).format("MM/DD/YYYY") + " ";
}
return activityPhaseDates;
}
}
The output is:
03/14/2022 03/31/2022 03/31/2022 03/31/2022 03/31/2022

Unable to display data for jQuery Datatable with server side processing

I face the issue with jQuery Datatable server-side processing in ASP.NET Core 3.1. Server-side returns data as JSON but it is not displaying in Datatable.
Below is my controller side code
public IActionResult LoadData()
{
var dict = Request.Form.ToDictionary(x => x.Key, x => x.Value.ToString());
var draw = dict["draw"];
var start = dict["start"];
var length = dict["length"];
////Find Order Column
var sortColumn = "Company";
var sortColumnDir = "asc";
int pageSize = length != null ? Convert.ToInt32(length) : 0;
int skip = start != null ? Convert.ToInt32(start) : 0;
DataSet ddata = GenralClass.GetCRMTestData((Convert.ToInt32(draw)-1)*100, 100);//GetCRMData();
ddata.Tables[0].TableName = "data";
var data = ddata;
int recordsTotal = 34790;
var jsonData = new { draw = draw, recordsFiltered = recordsTotal, recordsTotal = recordsTotal, data = data };
return Ok(JsonConvert.SerializeObject(jsonData));
}
Below is my view side code
<table class="table table-striped table-bordered table-hover dataTables-example">
<thead>
<tr>
<th style="white-space: nowrap;">Company</th>
<th style="white-space: nowrap;">Assignedto</th>
<th style="white-space: nowrap;">Provider</th>
</tr>
</thead>
</table>
Below is my Jquery Code.
$(document).ready(function () {
$('.dataTables-example').DataTable({
pageLength: 100,
processing: true,
serverSide: true,
ajax: {
url: '#Url.Action("LoadData", "SKU")',
type: 'POST',
dataType: "json",
columns: [
{ "data": "Company" },
{ "data": "Assignedto" },
{ "data": "Provider" },
]
}
});
});
I made some changes in startup.cs file in service configuration as below
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews()
.AddNewtonsoftJson(options =>
{
options.SerializerSettings.Converters.Add(new StringEnumConverter());
});
services.AddControllers();
services.AddRazorPages();
services.AddDbContext<AppDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("AppDb")));
}
No error display when page load just empty table. I verify from the chrome network that data is returning from the server-side as the data attached below. I don't know what is wrong why the data is not showing. The paging number showing correct but the data is not showing. Any help.
{
"draw":"1",
"recordsFiltered":34790,
"recordsTotal":34790,
"data":{
"data":[
{
"Company":"SHAN FOODS (PVT) LTD",
"Assignedto":"Stock-Transfer",
"Provider":"Stock-Transfer"
},
{
"Company":"SHAN FOODS (PVT) LTD",
"Assignedto":"Vermicelli (150gm)",
"Provider":"030180010017"
}
]
}
}
You can change your code as follows.
LoadData:
public IActionResult LoadData()
{
//...
var jsonData = new { draw = draw, recordsFiltered = recordsTotal, recordsTotal = recordsTotal, data = data };
return new JsonResult(new {json = jsonData });
}
Jquery:
$(document).ready(function () {
$.ajax({
type: "POST",
url: "/SKU/LoadData",
data: '{}',
contentType: "application/json; charset=utf-8",
dataType: "json",
success: OnSuccess,
});
});
function OnSuccess(response) {
$('.dataTables-example').DataTable(
{
data: response.json.data,
columns: [
{ "data": "company" },
{ "data": "assignedto" },
{ "data": "provider" },
],
});
};
Test result:
Change your json like below
{
"draw":"1",
"recordsFiltered":34790,
"recordsTotal":34790,
"data":[
{
"Company":"SHAN FOODS (PVT) LTD",
"Assignedto":"Stock-Transfer",
"Provider":"Stock-Transfer"
},
{
"Company":"SHAN FOODS (PVT) LTD",
"Assignedto":"Vermicelli (150gm)",
"Provider":"030180010017"
}
]
}

not refreshing data in angular js

I write a web in mvc framework with angular js.
my application is:
var app = angular.module("AngularApp", []);
and my controller is:
app.controller("EmpCtrl", function ($scope, EmployeeService) {
GetAllEmployee();
function GetAllEmployee() {
var getAllEmployee = EmployeeService.getEmployee();
getAllEmployee.then(function (emp) {
$scope.employees = emp.data;
}, function () {
alert('data not found');
});
}
$scope.deleteEmployee = function (id) {
var getData = EmployeeService.DeleteEmp(id);
getData.then(function (msg) {
GetAllEmployee();
alert('Employee Deleted...');
$scope.h1message = true;
$scope.message = "ED";
}, function () {
$scope.h1message = true;
$scope.message = "Error in Deleting Record";
});
}
});
and my service is:
app.service("EmployeeService", function ($http) {
this.getEmployee = function () {
debugger;
return $http.get("/EmployeeModels/GetAllEmployee");
};
//Delete Employee
this.DeleteEmp = function (employeeId) {
var response = $http({
method: "post",
url: "/EmployeeModels/deleteEmployee",
params: {
employeeId: JSON.stringify(employeeId)
}
});
return response;
}
});
and my mvc action is :
private ApplicationDbContext db = new ApplicationDbContext();
public JsonResult GetAllEmployee()
{
using (ApplicationDbContext db = new ApplicationDbContext())
{
var employeeList = db.EmployeeModels.ToList();
return Json(employeeList, JsonRequestBehavior.AllowGet);
}
}
//DeleteEmployee
public string DeleteEmployee(string employeeId)
{
if (employeeId != null)
{
int no = Convert.ToInt32(employeeId);
var employeeList = db.EmployeeModels.Find(no);
db.EmployeeModels.Remove(employeeList);
db.SaveChanges();
return "Employee Deleted";
}
else { return "Invalid Employee"; }
}
and html file is:
<div ng-app="AngularApp" ng-init="name='hn';backGroundColor='red';
person={firstname:'jo',lastname:'hary'}">
<div ng-controller="EmpCtrl">
<table border="1" width="100%">
<tr>
<th ng-click="orderByMe('emp.EmployeeId')">employee id</th>
<th ng-click="orderByMe('Address')">addres</th>
<th ng-click="orderByMe('EmailId')">email id</th>
<th ng-click="orderByMe('EmployeeName')">employee name</th>
</tr>
<tr ng-repeat="emp in employees|orderBy:orderByMe">
<td> {{emp.EmployeeId}}</td>
<td> {{emp.Address}}</td>
<td>{{emp.EmailId}}</td>
<td>{{emp.EmployeeName}}</td>
<td><a data-ng-click="deleteEmployee(emp.EmployeeId)" style="cursor:pointer;">delete</a></td>
</tr>
</table>
</div>
the view of data is ok. but when I add record to table of database, view not refresh data?
Your view not refresh data because, your method GetAllEmployee() is called once, at the loading of page. you need to refresh your page.

Table not refreshing using ajax

I an experimenting with MVC. I have a view which contains a dropdownlist and a table.
When I select an option from the dropdownlist, I want to get the data from my controller and update the view:
View:
<div>
<h2>Current Print Statistics</h2>
#using (Html.BeginForm())
{
#Html.DropDownList("LogTypes", new SelectList(Model.LogTypes, "Value", "Text"), new
{
id = "logType",
data_url = Url.Action("GetStatistics", "Home")
})
<table id="modelTable" class="table table-condensed">
<tr>
<th>RequestedOn</th>
<th>PrintedOn</th>
<th>Message</th>
<th>Success</th>
<th>TemplateName</th>
</tr>
<tbody>
#foreach (var item in Model.PrintLogs)
{
string css = (item.Success) ? "success" : "danger";
string link = (item.Success) ? "www.google.com" : string.Empty;
<tr class="#css">
<td>#item.RequestedOn</td>
<td>#item.PrintedOn</td>
<td>#item.Message</td>
#if (item.Success)
{
<td>#item.Success</td>
}
else
{
<td>#Html.ActionLink("False", "Index", "LogView", new { id = item.LogID }, null)</td>
}
<td>#item.TemplateName</td>
</tr>
}
</tbody>
</table>
}
</div>
</div>
<script src="~/Scripts/jquery-1.10.2.js"></script>
<script type="text/javascript">
$(function () {
$('#logType').change(function () {
console.log($(this).data('url'));
var selectedValue = $(this).val();
var table = $('#modelTable');
$.ajax({
url: $(this).data('url'),
type: 'GET',
cache: false,
context: table,
data: { value: selectedValue },
success: function (result) {
$.each(result.PrintLogs,
function (index, log) {
$('<tr/>', {
html: $('<td/>', {
html: log.RequestedOn
}).after($('<td/>', {
html: log.PrintedOn
})).after($('<td/>', {
html: log.Success
})).after($('<td/>', {
html: log.Message
})).after($('<td/>', {
html: log.TemplateName
}))
}).appendTo(tableBody);
}
);
}
});
});
});
</script>
Controller:
[HttpGet]
public JsonResult GetStatistics(string value)
{
var request = LogTypeRequest.Last24H;
if (value == "0") request = LogTypeRequest.Last24H;
if (value == "1") request = LogTypeRequest.LastWeek;
if (value == "2") request = LogTypeRequest.LastMonth;
var model = new PrintServerModel
{
LogTypes = new List<ListItem>
{
new ListItem() {Text = "Last 24 Hours", Value = "0"},
new ListItem() {Text = "Last Week", Value = "1"},
new ListItem() {Text = "Last Month", Value = "2"}
},
PrintLogs = PrintServerService.GetPrinterLog(request)
};
return Json(model, JsonRequestBehavior.AllowGet);
}
Now when I try to debug in chrome, when the line $.ajax({ is reached it seems to jump to the end.
Ideally what I want is to display the data on start up and then when the user selects something from the dropdown, refresh the data.
Any help greafully appreciated!!
Odds are there is an error from the json call, you should add .done or error: to the end of it so you can see what your error is.
also there is a tab in chrome debug tool for watching the network calls, you may be able to see the response from the call in there with some additional details.
just looking over the ajax call, may want to change to have
data: JSON.stringify( { value: selectedValue }),
if you get more info i will do what i can to better my answer.

on select change event - Html.DropDownListFor

I have two dropdownlist. The selected value from the first one loads the other. How do I do that when I have the helper methods in a controller?
#using (Html.BeginForm())
{
<div>
<table width="100%" cellpadding="0" cellspacing="0">
<tr>
<td><b>Select a District:</b></td>
<td>#Html.DropDownListFor(m => m.DistrictId, ViewData["DMManagers"] as IEnumerable<SelectListItem>, "Select One")</td>
</tr>
<tr>
<td><b>Select a TM:</b></td>
<td>#Html.DropDownListFor(m => m.TMId, ViewData["TMManagers"] as IEnumerable<SelectListItem>, "Select One")</td>
</tr>
</table>
</div>
}
private void LoadDistrictManagers()
{
var _DMS = (from c in SessionHandler.CurrentContext.ChannelGroups
join cgt in SessionHandler.CurrentContext.ChannelGroupTypes on c.ChannelGroupTypeId equals cgt.ChannelGroupTypeId
where cgt.Name == "District Manager"
select new { c.ChannelGroupId, c.Name }).OrderBy(m => m.Name);
ViewData["DMManagers"] = new SelectList(_DMS, "ChannelGroupId", "Name");
}
private void LoadTerritoryManagers(int districtId)
{
var _TMS = (from c in SessionHandler.CurrentContext.ChannelGroups
join cgt in SessionHandler.CurrentContext.ChannelGroupTypes on c.ChannelGroupTypeId equals cgt.ChannelGroupTypeId
where cgt.Name == "Territory" && c.ParentChannelGroupId == districtId
select new { c.ChannelGroupId, c.Name }).OrderBy(m => m.Name);
ViewData["TMManagers"] = new SelectList(_TMS, "ChannelGroupId", "Name");
}
public ActionResult SummaryReport()
{
DistrictManagerModel model = new DistrictManagerModel();
LoadDistrictManagers();
return View("AreaManager", model);
}
Give both dropdowns unique IDs using the HTTPAttributes field:
#Html.DropDownListFor(m => m.DistrictId, ViewData["DMManagers"] as IEnumerable<SelectListItem>, "Select One", new {#id="ddlDMManagers"})
2nd dropdown should be initialized as an empty list:
#Html.DropDownListFor(m => m.TMId, Enumerable.Empty<SelectListItem>(), new {#id="ddlTMManagers"})
If you don't mind using jQuery ajax to update the 2nd dropdown when a 'change' event is triggered on the 1st dropdown:
$(function() {
$('select#ddlDMManagers').change(function() {
var districtId = $(this).val();
$.ajax({
url: 'LoadTerritoryManagers',
type: 'POST',
data: JSON.stringify({ districtId: districtId }),
dataType: 'json',
contentType: 'application/json',
success: function (data) {
$.each(data, function (key, TMManagers) {
$('select#ddlTMManagers').append('<option value="0">Select One</option>');
// loop through the TM Managers and fill the dropdown
$.each(TMManagers, function(index, manager) {
$('select#ddlTMManagers').append(
'<option value="' + manager.Id + '">'
+ manager.Name +
'</option>');
});
});
}
});
});
});
Add this class to your controller namespace:
public class TMManager
{
public int Id {get; set;}
public string Name {get; set;}
}
You will need to update your controller action, LoadTerritoryManagers(), to respond to the ajax request and return a JSON array of {Id,Name} objects.
[HttpPost]
public ActionResult LoadTerritoryManagers(int districtId)
{
var _TMS = (from c in SessionHandler.CurrentContext.ChannelGroups
join cgt in SessionHandler.CurrentContext.ChannelGroupTypes on c.ChannelGroupTypeId equals cgt.ChannelGroupTypeId
where cgt.Name == "Territory" && c.ParentChannelGroupId == districtId
select new TMManager(){ Id = c.ChannelGroupId, Name = c.Name }).OrderBy(m => m.Name);
if (_TMS == null)
return Json(null);
List<TMManager> managers = (List<TMManager>)_TMS.ToList();
return Json(managers);
}
Use the following code. It is used in my project. For Zone and Region I used two drop-down list. On change Zone data I loaded the Region drop-down.
In View page
#Html.DropDownList("ddlZone", new SelectList(#ViewBag.Zone, "Zone_Code", "Zone_Name"), "--Select--", new { #class = "LoginDropDown" })
#Html.DropDownList("ddlRegion", Enumerable.Empty<SelectListItem>(), new { #class = "LoginDropDown" })
The Zone need to load when the view page is load.
In the controller write this method for Region Load
[WebMethod]
public JsonResult LoadRegion(string zoneCode)
{
ArrayList arl = new ArrayList();
RASolarERPData objDal = new RASolarERPData();
List<tbl_Region> region = new List<tbl_Region>();
region = erpDal.RegionByZoneCode(zoneCode);
foreach (tbl_Region rg in region)
{
arl.Add(new { Value = rg.Reg_Code.ToString(), Display = rg.Reg_Name });
}
return new JsonResult { Data = arl };
}
Then use the following JavaScript
<script type="text/javascript">
$(document).ready(function () {
$('#ddlZone').change(function () {
LoadRegion(this.value);
});
function LoadRegion(zoneCode) {
$.ajax({
type: "POST",
url: '#Url.Action("LoadRegion", "RSFSecurity")',
data: "{'zoneCode':'" + zoneCode + "'}",
contentType: "application/json; charset=utf-8",
dataType: 'json',
cache: false,
success: function (data) {
$('#ddlRegion').get(0).options.length = 0;
$('#ddlRegion').get(0).options[0] = new Option("--Select--", "0");
$.map(data, function (item) {
$('#ddlRegion').get(0).options[$('#ddlRegion').get(0).options.length] = new Option(item.Display, item.Value);
});
},
error: function () {
alert("Failed to load Item");
}
});
}
});
</script>
We can use the jquery to get and fill the dropdown like this:
<script>
function FillCity() {
var stateId = $('#State').val();
$.ajax({
url: '/Employees/FillCity',
type: "GET",
dataType: "JSON",
data: { State: stateId},
success: function (cities) {
$("#City").html(""); // clear before appending new list
$.each(cities, function (i, city) {
$("#City").append(
$('<option></option>').val(city.CityId).html(city.CityName));
});
}
});
}
</script>
For more detail see
MVC DropDownListFor fill on selection change of another dropdown

Categories

Resources