I have done groupby column using DataTable. Now I have to show the total value of "another number field column" with the existing groupby - datatables

I have done groupby column using DataTable as shown below.
Project
Task
Efforts(in Hrs)
Sakthi
---------
---------------
HTML Page
designing
2.30
HTML Page
JS
0.30
HTML Page
css
5.00
Vel
---------
---------------
HTML Page
Tesing
4.00
HTML Page
Test Case
4.00
Now I have to show the total value of "another number field column" with the existing groupby.
Project
Task
Efforts(in Hrs)
Sakthi
---------
8.00
HTML Page
designing
2.30
HTML Page
JS
0.30
HTML Page
css
5.00
Vel
---------
8.00
HTML Page
Tesing
4.00
HTML Page
Test Case
4.00

I have put together a mock example for you. You need to make sure that you are using the rowGroup external script/stylesheet for the following. Within your rowGroup.startRender function you need to do the following:
Create a total variable, and pluck data from the row which you want to get the total (efforts), then use a reduce function to return an added value. Once you have done this, append it to the new table row.
var totalEfforts = rows
.data()
.pluck('Efforts')
.reduce( function (a, b) {
return a + b;
}, 0);
var data = [
{
"Name" : "Sakthi",
"Project" : "HTML Page",
"Task" : "Designing",
"Efforts" : 2.5
},
{
"Name" : "Sakthi",
"Project" : "HTML Page",
"Task" : "JS",
"Efforts" : 0.5
},
{
"Name" : "Sakthi",
"Project" : "HTML Page",
"Task" : "CSS",
"Efforts" : 5
},
{
"Name" : "Vel",
"Project" : "HTML Page",
"Task" : "Testing",
"Efforts" : 4
},
{
"Name" : "Vel",
"Project" : "HTML Page",
"Task" : "Test Case",
"Efforts" : 4
}
]
$(document).ready(function() {
$('#example').DataTable( {
data: data,
columns : [
{"data" : "Name", visible: false},
{"data" : "Project"},
{"data" : "Task"},
{"data" : "Efforts"}
],
order: [[2, 'asc']],
rowGroup: {
dataSrc: ['Name'],
startRender: function (rows, group){
var totalEfforts = rows
.data()
.pluck('Efforts')
.reduce( function (a, b) {
return a + b;
}, 0);
return $('<tr/>')
.append( '<td colspan="2">'+group+'</td>' )
.append( '<td>'+totalEfforts.toFixed(0)+'</td>' )
.append( '<td/>' );
},
endRender: null,
}
} );
} );
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://cdn.datatables.net/1.11.5/css/jquery.dataTables.min.css">
<link rel="stylesheet" href="https://cdn.datatables.net/rowgroup/1.1.4/css/rowGroup.dataTables.min.css">
<script src="https://code.jquery.com/jquery-3.5.1.js"></script>
<script src="https://cdn.datatables.net/1.11.5/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/rowgroup/1.1.4/js/dataTables.rowGroup.min.js"></script>
</head>
<body>
<div class="container">
<table id="example" class="display" style="width:100%">
<thead>
<tr>
<th>Name</th>
<th>Project</th>
<th>Task</th>
<th>Efforts (hrs)</th>
</tr>
</thead>
</table>
</div>
</body>
</html>

Related

Loading the datatable with the data from JsonResult method from the controller, makes alignment fails in footer

