RowGrouping and SubTotals in Sharepoint List using Datatables - javascript

Hi I am using a Sharepoint List which I am displaying using DataTables , I referred one the articles and i was to do grouping but i am not able to get Group Totals ,RowGrouping and Subtotal on Datatable
In This field on which I am grouping on is a calculated field called Heirarch for example field values are generaly like Capital.Establishment it is concatenation of two fields
Below is my Code
<script type="text/javascript" charset="utf8" src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
<!-- DataTables CSS -->
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/r/dt/dt-1.10.9/datatables.min.css"/>
<!-- DataTables -->
<script type="text/javascript" src="https://cdn.datatables.net/r/dt/dt-1.10.9/datatables.min.js"></script>
<script type="text/javascript" src="http://jquery-datatables-row-grouping.googlecode.com/svn/trunk/media/js/jquery.dataTables.rowGrouping.js"></script>
<style type="text/css">
tr.group, tr.group:hover {
background-color: #ddd !important;
}
.pocell {
font-weight:bold;
}
</style>
<table id="example" class="display" cellspacing="0" width="100%">
<thead>
<tr>
</tr>
</thead>
</table>
<script type="text/javascript">
$(document).ready(function() {
var call = $.ajax({
url: _spPageContextInfo.webAbsoluteUrl + "/_api/Web/Lists/GetByTitle('Demo%20Custom%20List')/items?$select=Hierarch,Title,Year2015,Year2016,Year2017,Year2018,Year2019,Exp_x0020_Total",
type: "GET",
dataType: "json",
headers: {
Accept: "application/json;odata=verbose"
}
});
call.done(function (data,textStatus, jqXHR){
var marker;
var table = $('#example').DataTable({
"aaData": data.d.results,
"columns": [
{
"title": "Hierarchy",
"mData": "Hierarch",
"visible": false
}, {
"title": "Title",
"mData": "Title"
}, {
"title": "Year2015",
"mData": "Year2015",
"sortable": false
}, {
"title": "Year2016",
"mData": "Year2016",
"sortable": false
}, {
"title": "Year2017",
"mData": "Year2017",
"sortable": false
}, {
"title": "Year2018",
"mData": "Year2018",
"sortable": false
}, {
"title": "Year2019",
"mData": "Year2019",
"sortable": false
}, {
"title": "Total Expense",
"mData": "Exp_x0020_Total",
"sortable": false
}
],
"drawCallback": function (settings) {
var api = this.api();
var rows = api.rows({
page: 'current'
}).nodes();
var last = null;
api.column(0, {
page: 'current'
}).data().each(function (group, i) {
if (last !== group) {
$(rows).eq(i).before(
$("<tr></tr>", {
"class": "group",
"data-id": group
}).append($("<td></td>", {
"colspan": 1,
"class": "pocell",
"text": "Hierarch # " + group.split('_').join('.')
})).append($("<td></td>", {
"id": "e" + group,
"class": "noCount",
"text": "60.00"
})).append($("<td></td>", {
"id": "f" + group,
"class": "noCount",
"text": "60.00"
})).append($("<td></td>", {
"id": "g" + group,
"class": "noCount",
"text": "50.00"
})).append($("<td></td>", {
"id": "h" + group,
"class": "noCount",
"text": "40.00"
})).append($("<td></td>", {
"id": "i" + group,
"class": "noCount",
"text": "30.00"
})).append($("<td></td>", {
"id": "j" + group,
"class": "noCount",
"text": "20.00"
})).prop('outerHTML'));
last = group;
}
val = api.row(api.row($(rows).eq(i)).index()).data();
$("#e" + val.Hierarch.split('.').join('_')).text(parseFloat($("#e" + val.Hierarch.split('.').join('_')).text()) + parseFloat(val.Year2015));
// $("#e" + val.Hierarch).text(parseFloat($("#e" + val.Hierarch).text()) + val.Year2015);
$("#f" + val.Hierarch).text(parseFloat($("#f" + val.Hierarch).text()) + val.Year2015);
$("#g" + val.Hierarch).text(parseFloat($("#g" + val.Hierarch).text()) + val.Year2015);
$("#h" + val.Hierarch).text(parseFloat($("#h" + val.Hierarch).text()) + val.Year2015);
$("#i" + val.Hierarch).text(parseFloat($("#i" + val.Hierarch).text()) + val.Year2015);
$("#j" + val.Hierarch).text(parseFloat($("#j" + val.Hierarch).text()) + val.Year2015);
});
}
});
});
call.fail(function (jqXHR,textStatus,errorThrown){
alert("Error retrieving Tasks: " + jqXHR.responseText);
});
} );
</script>

