nbm-wx-elements-table

An error occurred while processing the template.
The following has evaluated to null or missing:
==> DefaultSortDirection  [in template "10132#10165#8470755" at line 194, column 6]

----
Tip: If the failing expression is known to be legally refer to something that's sometimes null or missing, either specify a default value like myOptionalVar!myDefault, or use <#if myOptionalVar??>when-present<#else>when-missing</#if>. (These only cover the last step of the expression; to cover the whole expression, use parenthesis: (myOptionalVar.foo)!myDefault, (myOptionalVar.foo)??
----

----
FTL stack trace ("~" means nesting-related):
	- Failed at: #if DefaultSortDirection.getData()?ha...  [in template "10132#10165#8470755" at line 194, column 1]
----
1<link href="/o/vlcs_dxp_theme/js/library/datatables/boostrap4/datatables.min.css" rel="stylesheet" type="text/css" /> 
2 
3<#assign themeId = themeDisplay.getThemeId() /> 
4<#assign VLCS_DXP_THEME =  "vlcs_dxp_theme_WAR_vlcs_dxp_theme" /> 
5 
6<style type="text/css"> 
7 
8.csv-alert .close { 
9       font-size: 2rem; 
10
11 
12div.dataTables_wrapper .dt-buttons .btn { 
13 
14padding: .25rem .5rem; 
15    font-size: .875rem; 
16<#if themeId == VLCS_DXP_THEME > 
17    font-size: 1.2em !important; 
18</#if> 
19    line-height: 1.5; 
20
21  
22div.dataTables_wrapper  div.dataTables_paginate ul.pagination { 
23    margin: 2px 0; 
24    white-space: nowrap; 
25    justify-content: flex-end; 
26
27 
28.pagination { 
29  display: -ms-flexbox; 
30  display: flex; 
31  padding-left: 0; 
32  list-style: none; 
33  border-radius: 0.25rem; 
34
35 
36.page-link { 
37  position: relative !important; 
38  display: block !important; 
39  padding: 0.5rem 0.75rem !important; 
40  margin-left: -1px !important; 
41  line-height: 1.25 !important; 
42  color: #239ded !important; 
43  background-color: #fff !important; 
44  border: 1px solid #dee2e6 !important; 
45  border-radius: 0  !important; 
46
47 
48.page-link:hover { 
49  z-index: 2; 
50  color: #0056b3 !important; 
51  text-decoration: none !important; 
52  background-color: #e9ecef !important; 
53  border-color: #dee2e6 !important; 
54
55 
56.page-link:focus { 
57  z-index: 2; 
58  outline: 0; 
59  box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25) !important; 
60
61 
62.page-link:not(:disabled):not(.disabled) { 
63  cursor: pointer; 
64
65 
66.page-item:first-child .page-link { 
67  margin-left: 0; 
68  border-top-left-radius: 0.25rem; 
69  border-bottom-left-radius: 0.25rem; 
70
71 
72.page-item:last-child .page-link { 
73  border-top-right-radius: 0.25rem; 
74  border-bottom-right-radius: 0.25rem; 
75
76 
77.page-item.active .page-link { 
78  z-index: 1; 
79  color: #fff !important; 
80  background-color: #239ded !important; 
81  border-color: #239ded !important; 
82
83 
84.page-item.disabled .page-link { 
85  color: #6c757d; 
86  pointer-events: none; 
87  cursor: auto; 
88  background-color: #fff; 
89  border:none !important; 
90
91 
92.pagination-lg .page-link { 
93  padding: 0.75rem 1.5rem; 
94  font-size: 1.25rem; 
95  line-height: 1.5; 
96
97 
98.pagination-lg .page-item:first-child .page-link { 
99  border-top-left-radius: 0.3rem; 
100  border-bottom-left-radius: 0.3rem; 
101
102 
103.pagination-lg .page-item:last-child .page-link { 
104  border-top-right-radius: 0.3rem; 
105  border-bottom-right-radius: 0.3rem; 
106
107 
108.pagination-sm .page-link { 
109  padding: 0.25rem 0.5rem; 
110  font-size: 0.875rem; 
111  line-height: 1.5; 
112
113 
114.pagination-sm .page-item:first-child .page-link { 
115  border-top-left-radius: 0.2rem; 
116  border-bottom-left-radius: 0.2rem; 
117
118 
119.pagination-sm .page-item:last-child .page-link { 
120  border-top-right-radius: 0.2rem; 
121  border-bottom-right-radius: 0.2rem; 
122
123 
124 
125.dataTables_wrapper .form-control { 
126    width:auto !important; 
127
128 
129#dataTable_filter  select { 
130    width:200px !important; 
131
132 
133 
134#view-select.nav-pills>li.active>a { 
135    background-color: #239ded; 
136    color: #FFF; 
137     
138    border-bottom-left-radius: 0rem; 
139    border-bottom-right-radius: 0rem; 
140
141 
142#view-select.nav-pills { 
143    border-bottom: 1px solid #dee2e6;  
144    box-shadow: 0 3px 2px -2px gray; 
145
146 
147#map { 
148    margin-bottom:20px; 
149
150 
151table.dataTable tr.dtrg-group td { 
152    background-color:#f1f2f5; /*#6c757d;*/ 
153    color:#239ded; 
154
155 
156table.dataTable td , table.dataTable th { 
157    padding:0.35rem; 
158    border-color: #272834 !important; 
159<#if themeId != VLCS_DXP_THEME > 
160    font-size: 1rem; 
161</#if> 
162
163 
164</style> 
165 
166<!--ul> 
167	<li><a class="group-by btn btn-default" data-column="Products" href="javascript:void(0);">Group by Products</a></li> 
168	<li><a class="group-by btn btn-default" data-column="State/Region" href="javascript:void(0);">Group by State/Region</a></li> 
169</ul--> 
170 
171<script src="https://cdn.jsdelivr.net/npm/moment@2.18.1/min/moment-with-locales.min.js"></script> 
172<script src="/o/vlcs_dxp_theme/js/library/datatables/boostrap4/datatables.min.js"></script> 
173<script src="https://cdn.datatables.net/1.10.20/js/dataTables.bootstrap4.min.js"></script> 
174<script src="/o/vlcs_dxp_theme/js/library/d3.min.js"></script> 
175 
176<div class="loading-animation csv-alert-message" role="alert">&nbsp;</div> 
177<table class="table thead-dark table-striped table-bordered" id="dataTable" width="100%"> 
178</table> 
179 
180<script type="text/javascript"> 
181var csvFile = "${CSVFile.getData()}"; 
182<#if ColumnNames.getData()?has_content > 
183    var COLUMNS = "${ColumnNames.getData()?js_string}"; 
184<#else> 
185var COLUMNS = ""; 
186</#if> 
187 
188<#if DefaultSortColumn.getData()?has_content > 
189    var DEFAULT_SORT_COL = "${DefaultSortColumn.getData()?js_string}"; 
190<#else> 
191    var DEFAULT_SORT_COL = ""; 
192</#if> 
193 
194<#if DefaultSortDirection.getData()?has_content > 
195    var DEFAULT_SORT_DIRECTION = "${DefaultSortDirection.getData()}"; 
196<#else> 
197    var DEFAULT_SORT_DIRECTION = "desc"; 
198</#if> 
199 
200<#if GroupByColumns.getData()?has_content > 
201    var GROUPBY_COL = "${GroupByColumns.getData()?js_string}"; 
202    var GROUPBY_COLS = GROUPBY_COL.split(","); 
203<#else> 
204    var GROUPBY_COL = ""; 
205</#if> 
206 
207var DROPDOWN_COLS = []; 
208 
209<#if DropdownSelectionColumnNames.getData()?has_content> 
210    var DROPDOWN_COLS = "${DropdownSelectionColumnNames.getData()?js_string}"; 
211    var DROPDOWN_COLS = DROPDOWN_COLS.split(","); 
212</#if> 
213 
214$( document ).ready(function() { 
215var timer = { 
216    start: moment() 
217}; 
218d3.csv(csvFile).then( function(rows)  { 
219                    var columnNames = Object.keys(rows[0]); 
220                     
221                    // check if columnNames and COLUMNS matched 
222                    // display message if not matching  
223                    // use columnNames if COLUMNS is not set 
224                    var selectedColumns = COLUMNS.toLowerCase().split(","); 
225                    dtTable = $("#dataTable").DataTable({ 
226                        "responsive": true, 
227                        dom: 'Bfrtlip', 
228                        lengthChange:true, 
229                        language: { 
230                                search: "_INPUT_", 
231                                searchPlaceholder: "Search..." 
232                         }, 
233                        buttons: [ 'copy', 'csv',  'print'], 
234                        "lengthMenu": [[ 25, 50, 100, -1], [25, 50,100, "All"]], 
235                        "data": rows, 
236                        "columns": Object.keys(rows[0]).map(c => ({ 
237                            "title": c, 
238                            "data": c, 
239                     
240                            <#if ColumnNames.getData()?has_content > 
241                            "visible":  selectedColumns.indexOf(c.toLowerCase()) != -1, 
242                            "responsivePriority": selectedColumns.indexOf(c.toLowerCase()), 
243                            <#else> 
244                                "visible":true, 
245                            </#if> 
246                            "default": "" 
247                        })), 
248       <#if DefaultSortColumn.getData()?has_content > 
249                        "order": [[columnNames.indexOf(DEFAULT_SORT_COL), DEFAULT_SORT_DIRECTION]], 
250       </#if> 
251       <#if  GroupByColumns.getData()?has_content >            
252                        rowGroup: { 
253                            dataSrc: GROUPBY_COLS[0] 
254                 
255                        orderFixed: [[columnNames.indexOf(GROUPBY_COLS[0]), 'asc']], 
256        </#if> 
257                         
258                        "drawCallback": function(settings) { 
259                         
260                            timer.end = moment(); 
261                            var duration = moment.duration(timer.end.diff(timer.start)); 
262                            var msg = "Take <strong>" + duration.asSeconds() +  "</strong> seconds to load"; 
263                            displayMessage(msg, true, true); 
264 
265                            /*var closeBtn = '<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>'; 
266                            $(".loading-animation").html("Take <strong>" + duration.asSeconds() +  "</strong> seconds to load" + closeBtn); 
267                            $(".loading-animation").removeClass("loading-animation").addClass("alert alert-success alert-dismissible fade show").fadeOut( 1600); 
268                            */ 
269                        }, 
270 
271                        initComplete: function(){ 
272                                $('.dataTables_filter').append('<button class="btn btn-primary btn-sm clear-search ml-2">Reset</button>'); 
273                                $('.clear-search').on('click', function() { 
274                                    $.each(DROPDOWN_COLS, function( index, value ) { 
275                                        $('#' + getValidHtmlId(value)).val("").change(); 
276                                     }); 
277                                    dtTable.search('').draw(); 
278                            });                       
279
280                    }); 
281               
282                     
283        dtTable.buttons().container().appendTo( '#dataTable_wrapper .col-md-6:eq(0)' ); 
284        $( '#dataTable_wrapper .row:eq(0) .col-sm-12:eq(0)' ).removeClass("col-md-6").addClass("col-md-2"); 
285        $( '#dataTable_wrapper .row:eq(0) .col-sm-12:eq(1)' ).removeClass("col-md-6").addClass("col-md-10"); 
286 
287        <#if  GroupByColumns.getData()?has_content >        
288        // Change the fixed ordering when the data source is updated 
289        dtTable.on( 'rowgroup-datasrc', function ( e, dt, val ) { 
290                dtTable.order.fixed( {pre: [[ columnNames.indexOf(val), 'asc' ]]} ).draw(); 
291        }); 
292        </#if> 
293        
294       // dropdown select display 
295        
296       $.each(DROPDOWN_COLS, function( index, value ) { 
297            displayDropdownColumnSelect(dtTable, columnNames, value); 
298         }); 
299          
300        <#if  GroupByColumns.getData()?has_content >  
301                  displayGroupByColumnSelect(dtTable, columnNames, GROUPBY_COLS ); 
302        </#if>  
303 
304    }).catch(function(error) { 
305        // handling error 
306         
307        displayMessage("Cannot read given CSV file, " + csvFile + ".",true, false) 
308    });   // d3 csv load 
309 
310});  // end document ready 
311 
312 
313function displayMessage(message,isLoadingAnimation,isFading) { 
314      var closeBtn = '<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>'; 
315      $(".csv-alert-message").html(message + closeBtn); 
316      if(isLoadingAnimation) { 
317          $(".csv-alert-message").removeClass("loading-animation").addClass("alert alert-success alert-dismissible fade show"); 
318
319      if(isFading) { 
320         $(".csv-alert-message").fadeOut( 2000); 
321
322
323 
324function displayDropdownColumnSelect(dataTable, columnNames, ddColumnName  ) { 
325 
326                    console.log("display dd column select") 
327                    var columnIndex = columnNames.indexOf(ddColumnName); 
328                    var values =dataTable.column(columnIndex).data().unique(); 
329 
330                    if(values.length ==0 || values.length >75) { 
331                         
332                        var str =  "Column " + ddColumnName + " have number of entries are not suitable for dropdown values " + values.length ; 
333                         
334                        console.log(str); 
335
336                     
337                    var id = getValidHtmlId(ddColumnName) 
338                    $('#dataTable_wrapper .dataTables_filter').prepend('<label for="' + 
339                    id + '" class="sr-only">Select for ' + ddColumnName + '</label><select id="' + 
340                    id + '" class="form-control d-inline form-control-sm mr-2"><option value="">Select ' + ddColumnName + '</option></select>'); 
341 
342                    $.each(values, function( index, value ) { 
343                            $("#" + id) 
344                                .append($("<option></option>") 
345                                .attr("value",value) 
346                                .text(value)); 
347 
348                            }); 
349 
350                    $("#" + id).change(function () { 
351                                var selectedValue = $(this). children("option:selected"). val(); 
352                                dataTable 
353                                .columns(columnIndex) 
354                                .search( selectedValue ) 
355                                .draw(); 
356                    }).change(); 
357                             
358
359 
360function displayGroupByColumnSelect(dataTable, columnNames, gbColumnNames  ) { 
361 
362                    var id = "groupby-select"; 
363                    $('#dataTable_wrapper .dataTables_filter').prepend('<label for="' + 
364                    id + '" class="sr-only">Select for Group By Column</label><select id="' + 
365                    id + '" class="form-control d-inline form-control-sm mr-2"></select>'); 
366 
367                    $.each(gbColumnNames, function( index, value ) { 
368                            $("#" + id) 
369                                .append($("<option></option>") 
370                                .attr("value",value) 
371                                .text("Group By " + value)); 
372                            }); 
373 
374                    $("#" + id).change(function () { 
375                        console.log("group by change handler"); 
376                        var selectedValue = $(this). children("option:selected").val(); 
377                        console.log(selectedValue); 
378                        dataTable.rowGroup().dataSrc(selectedValue); 
379                    }).change();                             
380
381 
382function getValidHtmlId(str) { 
383    return str.replace(/[^A-Z0-9]+/ig, "_"); 
384
385 
386 
387</script> 

NBM