I am trying to find the total of 'Net Value' and ' Total Value' in datatable as footer and the total value should be shown inside td element with the same alignment of its other data column. If I try to add footer , the total column shows different position from its data column. The footer should be showed the same column of its data. Here is my code in html. Since I am not able to show the original program , I had to make it in presentable format.
I am showing the data by calling JsonResult method from the controller , But after fetching the data from the Json method and showing the result in datatable with vertical scrolling, the footer value is showed bit far from its data column
#model myModel
<!DOCTYPE html>
<html lang="en">
<head>
<title>Bootstrap Example</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdn.datatables.net/1.13.2/css/jquery.dataTables.min.css" />
<link rel="stylesheet" href="https://cdn.datatables.net/buttons/2.3.4/css/buttons.dataTables.min.css" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.3/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<script src="https://cdn.datatables.net/1.13.2/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/buttons/2.3.4/js/dataTables.buttons.min.js"></script>
<script src="https://cdn.datatables.net/buttons/2.3.4/js/buttons.html5.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.1.3/jszip.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.53/pdfmake.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.53/vfs_fonts.js"></script>
</head>
<body>
<table id="myTable" class="table table-bordered table-striped" style="width:100%;font-size:90%">
<thead>
<tr>
<th>
Item
</th>
<th>
Net Value
</th>
<th>
Total Value
</th>
</tr>
</thead>
<tbody id="body">
<tr>
<td>Item</td>
<td>NetVal</td>
<td>TotVal</td>
</tr>
</tbody>
<tfoot>
<tr>
<td>Total</td>
<td></td>
<td></td>
</tr>
</tfoot>
</table>
<script>
$(document).ready(function () {
var report = {};
report.FromDate = "#Model.FromDate";
report.ToDate = "#Model.ToDate";
report.CustomerCode = "#Model.CustomerCode";
var table = $('#myTable').DataTable({
"processing": true,
"ajax": {
"url": "/mySales/SalesData",
"data": report,
"dataSrc": function (json) {
console.log(json);
return JSON.parse(json);
}
},
"columns": [
{ "data": "Item" },
{ "data": "NetVal" },
{ "data": "TotVal" },
],
"columnDefs": [
{
"className": "dt-center", "targets": "_all"
},
{ "width": "10%", "targets": 0 },
{ "width": "5%", "targets": 1 },
{ "width": "5%", "targets": 2 },
],
"pageLength": 40,
scrollY: "500px",
scrollX: true,
paging: true,
footerCallback: function (row, data, start, end, display) {
var api = this.api(), data;
var intVal = function (i) {
return typeof i === 'string' ?
i.replace(/[\$,]/g, '') * 1 :
typeof i === 'number' ?
i : 0;
};
var col1 = api
.column(1)
.data()
.reduce(function (a, b) {
return intVal(a) + intVal(b);
}, 0);
var col2 = api
.column(2)
.data()
.reduce(function (a, b) {
return intVal(a) + intVal(b);
}, 0);
$(api.column(1).footer()).html(col1);
$(api.column(2).footer()).html(col1);
},
scrollCollapse: true,
dom: 'Bfrtip',
buttons: [
'copyHtml5',
'excelHtml5',
'csvHtml5',
'pdfHtml5'
]
})
})
</script>
// Controller
public JsonResult SalesData(myModel model)
{
DateTime fromDate = new DateTime();
DateTime toDate = new DateTime();
if (report.FromDate != "" && report.ToDate != "" && report.FromDate != null && report.ToDate != null)
{
fromDate = DateTime.ParseExact(report.FromDate, "dd/MM/yyyy", CultureInfo.InvariantCulture);
toDate = DateTime.ParseExact(report.ToDate, "dd/MM/yyyy", CultureInfo.InvariantCulture);
}
report.CustomerCode = "001";
var data = _unitOfWork.GetSummary(report.CustomerCode, fromDate, toDate);
String jsonResult = JsonConvert.SerializeObject(data);
return Json(jsonResult);
}

How to populate dataTable with multidimensional array with dynamic key

I have an array like this:
"products": {
"111111": {
"date": "01.01.2018",
"amount": 10,
"user_id": "user1",
}
"222222": {
"date": "10.10.2018",
"amount": 15,
"user_id": "user1,
}
}
"111111" and "222222" are IDs and they are generated dynamically, depending on selected user.
I want to display the following columns: product_id, date, amount, user_id
Is there a way to populate the table when a column name is dynamic ?
Thanks!
If you can change the format of your json slightly, you can easily just assign it as an array for the data attribute when initializing datatables. If that is not an option, you could just parse it into the below format by iterating through the key-value pairs and adding that data to an array of jsons.
$(document).ready(function() {
var products = [{
"product_id": "111111",
"date": "01.01.2018",
"amount": 10,
"user_id": "user1",
},
{
"product_id": "222222",
"date": "10.10.2018",
"amount": 15,
"user_id": "user1",
}
];
var table = $('#example').DataTable({
data: products,
columnDefs: [
{ targets: 0, data: "product_id"},
{ targets: 1, data: "date" },
{ targets: 2, data: "amount" },
{ targets: 3, data: "user_id" }
]
});
});
<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
<link href="https://nightly.datatables.net/css/jquery.dataTables.css" rel="stylesheet" type="text/css" />
<script src="https://nightly.datatables.net/js/jquery.dataTables.js"></script>
<div class="container">
<table id="example" class="display nowrap" width="100%">
<thead>
<tr>
<th>product_id</th>
<th>date</th>
<th>amount</th>
<th>user_id</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>

Not able to display value of a element through button click of my extension