Related

Javascript Not Displaying Button Text

full json is
{
"id": "70dec1ac-345f-4b94-b255-b09c5ab1b522",
"name": "card",
"auto": true,
"contexts": [],
"responses": [
{
"resetContexts": false,
"affectedContexts": [],
"parameters": [],
"messages": [
{
"type": 1,
"platform": "facebook",
"title": "this is the title updated",
"subtitle": "this is the subtitle",
"imageUrl": "https://www.gettyimages.ie/gi-resources/images/Homepage/Hero/UK/CMS_Creative_164657191_Kingfisher.jpg",
"buttons": [
{
"text": "this is the button"
},
{
"text": "this is also a button"
}
],
"lang": "en"
},
{
"type": 0,
"speech": []
}
],
"defaultResponsePlatforms": {},
"speech": []
}
],
"priority": 500000,
"cortanaCommand": {
"navigateOrService": "NAVIGATE",
"target": ""
},
"webhookUsed": false,
"webhookForSlotFilling": false,
"lastUpdate": 1530197695,
"fallbackIntent": false,
"events": [],
"userSays": [
{
"id": "528c22d4-49d7-4ab9-a8db-fcd84d57694b",
"data": [
{
"text": "card"
}
],
"isTemplate": false,
"count": 0,
"updated": 1530196620,
"isAuto": false
}
],
"followUpIntents": [],
"templates": []
}
I am actually making a chatbot for wordpress to communicate with api.ai or dialogflow
The code I am currently using to display a card is the following:
var html = "<div class=\"myc-conversation-bubble myc-conversation-response myc-is-active myc-image-response\"><img src=\"" + imageUrl + "\"/></div>";
html+="<div class=\"myc-card-title\">" + title + "</div>"
html += "<div class=\"myc-card-subtitle\">" + subtitle+ "</div>";
html += "<input type=\"button\" " + "style=\"background-color:rgb(221, 153, 51);text-transform: none\"" + "class=\"myc-quick-reply\" value=\"" +buttons[0]+ "\" />";
var innerHTML = "<div class=\"myc-conversation-bubble-container myc-conversation-bubble-container-response\"><div class=\"myc-conversation-bubble myc-conversation-response myc-is-active myc-quick-replies-response\">" + html + "</div>";
I am getting the image ,title ,subtitle correctly but the Button is displayed as [object Object] what is the correct way to do it?
The button text is in the text property.
Try to replace buttons[0] with buttons[0].text.
in your case buttons is an array of object and have property text. so try buttons[0].text

How to conditionally draw DataTables columns in Razor pages

