Introduction
Ever wanted to create a custom webapp which allows recipient data editing without the hussle of coding it from the ground up? look no further than datatables;
DataTables is a powerful JavaScript library for adding advanced interaction controls to HTML tables, enhancing the functionality of standard HTML tables with features such as pagination, searching, filtering, and sorting. (link: https://datatables.net/). Overall, DataTables is a powerful and flexible tool for adding advanced interaction controls to HTML tables, making it easy to work with large datasets and create user-friendly, feature-rich tables for data display and analysis.
In this blog, we will develop a single page web application that provides you with recipient data and allows you to make modifications to this data. The ultimate goal of this web application is to store the modified recipient data in Adobe Campaign.
Sandbox
http://live.datatables.net/xecefabu/1/edit You can use this playground to make changes in your table development in realtime to be then promoted to adobe campaign.
Resources
Include the following files in your header.
<!-- CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.13.1/css/jquery.dataTables.css">
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/searchpanes/2.1.0/css/searchPanes.dataTables.min.css">
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/fixedcolumns/4.2.1/css/fixedColumns.dataTables.min.css">
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/select/1.5.0/css/select.dataTables.min.css">
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/buttons/2.3.2/css/buttons.dataTables.min.css">
<!-- JavaScript -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.1/jquery.js" integrity="sha512-CX7sDOp7UTAq+i1FYIlf9Uo27x4os+kGeoT7rgwvY+4dmjqV0IuE/Bl5hVsjnQPQiTOhAX1O2r2j5bjsFBvv/A==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4" crossorigin="anonymous"></script>
<script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.13.1/js/jquery.dataTables.js"></script>
<script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/searchpanes/2.1.0/js/dataTables.searchPanes.min.js"></script>
<script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/fixedcolumns/4.2.1/js/dataTables.fixedColumns.min.js"></script>
<script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/select/1.5.0/js/dataTables.select.min.js"></script>
<script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/buttons/2.3.2/js/dataTables.buttons.min.js"></script>
- Buttons: Provides an API framework which performs unique actions to your applications.
- Select: Select adds item selection capabilities to a DataTable. Items can be rows, columns or cells, which can be selected independently, or together.
- Fixed Columns: Allows to fix/sticky left or right columns in place.
- Search Panes: Provides accessible, intuitive and interactive search filters with advanced custom search capabilities.
Data Sources:
DataTables can obtain data from four different fundamental sources:
- HTML document (DOM)
- Javascript (array / objects)
- Ajax sourced data with client-side processing
- Ajax sourced data with server-side processing
Recipient Data
As the purpose of this blog is to develop a single page application, we will construct a query script that can be executed from the front end by posting the encoded query to endpoint: "/xtk/queryList.jssp" which returns response in javascript object.
example:
var recipientQuery = {
"operation":"select", "schema":"nms:recipient",
"startLine":0, "lineCount":999,
"select":{
"node":[
{"expr":"@id"},
{"expr":"@firstName+' '+@lastName","alias":"@name"},
{"expr":"@email"},
{"expr":"@phone"},
{"expr":"@blackList"},
{"expr":"@status"},
],
},
"where":{
"condition":[{"expr":"@id <> 0"}]
},
"orderBy":{
"node":[{"expr":"@id"}]
},
};
$.post("/xtk/queryList.jssp", {queryDef:encodeURIComponent(JSON.stringify(recipientQuery))}, function(recipientResponse) {
The above script will return an array objects containing all key:data pairs and will be used as the source to initialize our datatables table.
{
"blackList": "0",
"email": "500002@email.com",
"id": "13218257",
"name": "500002 - First Name Test Edit 500002 - Last Name",
"phone": "12345",
"status": "6",
"_schema": "nms:recipient"
}
Complete JS script
Head over to https://datatables.net/examples/advanced_init/ to understand all datatables options used in this script.
<script type="text/javascript">// <![CDATA[
//function to add a loading spinner
$(window).on('load', function(){
$('#cover').fadeOut(1000);
})
//highlight recipients who are blacklisted
function blacklistCheck(row) {
if (row.blackList == 1) {
return '<span class="recipient-blacklisted">' + row.name + '</span>'
} else {
return '<span class="recipient-notblacklisted">' + row.name + '</span>'
}
}
//render integer status to string equivalent
function statusRender(i){
switch(parseInt(i)) {
case 1:
return 'Subscriber';
break;
case 2:
return 'Lead';
break;
case 3:
return 'MQL';
break;
case 4:
return 'SQL';
break;
case 5:
return 'Opportunity';
break;
case 6:
return 'Client';
break;
default:
return '0';
}
}
jQuery( document ).ready(function() {
//query recipient json script
var recipientQuery = {
"operation":"select", "schema":"nms:recipient",
"startLine":0, "lineCount":99999,
"select":{
"node":[
{"expr":"@id"},
{"expr":"@firstName+' '+@lastName","alias":"@name"},
{"expr":"@email"},
{"expr":"@phone"},
{"expr":"@blackList"},
{"expr":"@status"},
],
},
"where":{
"condition":[{"expr":"@id <> 0"}]
},
"orderBy":{
"node":[{"expr":"@id"}]
},
};
//post to endpoint
$.post("/xtk/queryList.jssp", {queryDef:encodeURIComponent(JSON.stringify(recipientQuery))}, function(recipientResponse) {
//define columns used in table
var colsDef = [
{data: null, defaultContent:'', orderable: false, className: 'select-checkbox',title:'<input type="checkbox" id="select_all" class="" title="Select All" />'},
{data: null ,defaultContent:'',render: function (data, type, row, meta) {return meta.row;}},
{data: 'id', title: 'id' },
{data: 'name', title: 'Recipient',render: function (data, type, row, meta) {return blacklistCheck(row)}},
{data: 'email', title: 'Email' },
{data: 'phone', title: 'Phone' },
{data: 'blackList', title: ' Blacklist'},
{data: 'status', title: 'Status', render: function (data, type, row, meta) {return statusRender(data)}},
];
/** datatables ini **/
var table= $('#recipients').DataTable({
data:recipientResponse.data,
stateSave: false,
responsive: true,
select: true,
dom: 'PBfrtip',
deferRender: true,
paging: true,
scrollY: 400,
scrollX: true,
scrollCollapse: true,
fixedColumns:{left: 2},
buttons: [{
text: 'Submit',
action: function(e, dt, type, indexes) {
/****************doSomething ****************/
var selectedRecipients = [];
table.rows({ selected: true } ).every( function ( rowIdx, tableLoop, rowLoop ) {
var data = this.data();
selectedRecipients.push({recipient:data.id})
});
console.log(selectedRecipients)
/***************************************/
}
}, ],
columns:colsDef,
language: {
searchPanes: {
count: '{total} records',
countFiltered: '{shown} / {total}',
}
},
searchPanes: {cascadePanes: true, viewTotal: true},
columnDefs: [
{ targets: [1], visible:false},
//{ searchPanes: {show: true, initCollapsed: true},targets: [1,2 },
//{ searchPanes: {show: false}, targets: [1,2] }
],
select: {style:'multi', selector: 'td:first-child'}, order: [[ 1, 'asc' ]],
});//table ini
});// recipientResponse
/**JS: Select All ***/
$('#select_all').on('click', function() {
if ($('#select_all:checked').val() === 'on') {
table.rows().select();
} else {
table.rows().deselect();
}
});
//$('#recipients').DataTable().state.clear();
});
// ]]></script>
End product
WebApp backend
WebApp Frontend
Full page download ( acc-spa-webapp-code.docx)
AC Tips & Tricks: datatables jQuery plugin+ single page webapp [PART 2](TBC)
Part 2 will look at how to use front end inline editing to modify recipient data.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.