I have account with www.makemytrip.com and where 'from' field and 'to' field is already saved through cookies
Using extension, I would like to display the value present in 'from' field of that site. (whose id is 'hp-widget__sfrom')
On page load I am able to view the value but the same I can't achieve on click on my button defined in my extension
Below is the code: index.html
<html>
<head>
<title>My new extension</title>
</head>
<body>
<input type="button" id="save" value="Save Text">
</body>
</html>
manifest.json
{
"manifest_version": 2,
"name": "Test1",
"description": "TestDesc",
"version": "1.0",
"background": {
"scripts": ["background.js"]
},
"permissions": [
"activeTab"
],
"browser_action": {
"default_icon": "icon.png",
"default_popup": "index.html",
"default_title": "Test11"
},
"content_scripts": [
{
"matches": ["http://*/*", "https://*/*"],
"js": ["myContentScript.js"]
}
]
}
myContentScript.js
window.onload = function(){
alert("Hi by contentScript");
//alert(document.getElementById('hp-widget__sfrom').value); //this works!
//but the below doesn't work; onclick of button
document.getElementById('save').onclick = function(){
alert(document.getElementById('hp-widget__sfrom').value);
}
}
background.js
window.onload = function(){
alert("Hi by backgroundJS");
}
I appreciate any sort of help!

Having problems putting a dgrid into TitlePane

I am trying to put a dojo dgrid into a titlepane as follows:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Tutorial: Hello dgrid!</title>
<link rel="stylesheet" href="/dojo/dojo/resources/dojo.css">
<link rel="stylesheet" href="/dojo/dgrid/css/dgrid.css">
<link rel="stylesheet" href="/dojo/dgrid/css/skins/claro.css">
<link rel="stylesheet" href="/dojo/dijit/themes/claro/claro.css">
<!-- this configuration assumes that the dgrid package is located
on the filesystem as a sibling to the dojo package -->
<script src="/dojo/dojo/dojo.js">
data-dojo-config={async: true, parseOnLoad: true}
</script>
<script>
require(["dijit/TitlePane", "dgrid/Grid", "dojo/domReady!"], function(TitlePane,Grid){
var data = [
{ first: "Bob", last: "Barker", age: 89 },
{ first: "Vanna", last: "White", age: 55 },
{ first: "Pat", last: "Sajak", age: 65 }
];
var grid = new Grid({
columns: {
first: "First Name",
last: "Last Name",
age: "Age"
}
}, "grid");
grid.renderArray(data);
});
</script>
</head>
<body class="claro">
<div data-dojo-type="dijit/TitlePane" data-dojo-props="title: 'Pane #1'">
<div id="grid"></div>
</div>
</body>
</html>
And I am just not getting the TitlePane to show up. The grid shows up nicely. Any ideas what I am doing wrong here?
Ultimately I am going to be generating a page with a number of grids on it, and looking fora nice way to put the grids into containers...
When I put in "dojo/parser" it worked for me:
<script>
require(["dijit/TitlePane", "dojo/parser","dgrid/Grid", "dojo/domReady!"],
function(TitlePane, parser, Grid) {
parser.parse();
var data = [{
first : "Bob",
last : "Barker",
age : 89
}, {
first : "Vanna",
last : "White",
age : 55
}, {
first : "Pat",
last : "Sajak",
age : 65
}];
var grid = new Grid({
columns : {
first : "First Name",
last : "Last Name",
age : "Age"
}
}, "grid");
grid.renderArray(data);
});
</script>

My extjs grid is not showing in new archictecture