Currently we are doing this to draw the columns for a server side DataTable for 2 different users, we were able to hide the column headers using razor code to only draw them when the user is an admin or group admin. However when it comes to drawing the data we are having an issue with the following:
function getTableColumns() {
var allowedToDelete = #(User.IsInRole("SysAdmin") || GroupManager.IsUserGroupAdmin(Model.GroupId, User.FindFirst(ClaimTypes.NameIdentifier).Value) ? "true" : "false");
if (allowedToDelete) {
return [{ "defaultContent": "" },
{ "data": "deadlineDate", "name": "DeadlineDate" },
{ "data": "priority", "name": "Priority" },
{ "data": "jobNumber", "name": "JobNumber" },
{ "data": "project", "name": "Project" },
{ "data": "description", "name": "Description" },
{ "data": "reference", "name": "Reference" },
{ "data": "subReference", "name": "SubReference" },
{ "data": "employee", "name": "Employee" },
{ "data": "allocatedTo", "name": "AllocatedTo" },
{
"render": function (data, type, full, meta) {
return "<i title ='Archive Item' class='fa fa-archive table-icon-view' onclick='archiveJob(\""
+ full.groupId + "\",\"" + full.id + "\")'></i>";
}
},
{
"render": function (data, type, full, meta) {
return "<i title ='Edit' class='fa fa-pencil table-icon-edit' onclick='editJob(\""
+ full.groupId + "\",\"" + full.id + "\")'></i>";
}
},
{
"render": function (data, type, full, meta) {
return "<i title ='Delete' class='fa fa-trash table-icon-delete' onclick='showDeleteModal(\""
+ full.groupId + "\",\"" + full.id + "\")'></i>";
}
},
{ "data": "issueDate" },
{ "data": "startDate" },
{ "data": "createdBy" },
{ "data": "createdDate" },
{ "data": "notes" }];
} else {
return [{ "defaultContent": "" },
{ "data": "deadlineDate", "name": "DeadlineDate" },
{ "data": "priority", "name": "Priority" },
{ "data": "jobNumber", "name": "JobNumber" },
{ "data": "project", "name": "Project" },
{ "data": "description", "name": "Description" },
{ "data": "reference", "name": "Reference" },
{ "data": "subReference", "name": "SubReference" },
{ "data": "employee", "name": "Employee" },
{ "data": "allocatedTo", "name": "AllocatedTo" },
{
"render": function (data, type, full, meta) {
return "<i title ='Edit' class='fa fa-pencil table-icon-edit' onclick='editJob(\""
+ full.groupId + "\",\"" + full.id + "\")'></i>";
}
},
{ "data": "issueDate" },
{ "data": "startDate" },
{ "data": "createdBy" },
{ "data": "createdDate" },
{ "data": "notes" }];
}
}
Is there a way to optimise this so that we don't have to repeat the code just to hide 2 icon links?
You could use the columns.visible option to display/hide the column accordingly.
Additionally, it might be worth looking at Reusable renderers to avoid some of the repetition with the rendering functions.
Creating such a rendering function may look like this:
$.fn.dataTable.render.icon = function ( title, icon, func) {
return function ( data, type, row ) {
return "<i title ='" + title + "' class='fa " + icon + "' onclick='" + func + "(\""
+ row.groupId + "\",\"" + row.id + "\")'></i>";
}
};
You could then use this as follows:
{
//Column visibility
visible: allowedToDelete,
//Reusable renderer
render: $.fn.dataTable.render.icon('Archive Item', 'fa-archive table-icon-view', 'archiveJob')
},
{
visible: allowedToDelete,
render: $.fn.dataTable.render.icon('Edit', 'fa-pencil table-icon-edit', 'editJob')
},
{
visible: allowedToDelete,
render: $.fn.dataTable.render.icon('Delete', 'fa-trash table-icon-delete', 'showDeleteModal')
},
You could have the default array be defined in a variable, and push the 2 icon links into it inside the if, before returning:
function getTableColumns() {
var allowedToDelete = #(User.IsInRole("SysAdmin") || GroupManager.IsUserGroupAdmin(Model.GroupId, User.FindFirst(ClaimTypes.NameIdentifier).Value) ? "true" : "false");
var dataArray = [{ "defaultContent": "" },
{ "data": "deadlineDate", "name": "DeadlineDate" },
{ "data": "priority", "name": "Priority" },
{ "data": "jobNumber", "name": "JobNumber" },
{ "data": "project", "name": "Project" },
{ "data": "description", "name": "Description" },
{ "data": "reference", "name": "Reference" },
{ "data": "subReference", "name": "SubReference" },
{ "data": "employee", "name": "Employee" },
{ "data": "allocatedTo", "name": "AllocatedTo" },
{
"render": function (data, type, full, meta) {
return "<i title ='Edit' class='fa fa-pencil table-icon-edit' onclick='editJob(\""
+ full.groupId + "\",\"" + full.id + "\")'></i>";
}
},
{ "data": "issueDate" },
{ "data": "startDate" },
{ "data": "createdBy" },
{ "data": "createdDate" },
{ "data": "notes" }];
if (allowedToDelete) {
return dataArray.Concat([{
"render": function (data, type, full, meta) {
return "<i title ='Edit' class='fa fa-pencil table-icon-edit' onclick='editJob(\""
+ full.groupId + "\",\"" + full.id + "\")'></i>";
}
},
{
"render": function (data, type, full, meta) {
return "<i title ='Delete' class='fa fa-trash table-icon-delete' onclick='showDeleteModal(\""
+ full.groupId + "\",\"" + full.id + "\")'></i>";
}
}]).ToArray();
} else {
return dataArray;
}
}

Jquery multiply input number value and Json data

