I have displayed data in view page using data table. I want to display data in descending order according to
public ActionResult Index()
{
return View(db.BusinessRegModel.OrderByDescending(v => v.BusinessId).ToList());
}
BusinessId is primary key.
But in view page, data is not sorted via primary key. I am using jquery data table to display data.
<table id="tblBusinessData" class="table" width="100%" cellspacing="0">
<thead>
<tr>
<th>Edit/Print</th>
<th>
#Html.DisplayNameFor(model => model.RegNum)
</th>
<th>
#Html.DisplayNameFor(model => model.RegDate)
</th>
<th>
#Html.DisplayNameFor(model => model.NameOfFirm)
</th>
//code blocks
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td width="20%">
#Html.ActionLink("Edit", "Edit", new { id = item.BusinessId }, new { #class = "btn btn-warning" })
#Html.ActionLink("Print", "Details", new { id = item.BusinessId }, new { #class = "btn btn-danger" })
</td>
//code blocks
But the data is not sorted in descending order via BusinessId key. How can I do this? I need to display data in descending order by BusinessId.
jquery code
<script type="text/javascript">
$('#tblBusinessData').DataTable();
</script>
Add the column Id to the HTML and hide it via configuration:
$('#tblBusinessData').DataTable({
"columnDefs": [{
"targets": [0],
"visible": false
}],
"order": [
[0, "desc"]
]
});
If you are able to set the desired order in your data before you send it to DataTables, you can simply set order: [] to disable the initial sort while still being able to click on the column headers.
$('#tblBusinessData').DataTable({
order: []
});
Related
I am currently working in Asp.net MVC in Visual Studio 2017. I am new to working with Asp.net MVC and can not get the values i am needing.
I have a table of questions that are all displayed in a table on my view page. Each one of the questions have a Boolean value that shows as check boxes when they are being displayed. I am currently trying to write a script to get the checkbox value of true or false and where that checkbox is checked I am trying to get the Id of the question in the current row.
This is my view where I am displaying the questions.
#model IEnumerable<CapstoneApplication.Models.Question>
#{
ViewBag.Title = "Index";
}
<h2>Questions: Admin View</h2>
<script src="~/Scripts/jquery-3.3.1.min.js"></script>
<script src="~/Scripts/SaveCheckBox.js"></script>
<p>
#Html.ActionLink("Create Question", "Create")
</p>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.IsPartOfGame)
</th>
<th>
#Html.DisplayNameFor(model => model.Category.CategoryName)
</th>
<th>
#Html.DisplayNameFor(model => model.QuestionDescription)
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.CheckBoxFor(modelItem=>item.IsPartOfGame, new {onclick = "SaveCheckBox(this)" })
</td>
<td>
#Html.DisplayFor(modelItem => item.Category.CategoryName)
</td>
<td>
#Html.DisplayFor(modelItem => item.QuestionDescription)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new {id = item.Id}) |
#Html.ActionLink("Delete", "Delete", new {id = item.Id})
</td>
</tr>
}
</table>
This is the script I am currently using.
function SaveCheckBox(checkboxInput) {
$.ajax({
type: 'GET',
url: 'Index',
data: {idValue: checkboxInput.closest("tr").getAttribute("id"),
newValue: checkboxInput.checked },
dataType: 'json'
});
}
Finally this is the method the script calls to give the values to.
public ActionResult Index(bool? newValue, int? idValue)
{
//save to database here
var questions = db.Questions.Include(q => q.Category);
return View(questions.ToList());
}
The problem I am having is that newValue always returns the correct value of being either true or false but idValue is always null it never grabs the id of the question in the row of the checkbox that was checked.
I would place the id as the data attribute in your CheckboxFor
#Html.CheckBoxFor(
modelItem=>item.IsPartOfGame
, new {onclick = "SaveCheckBox(this)", data_itemid = item.Id}
})
Then I would use this for your javascript
function SaveCheckBox(checkboxInput) {
$.ajax({
type: 'GET',
url: 'Index',
data: {
idValue: checkboxInput.dataset.itemid
, newValue: checkboxInput.checked
},
dataType: 'json'
});
}
I have my html code like this defining a footable
<table class="table toggle-circle" id="exampleRowToggler">
<thead>
<tr>
<th data-field="marca">Marca</th>
<th data-field="modelo">Modelo</th>
<th data-field="placa">Placa</th>
<th data-field="chasis">Chasis</th>
<th data-field="vigencia_desde">Vigencia Desde</th>
<th data-field="vigencia_hasta">Vigendia Hasta</th>
<th data-hide="all">Clausulas</th>
<th data-hide="all">Exclusiones</th>
<th data-hide="all">Beneficios</th>
<th data-hide="all">Deducibles</th>
<th data-hide="all">Coberturas</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
and I want to fill it from a .js file that contains a function with the data in json like this. I've tried some options but still can't get it and the last thing I've tried was this.
loadTable: function () {
var bt_data = [{
"marca": "HYUNDAI",
"modelo": "IONIQ",
"placa": "T02096577",
"chasis":"KMHC851CGHU029520",
"vigencia_desde":"22/05/2017",
"vigencia_hasta":"22/05/2018",
"clausulas": "clauuuuuusulaaas",
"exclusiones": "eeexclusioooonesss",
"beneficios": "beeeeneeefiiiciiiooosss",
"deducibles":"deeeeduuuuciiiibleeeessss",
"coberturas":"cooooobeeeertuuuuraaaasssss"
}];
$('#exampleRowToggler').footable({
"useParentWidth": true,
"columns": $.get('columns.bt_data'),
"rows": $.get('rows.bt_data')
});
}
help me please.
The columns and rows values that you are passing in to footable will be producing nothing at all unless you have a server side page listening for the "columns.bt_data" and "rows.bt_data" URLs and returning relevant JSON/array responses.
Here's what I think you wanted to do:
loadTable: function () {
var bt_data = [{
"marca": "HYUNDAI",
"modelo": "IONIQ",
"placa": "T02096577",
"chasis":"KMHC851CGHU029520",
"vigencia_desde":"22/05/2017",
"vigencia_hasta":"22/05/2018",
"clausulas": "clauuuuuusulaaas",
"exclusiones": "eeexclusioooonesss",
"beneficios": "beeeeneeefiiiciiiooosss",
"deducibles":"deeeeduuuuciiiibleeeessss",
"coberturas":"cooooobeeeertuuuuraaaasssss"
}];
//get Column JSON from first item in Rows array
var columnJSON = $.map(Object.getOwnPropertyNames(bt_data[0]), function (column) {
return {"name": column,"title": column}
});
$('#exampleRowToggler').footable({
"useParentWidth": true,
"columns": columnJSON, //Pass columns object through to footable
"rows": bt_data //Pass your existing rows array through to footable
});
}
I'm new to Angular, so I don't know how to do this, what I want is to count all results of a filtered array, but the problem is that data I want to filter is on second level array, I have seen some things on Stack Overflow but none of them seem to work. So basically I have this:
app.controller('mainController', function ($scope, $http, $location, $filter) {
var externalOrigin1 = [];
var externalOrigin2 = [];
var externalOrigin3 = [];
var externalOrigin4 = [];
$http.get('app/data.json').then(function (datos) {
externalOrigin1 = datos.data;
externalOrigin2 = datos.data;//This will later be different on each case, but array will have same structure
externalOrigin3 = datos.data;
externalOrigin4 = datos.data;
//Estructura de representación de datos
$scope.Headers = [
{
'headerTitle': 'Morning Taskforce',
'headerLinkCode': 'TFC',
'headerData': externalOrigin1
},
{
'headerTitle': 'Op Taskforce',
'headerLinkCode': 'opr',
'headerData': externalOrigin2
},
{
'headerTitle': 'SAM Taskforce',
'headerLinkCode': 'sbgr',
'headerData': externalOrigin3
},
{
'headerTitle': 'Undefined Section Taskforce',
'headerLinkCode': 'ufts',
'headerData': externalOrigin4
}
];
//Count all rows where ActionTaken is 'PENDING' on it, but this won't work
$scope.pendingCount = $filter('pendingFilter')($scope.Headers.headerData, { autr: 'PENDING' }).length;
});
});
Data on data.Json has this structure
[
{
"_id": "569fd9c251f51d316e12efbe",
"actionTaken": "PENDING",
"actionTakenCode": "P",
"autr": false,
"action": "CANCELAR",
"actionAvailCode": "A",
"tp": "male",
"cta": 45.558392,
"doc": 25.395304,
"offset": 68305.2342,
"client": "George Oneil",
"terminal": 9215.6905
},
{
"_id": "569fd9c27e048c82ce0564a4",
"actionTaken": "CANCELED",
"actionTakenCode": "C",
"autr": false,
"action": "AUTORIZAR",
"actionAvailCode": "A",
"tp": "male",
"cta": 87.114735,
"doc": -142.965417,
"offset": 827448.2097,
"client": "Fischer Ballard",
"terminal": 2654.5002
}
]
And on my view I have this:
<ul data-role="listview" ng-repeat="header in Headers">
<li data-role="list-divider" data-theme="a"><h2>{{header.headerTitle}}</h2></li>
<li>
<table data-role="table" class="ui-grid-b ui-responsive table-stroke">
<thead>
<tr>
<th>
ACT TAKEN
</th>
<th>
OWNER
</th>
<th>
TP
</th>
<th>
CT
</th>
<th>
DOCEMER
</th>
<th>
MF47
</th>
<th>
CLIENT
</th>
<th>
BUREUS
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="dato in header.headerData | orderBy: '-monto'">
<td>
<span class="indicator action-{{dato.actionTakenCode}}">{{dato.actionTaken}}</span>
</td>
<td>
{{dato.autr}}
</td>
<td>
{{dato.tp}}
</td>
<td>
{{dato.cta}}
</td>
<td>
{{dato.doc}}
</td>
<td>
<b>{{dato.offset}}</b>
</td>
<td>
{{dato.cliente}}
</td>
<td>
{{dato.terminal}}
</td>
</tr>
</tbody>
</table>
</li>
</ul>
So far this do creates a table for every header, and rows for data on the sub level arrays, but I want to have an additional field that counts all PENDING on all tables, which I tried getting on pendingCount variable, but won't work.
<div id="overview">PENDING OPERATORS = {{pendingCount}} </div>
You need to define pendingCount as a variable in $scope. Another way is to define a function in $scope called getPendingCount and do the math in that function. Let me know if I did not understand the context clearly and I'll try to help you out with this problem.
Also take a look at the documentation for $filter as the second parameter must be an array.
https://docs.angularjs.org/api/ng/filter/filter
Iterate over the Headers array and call the filter for each one of them and sum up the quantity.
Another approach would be to just use 2 for statements and count the records that match your criteria.
I have to render a table with dynamic headers, I mean, I don't want to do something like this in the HTML
<table>
<tr>
// THIS TABLE ROW IS WHAT I SAY
<th>here info</th>
<th>something here</th>
<th>another header</th>
</tr>
<tr ng-repeat="thing in things">
<td>{{thing.asfs}}</td>
<td>{{thing.asx}}</td>
<td>{{person.dsf}}</td>
</tr>
</table>
I want something like this
<table>
<tr ng-repeat="head in heads">
{{head}}
</tr>
<tr ng-repeat="bar in bars">
<td ng-repeat="foo in foos"></td>
</tr>
</table>
that is only an example, I need to do it with this data:
{
"55f6de98f0a50c25f7be4db0":{
"clicks":{
"total":144,
"real":1
},
"conversions":{
"total":4,
"amount":229
},
"cost":{
"cpc":0.1999999999999995,
"ecpc":1145.0000000000027,
"total":28.79999999999993
},
"revenue":{
"total":4,
"epc":0.027777777777777776
},
"net":{
"roi":-1.1612903225806457,
"total":4
},
"name":"Traffic Source #2",
},
"55f6de98f0a50c25f7be4dbOTHER":{
"clicks":{
"total":144,
"real":1
},
"conversions":{
"total":4,
"amount":229
},
"cost":{
"cpc":0.1999999999999995,
"ecpc":1145.0000000000027,
"total":28.79999999999993
},
"revenue":{
"total":4,
"epc":0.027777777777777776
},
"net":{
"roi":-1.1612903225806457,
"total":4
}
"name":"Traffic Source #3"
},
}
every key, like clicks, conversions, cost, etc, should be a td, it is just that I don't want static HTML.
Any suggestions?
EDIT
And also, sometimes that object will grow, could come up with some more keys like this one 55f6de98f0a50c25f7be4db0
I did this fiddle with the exact same data I am receiving
http://jsfiddle.net/wLkz45qj/
UPDATE:
What you need to do is first convert you inconvenient object to array of objects with simple structure, and then use my code , i.e.
{
a: {
b:{
c: 'x'
}
}
}
will turn into
[[ a, { 'b.c' : 'x' }], ...]
or just
[{ _id : a , 'b.c' :'x'}, ...]
easiest way to do that is to use lodash or underscore ( check map, flatMap, pairs etc)
#jperezov showed you core idea, little bit detailed example:
$scope.peopleKeys = Object.keys(people[0])
and
<table>
<tr>
<th></th>
<th ng-repeat="personKey in peopleKeys">
{{ personKey }}
</th>
</tr>
<tr ng-repeat='p in people'>
<th>{{ $index }}</th>
<td ng-repeat="personKey in peopleKeys">
{{ p[personKey] }}
</td>
</tr>
</table>
You may also have some dictionary with display names:
$scope.displayNames = {
id: 'ID',
firstName: 'First Name'
...
}
and then your header going to be:
<tr>
<th></th>
<th ng-repeat="personKey in peopleKeys">
{{ displayNames[personKey] }}
</th>
</tr>
PS: OR you can just use ui-grid
var app = angular.module('myApp', []);
function PeopleCtrl($scope, $http) {
$scope.headers=[];
$scope.data = [];
$scope.LoadMyJson = function() {
for (var s in myJson){
$scope.data.push(s);
if ($scope.headers.length < 1)
for (var prop in myJson[s]){
prop.data = [];
$scope.headers.push({th:prop, td: []});
}
}
for (var s in $scope.data){
for (var prop in $scope.headers){
var header = $scope.headers[prop].th;
var data = myJson[$scope.data[s]][header];
$scope.headers[prop].td.push(data);
}
}
};
}
What you're looking for is something like this, I think:
http://jsfiddle.net/wLkz45qj/8/
Maybe iterate another time over "inner" for formatting.
For our site we have an Admin section and a user section. We want to allow Admins to specify which order items are listed to the users in the user section.
I have an MVC list table, and I've enabled sorting the rows to actually change the sort value. But I'm trying to save the sort to the database. As you can see below, I have hidden elements for certain properties, and my javascript sets the HiddenFor(item.SortOrder) correctly. It then calls the controller. But I would like the entire collection of rows to be passed back as a List<> object. Are there any good examples?
#model System.Collections.Generic.IList<PublicationSystem.Model.CustomField>
<table class="table sortable-table"
data-source-href='#Url.RouteUrl("Default",
new { action = "_CustomFieldSort" },
Request.Url.Scheme)'>
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model[0].ColumnName)
</th>
<th>
#Html.DisplayNameFor(model => model[0].ColumnCaption)
</th>
<th></th>
</tr>
</thead>
#for (var i=0; i < Model.Count; i++) //each (var item in Model)
{
<tr>
<td>
#Html.HiddenFor(modelItem => Model[i].CustomFieldId,new {name="fieldsToEdit["+i+"].CustomFieldId"})
#Html.HiddenFor(modelItem => Model[i].CustomFormId, new { name = "fieldsToEdit[" + i + "].CustomFormId" })
#Html.HiddenFor(modelItem => Model[i].SortOrder, new { name = "fieldsToEdit[" + i + "].SortOrder", #class = "SortOrder" })
#Html.DisplayFor(modelItem => Model[i].ColumnName)
</td>
<td>
#Html.DisplayFor(modelItem => Model[i].ColumnCaption)
</td>
<td>
... buttons
</td>
</tr>
}
</table>
My javascript:
$(".sortable-table tbody").sortable({
stop: function (event, ui) {
$(".sortable-table tr").each(function (index, element) {
var hiddenInput = $(element).find(".SortOrder").first();
hiddenInput.val(index);
});
$.ajax({
url: $(".sortable-table").attr("data-source-href"),
method: "POST",
data: $(".sortable-table").serialize(),
success: function (result) {
ClearAndRefresh(); // Assumes parent has this function
}
});
}
});
My controller method:
public ActionResult _CustomFieldSort(List<CustomField> fieldsToEdit)
{
if (fieldsToEdit != null) // fieldsToEdit is always null after the sort
{
var fieldCount = fieldsToEdit.Count();
}
return null;// PartialView();
}
I have my javascript correctly trying an ajax call to my controller method, but 'fieldsToEdit' is null. What am I doing wrong?
Bulk update on sorting? using a for loop will enable you to map back the whole list back to a post/get method on the controller
#model System.Collections.Generic.IList<PublicationSystem.Model.CustomField>
<table class="table sortable-table">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.ColumnName)
</th>
<th>
#Html.DisplayNameFor(model => model.ColumnCaption)
</th>
<th></th>
</tr>
</thead>
#for (int i=0; i < Model.Length;i++)
{
<tr>
<td>
#Html.HiddenFor(modelItem => Model[i].CustomFieldId,new {name="fieldsToEdit["+i+"].CustomFieldId")
#Html.HiddenFor(modelItem =>Model[i].CustomFormId,new {name="fieldsToEdit["+i+"].CustomFormId")
#Html.HiddenFor(modelItem => Model[i].SortOrder, new { #class = "SortOrder",name="fieldsToEdit["+i+"].SortOrder" })
#Html.DisplayFor(modelItem => Model[i].ColumnName,new {name="fieldsToEdit["+i+"].ColumnName")
</td>
<td>
#Html.DisplayFor(modelItem => Model[i].ColumnCaption,new {name="fieldsToEdit["+i+"].ColumnCaption")
</td>
<td>
... buttons
</td>
</tr>
}
Then hitting back on button to post button will bulk update the whole list, im not sure if I am answering you question correctly or not though.