I am using the architecture for my extjs app is from this blog post
http://blog.extjs.eu/know-how/writing-a-big-application-in-ext/
So here is my index.html Please read the whole question for complete answer.
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Reseller DashBoard</title>
<!-- ** CSS ** -->
<!-- base library -->
<link rel="stylesheet" type="text/css" href="./ext/resources/css/ext-all.css" />
<link rel="stylesheet" type="text/css" href="./ext/resources/css/xtheme-gray.css" />
<!-- overrides to base library -->
<!-- ** Javascript ** -->
<!-- ExtJS library: base/adapter -->
<script type="text/javascript" src="./ext/adapter/ext/ext-base-debug.js"></script>
<!-- ExtJS library: all widgets -->
<script type="text/javascript" src="./ext/ext-all-debug.js"></script>
<!-- overrides to base library -->
<!-- page specific -->
<script type="text/javascript" src="application.js"></script>
<script type="text/javascript" src="js/Application.dashboard.js"></script>
<script type="text/javascript" src="js/jsfunction.js"></script>
<script type="text/javascript" src="js/reseller.js"></script>
</head>
<body>
<div id="dashboard">
</div>
</body>
</html>
Here is my application.js I am intialising here my dashboard grid, is it the right place to initialise ?
/*global Ext, Application */
Ext.BLANK_IMAGE_URL = './ext/resources/images/default/s.gif';
Ext.ns('Application');
// application main entry point
Ext.onReady(function() {
Ext.QuickTips.init();
var pg = new Application.DashBoardGrid();
// or using it's xtype
var win = new Ext.Window({
items:{xtype:'DashBoardGrid'}
});
// code here
}); // eo function onReady
// eof
Here is my Application.DashBoardGrid.js
My request to the api is going two times right now Why ?
I have a linkrenderer function for a column for rendering where should i put this function?
And Suggest Why My Grid is not Coming ?
Application.DashBoardGrid = Ext.extend(Ext.grid.GridPanel, {
border:false
,initComponent:function() {
var config = {
store:new Ext.data.JsonStore({
// store configs
autoDestroy: true,
autoLoad :true,
url: 'api/index.php?_command=getresellerscount',
storeId: 'getresellerscount',
// reader configs
root: 'cityarray',
idProperty: 'cityname',
fields: [
{name: 'cityname'},
{name: 'totfollowup'},
{name: 'totcallback'},
{name: 'totnotintrested'},
{name: 'totdealsclosed'},
{name: 'totcallsreceived'},
{name: 'totcallsentered'},
{name: 'totresellerregistered'},
{name: 'countiro'},
{name: 'irotransferred'},
{name: 'irodeferred'}
]
})
,columns: [
{
id :'cityname',
header : 'City Name',
width : 120,
sortable : true,
dataIndex: 'cityname'
},
{
id :'countiro',
header : ' Total Prospect',
width : 100,
sortable : true,
dataIndex: 'countiro'
},
{
id :'irotransferred',
header : 'Calls Transfered By IRO',
height : 50,
width : 100,
sortable : true,
dataIndex: 'irotransferred'
},
{
id :'irodeferred',
header : ' Calls Deferred By IRO',
width : 100,
sortable : true,
dataIndex: 'irodeferred'
},
{
id :'totcallsentered',
header : ' Total Calls Entered',
width : 100,
sortable : true,
dataIndex : 'totcallsentered'//,
//renderer : linkRenderer
},
{
id :'totfollowup',
header : ' Follow Up',
width : 100,
sortable : true,
dataIndex: 'totfollowup'
},
{
id :'totcallback',
header : ' Call Backs',
width : 100,
sortable : true,
dataIndex: 'totcallback'
},
{
id :'totnotintrested',
header : ' Not Interested',
width : 100,
sortable : true,
dataIndex: 'totnotintrested'
},
{
id :'totdealsclosed',
header : ' Deals Closed',
width : 100,
sortable : true,
dataIndex: 'totdealsclosed'
},
{
id :'totresellerregistered',
header : ' Reseller Registered',
width : 100,
sortable : true,
dataIndex: 'totresellerregistered'
}
]
,plugins:[]
,viewConfig:{forceFit:true}
,tbar:[]
,bbar:[]
,render:'dashboard'
,height: 350
,width: 1060
,title: 'Reseller Dashboard'
}; // eo config object
// apply config
Ext.apply(this, Ext.apply(this.initialConfig, config));
Application.DashBoardGrid.superclass.initComponent.apply(this, arguments);
} // eo function initComponent
,onRender:function() {
// this.store.load();
Application.DashBoardGrid.superclass.onRender.apply(this, arguments);
} // eo function onRender
});
Ext.reg('DashBoardGrid', Application.DashBoardGrid);
Json Response
{
"countothercities": "0",
"directreseller": "14",
"totalresellersregisteredfor8cities": 33,
"cityarray": [{
"cityname": "bangalore",
"totfollowup": "3",
"totcallback": "4",
"totnotintrested": "2",
"totdealsclosed": "0",
"totcallsreceived": "0",
"totcallsentered": "68",
"totresellerregistered": "6",
"countiro": "109",
"irotransferred": "83",
"irodeferred": "26"
}]
}
Please show your JSON response, or server code. So that we can answer better.
My request to the api is going two times right now Why ?
Obvious. Inside Ext.onReady()
You are creating instance of DashboardGrid. Call 1
You are asking Ext to create instance of DashboardGrid by passing xtype. Call 2
You are creating the grid twice. Do this instead.
Ext.onReady(function() {
Ext.QuickTips.init();
var win = new Ext.Window({
items:{xtype:'DashBoardGrid'}
});
// code here
}); // eo function onReady