I have a time calculation tool which you can find in the following fiddle link. Once someone has selected a platform, task type, component and number of units, the number of units entered should be multiplied with selected component value and show it on the below table. I have managed to get the all populated values but can't do the math. I have tried several attempts but it wasn't working.
var myJson = {
"platforms": [
{
"name": "Sitecore",
"id": "sitecore",
"tasktype": [
{
"name": "Promobox",
"id": "promobox",
"components": [
{
"name": "Accordion",
"id": "accordion",
"time": "20"
},
{
"name": "Box 1",
"id": "box1",
"time": "30"
}
]
},
{
"name": "Video",
"id": "video",
"components": [
{
"name": "Box 2",
"id": "box2",
"time": "25"
},
{
"name": "Box 3",
"id": "box3",
"time": "30"
}
]
}
]
},
{
"name": "Siab",
"id": "siab",
"tasktype": [
{
"name": "Newswire",
"id": "newswire",
"components": [
{
"name": "Box 4",
"id": "box5",
"time": "50"
},
{
"name": "Box 5",
"id": "box5",
"time": "40"
}
]
},
{
"name": "Task Type New",
"id": "tasktypenew",
"components": [
{
"name": "Box 6",
"id": "box6",
"time": "20"
},
{
"name": "Box 7",
"id": "box7",
"time": "100"
}
]
}
]
}
]
};
$.each(myJson.platforms, function (index, value) {
var platform_id;
var tasktype_id;
var component_id;
$("#platform").append('<option rel="' + index + '" value="' + value.id + '">' + value.name + '</option>');
$("#platform").change(function () {
$("#tasktype, #component").find("option:gt(0)").remove();
$("#tasktype").find("option:first").text("Loading...");
platform_id = $(this).find('option:selected').attr('rel');
$.each(myJson.platforms[platform_id].tasktype, function (index1, value1) {
$("#tasktype").find("option:first").text("Select Task Type");
$("#tasktype").append('<option rel="' + index1 + '" value="' + value1.id + '">' + value1.name + '</option>');
});
});
$("#tasktype").change(function () {
$("#component").find("option:gt(0)").remove();
$("#component").find("option:first").text("Loading...");
tasktype_id = $(this).find('option:selected').attr('rel');
$.each(myJson.platforms[platform_id].tasktype[tasktype_id].components, function (index2, value2) {
$("#component").find("option:first").text("Select Component");
$("#component").append('<option rel="' + index2 + '" value="' + value2.time + '">' + value2.name + '</option>');
});
});
});
$(document).ready(function () {
$('#calculate').click(function () {
$('#calc input, #calc select').each(
function (index) {
var input = $(this);
$('#data tbody').append('<tr><td>' + input.val() + '</td></tr>');
});
});
});
JS Fiddle
Ok this took a lot of debugging. You were building your table wrong and not storing data properly. The whole fishing for data was problematic. Here is the debugged calculator:
$(document).ready(function () {
$('#calculate').click(function () {
let tr = $("<tr/>").appendTo("#data tbody");
console.log(tr);
$('#calc input, #calc select').each( function (index) {
console.log($(this));
var input = $(this);
$(tr).append('<td class=row-'+ $(input).attr("id") + '>' + input.val() + '</td>');
});
const componentFactor = $(tr).children(".row-component").text();
const units = $(tr).children(".row-units").text();
const total = componentFactor*units;
$(tr).append('<td>' + total + '</td>');
});
});
notice:
Change of table structure format.
Now appending td's to single tr each time in order to sustain table-row consistency.
Fishing data from row with the help of adding class tag identifier to each td
Showing result.
update fiddle link:
https://jsfiddle.net/x4rLuf88/1/

cant print the json content in table form in jquery

