Web Interfaces of PROSUME

datatable.ctp 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. <script>
  2. // DOM elements declaration
  3. var dataTable;
  4. var searchButton;
  5. var exportButton;
  6. var searchInput;
  7. var searchReset;
  8. var meterSelect;
  9. var pickerElement;
  10. var pickerCallback;
  11. var periodRadio;
  12. // general configuration
  13. var dataTableConfiguration = {
  14. "order": [[ 0, 'desc' ]],
  15. "deferRender": true,
  16. "responsive": true,
  17. "pageLength": 50,
  18. "searching": false,
  19. "language": {
  20. "sEmptyTable": "No records found",
  21. "sInfo": "Viewing records from _START_ to _END_ of _TOTAL_",
  22. "sInfoEmpty": "Viewing from 0 to 0 of 0 records",
  23. // "sInfoFiltered": "(filtered _MAX_ records)",
  24. "sInfoPostFix": "",
  25. "sInfoThousands": ".",
  26. "sLengthMenu": "Viewing _MENU_ records",
  27. "sLoadingRecords": "Loading...",
  28. "sProcessing": "Calculating...",
  29. "sSearch": "Search:",
  30. "sZeroRecords": "No records found.",
  31. "oPaginate": {
  32. "sFirst": "Start",
  33. "sPrevious": "Previous",
  34. "sNext": "Next",
  35. "sLast": "End"
  36. },
  37. "oAria": {
  38. "sSortAscending": ": sort the column in ascending order",
  39. "sSortDescending": ": sort the column in descending order"
  40. }
  41. }
  42. };
  43. var historyDataTableConfiguration = {
  44. "initComplete": function() {
  45. $('#exportButtonWrapper').removeClass("hidden");
  46. $('#periodInputWrapper').removeClass("hidden");
  47. $('#searchInputWrapper').removeClass("hidden");
  48. },
  49. "processing": true,
  50. "serverSide": true,
  51. "ajax": {
  52. url : "/xhr/history",
  53. data: function(data) {
  54. data.meter = meterSelect.val();
  55. data.txid = searchInput.val();
  56. data.from = pickerElement.getAttribute("data-from");
  57. data.to = pickerElement.getAttribute("data-to");
  58. data.period = $('input[name=periodRadio]:checked').val();
  59. },
  60. type: "GET",
  61. contentType: "application/json",
  62. headers: {
  63. "X-CSRF-Token": <?= json_encode($this->request->getParam('_csrfToken')) ?>
  64. },
  65. dataType : "json"
  66. },
  67. "columns": [
  68. { "data": "timestamp", "render": function (data, type, row) { return row.id == null ? data : '<a href="/web/block/'+row.id+'">'+data+'</a>'; } },
  69. { "data": "txID", "className": "cell-fixed", "render": function (data) { return '<div class="cell-clip">'+(data == null ? '' : data)+'</div>'; } },
  70. { "data": "wallet_from", "render": function (data) { return '<a href="/web/meter/'+data+'">'+data+'</a>'; } },
  71. { "data": "wallet_to", "render": function (data) { return '<a href="/web/meter/'+data+'">'+data+'</a>'; } },
  72. { "data": "asset" },
  73. { "data": "type" },
  74. { "name": "Value", "data": "amount", "type": "number", "render": function (data) { return data == null ? '-' : data % 1 == 0 ? parseInt(data) : data;} },
  75. { "name": "Purchased/Sold Energy", "data": "energyDiff", "type": "number", "render": function (data) { return data == null ? '-' : data % 1 == 0 ? parseInt(data) : data;} }
  76. ]
  77. };
  78. var paymentDataTableConfiguration = {
  79. "initComplete": function() {
  80. $('#exportButtonWrapper').removeClass("hidden");
  81. $('#periodInputWrapper').removeClass("hidden");
  82. },
  83. "processing": true,
  84. "serverSide": true,
  85. "ajax": {
  86. url : "/xhr/payment",
  87. data: function(data) {
  88. data.meter = meterSelect.val();
  89. data.from = pickerElement.getAttribute("data-from");
  90. data.to = pickerElement.getAttribute("data-to");
  91. data.period = $('input[name=periodRadio]:checked').val();
  92. },
  93. type: "GET",
  94. contentType: "application/json",
  95. headers: {
  96. "X-CSRF-Token": <?= json_encode($this->request->getParam('_csrfToken')) ?>
  97. },
  98. dataType : "json"
  99. },
  100. "columns": [
  101. { "data": "timestamp", "render": function (data, type, row) { return row.id == null ? data : '<a href="/web/block/'+row.id+'">'+data+'</a>'; } },
  102. { "data": "wallet_from", "render": function (data) { return '<a href="/web/meter/'+data+'">'+data+'</a>'; } },
  103. { "data": "wallet_to", "render": function (data) { return '<a href="/web/meter/'+data+'">'+data+'</a>'; } },
  104. { "data": "amount", "type": "number", "render": function (data) { return data == null ? '-' : data % 1 == 0 ? parseInt(data) : data;} },
  105. { "data": "asset" }
  106. ]
  107. };
  108. var priceHistoryDataTableConfiguration = {
  109. "initComplete": function() {
  110. $('#exportButtonWrapper').removeClass("hidden");
  111. },
  112. "processing": true,
  113. "serverSide": true,
  114. "ajax": {
  115. url : "/xhr/price/history",
  116. data: function(data) {
  117. data.meter = meterSelect.val();
  118. data.from = pickerElement.getAttribute("data-from");
  119. data.to = pickerElement.getAttribute("data-to");
  120. },
  121. type: "GET",
  122. contentType: "application/json",
  123. headers: {
  124. "X-CSRF-Token": <?= json_encode($this->request->getParam('_csrfToken')) ?>
  125. },
  126. dataType : "json"
  127. },
  128. "columns": [
  129. { "data": "timestamp", "render": function (data, type, row) { return row.id == null ? data : '<a href="/web/block/'+row.id+'">'+data+'</a>'; } },
  130. { "data": "wallet_from", "render": function (data) { return '<a href="/web/meter/'+data+'">'+data+'</a>'; } },
  131. { "data": "wallet_to", "render": function (data) { return '<a href="/web/meter/'+data+'">'+data+'</a>'; } },
  132. { "data": "buyPrice", "type": "number", "render": function (data) { return data == null ? '-' : data % 1 == 0 ? parseInt(data) : data;} },
  133. { "data": "sellPrice", "type": "number", "render": function (data) { return data == null ? '-' : data % 1 == 0 ? parseInt(data) : data;} }
  134. ]
  135. };
  136. var transferDataTableConfiguration = {
  137. "autoWidth": false,
  138. "initComplete": function() {
  139. var $periodRadio = $('input:radio[name=periodRadio]');
  140. $periodRadio.filter('[value=0]').prop('checked', false);
  141. $periodRadio.filter('[value=2]').prop('checked', true);
  142. $('#periodInputWrapper').removeClass("hidden");
  143. $('#searchInputWrapper').removeClass("hidden");
  144. $('#searchInputWrapper').hide();
  145. },
  146. "processing": true,
  147. "serverSide": true,
  148. "ajax": {
  149. url : "/xhr/historyTransfer",
  150. data: function(data) {
  151. data.meter = meterSelect.val();
  152. data.txid = searchInput.val();
  153. data.from = pickerElement.getAttribute("data-from");
  154. data.to = pickerElement.getAttribute("data-to");
  155. data.period = $('#periodInputWrapper').hasClass("hidden") ? 2 : $('input[name=periodRadio]:checked').val();
  156. },
  157. type: "GET",
  158. contentType: "application/json",
  159. headers: {
  160. "X-CSRF-Token": <?= json_encode($this->request->getParam('_csrfToken')) ?>
  161. },
  162. dataType : "json"
  163. },
  164. "columns": [
  165. { "data": "timestamp", "render": function (data, type, row) { return row.id == null ? data : '<a href="/web/block/'+row.id+'">'+data+'</a>'; } },
  166. { "data": "wallet_from", "render": function (data) { return '<a href="/web/balance/'+data+'">'+data+'</a>'; } },
  167. { "data": "wallet_to", "render": function (data) { return '<a href="/web/balance/'+data+'">'+data+'</a>'; } },
  168. { "data": "asset" },
  169. { "name": "Value", "data": "amount", "type": "number", "render": function (data) { return data == null ? '-' : data % 1 == 0 ? parseInt(data) : data;} },
  170. { "data": "mv", "width": "30%" },
  171. ]
  172. };
  173. // jquery document ready functions
  174. $(document).ready(function() {
  175. // searchButton event listener
  176. searchButton = $("#searchButton");
  177. searchInput = $("#searchInput");
  178. searchReset = $("#searchReset");
  179. searchButton.click(function () {
  180. dataTable.search(searchInput.val()).draw();
  181. });
  182. searchReset.click(function () {
  183. searchInput.val("");
  184. dataTable.search("").draw();
  185. });
  186. // meterSelect event listener
  187. meterSelect = $('#meterSelect');
  188. meterSelect.change( function() {
  189. dataTable.draw();
  190. });
  191. // periodRadio event listener
  192. periodRadio = $('input[name=periodRadio]');
  193. periodRadio.change( function() {
  194. dataTable.draw();
  195. });
  196. // exportButton event listener
  197. exportButton = $("#exportButton");
  198. exportButton.click(function () {
  199. window.open(dataTable.ajax.url()+"?format=csv&"+$.param(dataTable.ajax.params()));
  200. });
  201. // pickerSelect element and event listener
  202. pickerElement = document.getElementById('pickerSelect');
  203. pickerCallback = function() { dataTable.draw(); };
  204. var _ = getDate();
  205. _.setHours(23);_.setMinutes(59);
  206. var defaultDate = getDateString(_);
  207. var _min = getDate();
  208. _min.setDate(_min.getDate() - 60);
  209. if(pickerElement != null) {
  210. pickerElement.setAttribute("data-from", getDateString(_min));
  211. pickerElement.setAttribute("data-to", defaultDate);
  212. var picker = flatpickr(pickerElement, {
  213. enableTime: false,
  214. maxDate: defaultDate,
  215. mode: 'range',
  216. time_24hr: true,
  217. defaultDate: [getDateString(_min), defaultDate],
  218. onClose: function(selectedDates) {
  219. let dates = selectedDates.map(d => getDate(d));
  220. dates[0] == null && dates.push(defaultDate);
  221. dates[1] == null && dates.push(dates[0]);
  222. if((Math.round(dates[1].getTime() / 1000)) - (Math.round(dates[0].getTime() / 1000)) > 5184000) {
  223. alert("Max date range is 60 days, please select a different period");
  224. return;
  225. }
  226. dates[1].setHours(23);dates[1].setMinutes(59);
  227. pickerElement.setAttribute("data-from", getDateString(dates[0]));
  228. pickerElement.setAttribute("data-to", getDateString(dates[1]));
  229. pickerCallback();
  230. }
  231. });
  232. $('#meterReset').click( function() {
  233. meterSelect.find("option:selected").prop("selected", false);
  234. meterSelect.find("option:first").prop("selected", "selected");
  235. meterSelect.val(meterSelect.find("option:first").val()).change();
  236. });
  237. $('#pickerReset').click( function() {
  238. picker.clear();
  239. picker.setDate([getDateString(_min), defaultDate]),
  240. pickerElement.setAttribute("data-from", getDateString(_min));
  241. pickerElement.setAttribute("data-to", defaultDate);
  242. dataTable.draw();
  243. });
  244. }
  245. // datatable init
  246. objShallowMerge(dataTableConfiguration, <?php echo isset($dataTableConfiguration) ? $dataTableConfiguration : "{}"; ?>)
  247. dataTable = $('#valueTable').DataTable(dataTableConfiguration);
  248. dataTable.on('processing.dt', function (e, settings, processing) {
  249. var overlay = $("#eprosume_overlay");
  250. if (processing) {
  251. overlay.show();
  252. } else {
  253. overlay.hide();
  254. }
  255. });
  256. });
  257. </script>