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
Related
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;
}
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"
}
]
}
I am using the following to generate a dropdownlist of provinces based on the country selection:
<select id="Province" name="Province" class="form-control input-sm">
#{
string[] provinces = ViewBag.ProvincesForSelectedCountry;
string selectedProvinceName = null;
}
#{
if (Model != null && !String.IsNullOrEmpty(Model.Province))
{
selectedProvinceName = Model.Province;
}
else
{
selectedProvinceName = ConfigData.DefaultProvinceName;
}
}
#foreach (var anEntry in provinces)
{
string selectedTextMark = anEntry == selectedProvinceName
? "selected=\"selected\""
: String.Empty;
<option value="#(anEntry)" #(selectedTextMark)>#(anEntry)</option>
}
</select>
The challenge is I don't have a list of provinces (states) for other countries! Is there a way to allow for the user to type in the name of the province? Like a combobox.
I had to do it using Knockout-Kendo combobox, here is the solution:
Controller:
public ActionResult Index()
{
ViewBag.CountryID = new SelectList(db.Countries, "ID", "Name", "34");
.....
public JsonResult GetState(int? id)
{
if (id == null)
{ id = 34; }
var data = db.States.Where(x => x.CountryID == id)
.Select( x =>
new
{
ID = x.ID,
Name = x.Name
}).ToList();
return Json(data, JsonRequestBehavior.AllowGet);
}
In the View:
#Html.DropDownList("Country", ViewBag.CountryID as SelectList, "Select...",
new { onchange = "UpdateProvinces();" })
<input data-bind="kendoComboBox: { dataTextField: 'Name', dataValueField: 'ID',
data: choices, value: selectedChoice }" />
Here is the JavaScript:
function UpdateProvinces() {
var countryId = $("#Country option:selected").val();
$.getJSON("/Home/GetState/" + countryId,
null,
function (data) {
objVM.choices(data);
});
}
function ItemViewModel(arg) {
arg = 34;
var self = this;
this.choices = ko.observableArray([]),
$.ajax({
type: "GET",
url: '#Url.Action("GetState", "Home")',
contentType: "application/json; charset=utf-8",
data: { id: arg },
dataType: "json",
success: function (data) {
self.choices(data);
},
error: function (err) {
alert(err.status + " : " + err.statusText);
}
});
var selectedChoice = {
ID: self.ID,
Name: self.Name
};
self.selectedChoice = ko.observable();
}
var objVM = new ItemViewModel();
ko.applyBindings(objVM);
Edit:
Another alternative is to use Telerik MVC UI Combobox http://demos.telerik.com/aspnet-mvc/combobox/cascadingcombobox
I am using ajax to call an action in the controller. The code is like this
$('#kitchen').change(function () {
var selectedKitchen = $('#kitchen').val();
if (selectedKitchen != '') {
console.log("selected item:" + $('#kitchen').val());
$.ajax({
type: "GET",
url: "/Home/GiveInsitutionsWithoutResponsibility",
data: "id=" + selectedKitchen,
dataType:'json',
success: function (result) {
result = JSON.parse(result);
console.log(result.length);
},
error: function (error) {
console.log("There was an error posting the data to the server: ");
console.log(error.responseText);
}
});
}
});
Now what I want is to use the result coming from the server to populate a drop down on the client side. How should I do it? Is there a way for it or my approach here is wrong?
My result object is like this
{
Id: "04409314-ea61-4367-8eee-2b5faf87e592"
Name: "Test Institution Two"
NextPatientId: 1
OwnerId: "1"
PartitionKey: "1"
RowKey: "04409314-ea61-4367-8eee-2b5faf87e592"
Timestamp: "/Date(1417180677580)/"
}
The controller function is like this
public ActionResult GiveInsitutionsWithoutResponsibility()
{
var kitchenId = Request["id"].ToString();
Kitchen k = Kitchen.Get(kitchenId);
IEnumerable <Institution> ins = k.GetInstitutions();
IEnumerable<Institution> allIns = Institution.GetAll();
List<Institution> result = new List<Institution>();
bool contain = true;
int index = 0;
if (ins.Count() > 0)
{
for (int i = 0; i < allIns.Count(); i++, contain = true)
{
for (int j = 0; j < ins.Count(); j++)
{
if (allIns.ElementAt(i).Id == ins.ElementAt(j).Id)
{
contain = true;
break;
}
else
{
index = j;
contain = false;
}
}
if (!contain)
{
result.Add(allIns.ElementAt(index));
}
}
}
else
{
for (int i = 0; i < allIns.Count(); i++)
{
result.Add(allIns.ElementAt(index));
}
}
string response = new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(result);
return Json(response, JsonRequestBehavior.AllowGet);
}
First your action method can be simplified to
public ActionResult GiveInsitutionsWithoutResponsibility(int ID)
{
Kitchen k = Kitchen.Get(ID);
var data = Institution.GetAll().Except(k.GetInstitutions(), new InstitutionComparer()).Select(i => new
{
ID = i.ID,
Name = r.Name
});
return Json(data, JsonRequestBehavior.AllowGet);
}
Note the Kitchen.ID is passed in the method parameter. The Linq query is used to select all Institution's then exclude any Institution's that already exist in the Kitchen, then creates a collections of anonymous object so unnecessary data is not sent to the client. The Json() method returns the data in the correct JSON format (calling JavaScriptSerializer().Serialize() is not required).
In order for .Except() to work with complex objects, you need a comparer
public class InstitutionComparer : IEqualityComparer<Institution>
{
public bool Equals(Institution x, Institution y)
{
if (Object.ReferenceEquals(x, y))
{
return true;
}
if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
{
return false;
}
return x.ID == y.ID;
}
public int GetHashCode(Institution institution)
{
if (Object.ReferenceEquals(institution, null))
{
return 0;
}
return institution.ID.GetHashCode();
}
}
Next change the ajax method to
$('#kitchen').change(function () {
var selectedKitchen = $('#kitchen').val();
if (!selectedKitchen) {
return;
}
$.ajax({
type: "GET",
url: '#Url.Action("GiveInsitutionsWithoutResponsibility", "Home")', // don't hard code urls
data: { id: selectedKitchen }, // pass selectedKitchen to the id parameter
dataType:'json',
success: function (result) {
var select = $('YourDropDownSelector').empty().append($('<option></option>').val('').text('--Please select--'));
$.each(result, function(index, item) {
select.append($('<option></option>').val(item.ID).text(item.Name));
});
},
error: function (error) {
}
});
});
or you could use the short cut
$.getJSON('#Url.Action("GiveInsitutionsWithoutResponsibility", "Home")', { id: selectedKitchen }, function(result) {
$.each(result, .... // as above
});
Depending on the object from your controller, you could loop through your results data and .append this to your drop down list.
success: function (result) {
$.each(result, function(index, manager) {
$('select#yourId').append(
'<option value="' + result.Id + '">'
+ result.Name +
'</option>');
});
}
Your approach is fine, you will have to format the result to be added to combo box. For example, support on a page I have country and states combo box. Based on selected country, I need to populate state, so I will write following code:
$("#billingContactCountry").change(function (e) {
e.preventDefault();
var countryId = $("#billingContactCountry").val();
getStatesByCountry(countryId, "", "#billingContactState", "#billingContactZip");
});
function getStatesByCountry(countryId, stateId, stateCombobox, zipTextBox) {
$.ajax({
url: "#Url.Action("GetStatesByCountry", "Admin")",
data: { countryId: countryId },
dataType: "json",
type: "GET",
error: function (xhr, status) {
//debugger;
var items = "<option value=\"\">-Select State-</option>";
$(stateCombobox).html(items);
var zipMessage = validateZip(countryId, $(zipTextBox).val());
if (zipMessage != "The ZIP Code field is required.") {
$(zipTextBox).parent().find("span.field-validation-error").text(zipMessage);
}
$("div.overlay").hide();
},
success: function (data) {
//debugger;
var items = "<option value=\"\">-Select State-</option>";
$.each(data, function (i, item) {
items += "<option value=\"" + item.Id + "\">" + item.Name + "</option>";
});
$(stateCombobox).html(items);
if (stateId != "") {
$('#billingContactState').val(stateId);
}
var zipMessage = validateZip(countryId, $(zipTextBox).val());
if (zipMessage != "The ZIP Code field is required.") {
$(zipTextBox).parent().find("span.field-validation-error").text(zipMessage);
}
$("div.overlay").hide();
}
});
}
So basically interesting code is,
var items = "<option value=\"\">-Select State-</option>";
$.each(data, function (i, item) {
items += "<option value=\"" + item.Id + "\">" + item.Name + "</option>";
});
$(stateCombobox).html(items);
We are operating on each element returned from server to create option item for combo box.
As an aside, you should use #Url.Action as shown in example above.
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