guys i know its dummy question but i have spent alot of hours in this and still cant reach .. i want print the json content in table form .. here is my code
[{
"id": 1,
"name": "name1",
"age": 67,
"feedback": "feedback1"
}, {
"id": 2,
"name": "name2",
"age": 30,
"feedback": "feedback2"
}, {
"id": 3,
"name": "name3",
"age": 59,
"feedback": "feedback3"
}, {
"id": 4,
"name": "name4",
"age": 17,
"feedback": "feedback4"
}]
in javascript
$(document).ready(function() {
$.ajax({
url : 'data.json',
error : function(that, e) {
console.log(e);
},
success : function(data) {
$.each(data, function(index1, MyList) {
$.each(MyList, function(index2, item) {
$('body').append('<div id="div'+ index2+'" />');
$('#div' + index2).append(MyList[index2]);
});
});
}
});
});
here is my output
1234
name1name2name3name4
67305917
feedback1feedback2feedback3feedback4
and i want to make it in table form like this
1 name1 67 feedback1
2 name2 39 feedback2
3 name3 59 feedback3
4 name4 17 feedback4
try this snippet.you dont need two loops. just loop on items and build the bale row markup with data in each item.
data = [{
"id": 1,
"name": "name1",
"age": 67,
"feedback": "feedback1"
}, {
"id": 2,
"name": "name2",
"age": 30,
"feedback": "feedback2"
}, {
"id": 3,
"name": "name3",
"age": 59,
"feedback": "feedback3"
}, {
"id": 4,
"name": "name4",
"age": 17,
"feedback": "feedback4"
}]
var table_markyp = "<table>";
$.each(data, function(i, v) {
table_markyp += '<tr><td>' + v.id + '</td><td>' + v.name + '</td><td>' + v.age + '</td><td>' + v.feedback + '</td><tr>';
})
table_markyp += '</table>';
$('body').append(table_markyp)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
what you can do is , you have to create and HTML structure,
so that all the result will be displayed with a line by line and for that you can follow the table structure,.
check this code.
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
</head>
<body>
</body>
<script type="text/javascript">
$(document).ready(function () {
$.ajax({
url: "data.json",
error : function(that, e) {
console.log(e);
},
success : function(data) {
var Mytable = "<table>";
$.each(data, function(temp, res) {
Mytable +=
'<tr>\n\
<td>' + res.id + '</td>\n\
<td>' + res.name + '</td>\n\
<td>' + res.age + '</td>\n\
<td>' + res.feedback + '</td>\n\
<tr>';
});
Mytable += '</table>';
$('body').append(Mytable);
}
});
});
</script>
</html>
create a container with an id e.g <div id="tablecontainer"> and this below will generate a table with the results
if you want headers you can take one object from data e.g data[0], perform Object.keys(data[0]) and attached them to a <tr/> <th/> object like the row method below
success: function(data) {
var container = $('#tablecontainer');
var table = $('<table></table>');
data.forEach(function(datarow) {
var row = $("<tr />");
for (var item in datarow) {
row.append($("<td>" + datarow[item] + "</td>"));
}
table.append(row);
});
container.append(table);
}
example output with headers:
var data = [{
"id": 1,
"name": "name1",
"age": 67,
"feedback": "feedback1"
}, {
"id": 2,
"name": "name2",
"age": 30,
"feedback": "feedback2"
}, {
"id": 3,
"name": "name3",
"age": 59,
"feedback": "feedback3"
}, {
"id": 4,
"name": "name4",
"age": 17,
"feedback": "feedback4"
}];
var container = $('body');
var table = $('<table></table>');
var head = $("<tr />");
var keys = Object.keys(data[0]);
keys.forEach(function(key){
head.append($("<th>" + key + "</th>"))
})
table.append(head);
data.forEach(function(datarow) {
var row = $("<tr />");
for (var item in datarow) {
row.append($("<td>" + datarow[item] + "</td>"));
}
table.append(row);
});
container.append(table);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Iterate JsonObject

Hi this is my JsonObject i want to iterate this and get the values of title elements class of header , Container and footer.
var jsonObj = [{
"Header": {
"title": "Header",
"element":"div",
"class": "innerElements header",
"id": "",
"contenteditable":"true"
},
"Container": {
"title": "Container",
"element": "div",
"class": "innerElements header",
"id": "",
"contenteditable":"true"
},
"Footer": {
"title": "Container",
"element": "div",
"class": "innerElements header",
"id": "",
"contenteditable": "true"
}
}]
You can do this by
for (var key in jsonObj[0]) {
if (jsonObj[0].hasOwnProperty(key)) {
console.log(key + " -> " + jsonObj[0][key].title);
}
}
Here id the fiddle for this code.
For getting the inner elements from the object we have to extend the previous loop
for (var key in jsonObj[0]) {
if (jsonObj[0].hasOwnProperty(key)) {
console.log(key + " ---");
for(innerKey in jsonObj[0][key]) {
console.log(innerKey + " -> " + jsonObj[0][key][innerKey])
}
console.log("-----")
}
}
Here is the fiddle for above code

Categories

Resources