You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

211 lines
6.8 KiB

​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
  1. $(document).ready(function () {
  2. // Initialize DataTable
  3. var table = $('#oc-file-det-tbl').DataTable({
  4. paging: true,
  5. searching: true,
  6. ordering: true,
  7. lengthChange: true,
  8. pageLength: 10,
  9. language: {
  10. emptyTable: "No data available",
  11. lengthMenu: "Display _MENU_ records per page",
  12. info: "Showing _START_ to _END_ of _TOTAL_ entries",
  13. infoEmpty: "No records to show",
  14. infoFiltered: "(filtered from _MAX_ total records)"
  15. },
  16. columnDefs: [
  17. {
  18. orderable: false,
  19. targets: [0, 5] // S.No and OC File columns
  20. }
  21. ],
  22. buttons: [
  23. {
  24. extend: 'excelHtml5',
  25. title: "OC File Details",
  26. filename: "OC File Details",
  27. exportOptions: {
  28. columns: ':visible:not(:eq(5))', // exclude OC File column
  29. format: {
  30. body: function (data, row, column, node) {
  31. if (column === 0) {
  32. return row + 1;
  33. }
  34. return $('<div>').html(data).text().trim();
  35. }
  36. }
  37. }
  38. },
  39. 'pdfHtml5'
  40. ]
  41. });
  42. // --- SEQUENTIAL S.NO FIX ---
  43. table.on('order.dt search.dt draw.dt', function () {
  44. var pageInfo = table.page.info();
  45. table.column(0, { page: 'current' }).nodes().each(function (cell, i) {
  46. cell.innerHTML = pageInfo.start + i + 1;
  47. });
  48. }).draw();
  49. // Move DataTable controls to custom containers
  50. $('#custom-pagination').html($('.dataTables_paginate'));
  51. $('#custom-info').html($('.dataTables_info'));
  52. $('#custom-length').html($('.dataTables_length'));
  53. $('.dataTables_filter').hide(); // hide default search
  54. // Custom search / filtering on the datatable
  55. $('#export-excel').on('click', function () {
  56. table.button('.buttons-excel').trigger();
  57. });
  58. $('#export-pdf').on('click', function () {
  59. var originalLength = table.page.len();
  60. table.one('draw', function () {
  61. var tableClone = $('#oc-file-det-tbl').clone();
  62. tableClone.removeClass('dataTable');
  63. tableClone.find('thead, tbody, tfoot').removeAttr('style');
  64. // Remove "OC File" column (6th col = index 5)
  65. tableClone.find('tr').each(function () {
  66. $(this).find('th:eq(5), td:eq(5)').remove();
  67. });
  68. var pdfContainer = $('#pdf-print-container');
  69. if (!pdfContainer.length) {
  70. $('body').append('<div id="pdf-print-container" style="display:none;"></div>');
  71. pdfContainer = $('#pdf-print-container');
  72. }
  73. pdfContainer.html('<h2 style="text-align:center;">OC File Details</h2>');
  74. pdfContainer.append(tableClone).css({ display: 'block', padding: '20px' });
  75. tableClone.css({ width: '100%', borderCollapse: 'collapse' });
  76. tableClone.find('th, td').css({
  77. border: '1px solid #ccc',
  78. padding: '5px',
  79. fontSize: '10px',
  80. textAlign: 'left',
  81. verticalAlign: 'top'
  82. });
  83. tableClone.find('tr').css({ pageBreakInside: 'avoid', breakInside: 'avoid', webkitBreakInside: 'avoid' });
  84. html2pdf().set({
  85. margin: 0.5,
  86. filename: 'OC File Details.pdf',
  87. image: { type: 'jpeg', quality: 0.98 },
  88. html2canvas: { scale: 2, useCORS: true },
  89. jsPDF: { unit: 'in', format: 'a3', orientation: 'landscape' }
  90. }).from(pdfContainer[0]).save().then(function () {
  91. table.page.len(originalLength).draw();
  92. pdfContainer.hide();
  93. });
  94. });
  95. table.page.len(-1).draw(); // show all rows for PDF
  96. });
  97. function populateFilters() {
  98. var numSet = {}, vendSet = {};
  99. table.rows().every(function () {
  100. var data = this.data();
  101. var fileNum = data[1] ? $('<div>').html(data[1]).text().trim() : '';
  102. var vendName = data[2] ? $('<div>').html(data[2]).text().trim() : '';
  103. if (fileNum) numSet[fileNum] = true;
  104. if (vendName) vendSet[vendName] = true;
  105. });
  106. Object.keys(numSet).sort().forEach(val => $('#file-num-list').append(`<option value="${val}">`));
  107. Object.keys(vendSet).sort().forEach(val => $('#vend-name-list').append(`<option value="${val}">`));
  108. }
  109. populateFilters();
  110. function applyFilters() {
  111. var fileNum = $('#filter-file-num').val();
  112. var vendName = $('#filter-vend-name').val();
  113. table.columns().search(''); // reset all
  114. if (fileNum) table.column(1).search('^' + $.fn.dataTable.util.escapeRegex(fileNum) + '$', true, false);
  115. if (vendName) table.column(2).search('^' + $.fn.dataTable.util.escapeRegex(vendName) + '$', true, false);
  116. table.draw();
  117. }
  118. // Event bindings for filters
  119. $('#filter-file-num').on('input', applyFilters);
  120. $('#filter-vend-name').on('input', applyFilters);
  121. });
  122. // Function to view Supporting Document in modal
  123. function viewFileInModal(fileNum, fileType, filePath) {
  124. var pdfModal = new bootstrap.Modal(document.getElementById('pdf-modal'));
  125. var modalTitle = document.getElementById('pdf-modal-label');
  126. var pdfContainer = document.getElementById('pdf-container');
  127. pdfContainer.innerHTML = ''; // Clear previous pages
  128. pdfContainer.scrollTop = 0; // Scroll to the first page (top)
  129. var decodedFilePath = decodeURIComponent(filePath);
  130. var fileName = decodedFilePath.split(/[\\/]/).pop();
  131. modalTitle.textContent = fileType + " File (" + fileName + ")";
  132. var params = new URLSearchParams();
  133. params.append('file-type', fileType);
  134. params.append('file-path', decodedFilePath);
  135. params.append('file-num', fileNum);
  136. fetch('/api/file/view-supp-docs', {
  137. method: 'POST',
  138. headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
  139. body: params.toString()
  140. }).then(function (response) {
  141. if (!response.ok) {
  142. throw new Error('Failed to fetch PDF: ' + response.statusText);
  143. }
  144. return response.arrayBuffer();
  145. }).then(function (pdfData) {
  146. console.log(pdfData);
  147. var blob = new Blob([pdfData], { type: 'application/pdf' });
  148. var blobUrl = URL.createObjectURL(blob);
  149. // Set download link
  150. var downloadBtn = document.getElementById('download-pdf-btn');
  151. downloadBtn.href = blobUrl;
  152. downloadBtn.download = fileName;
  153. return pdfjsLib.getDocument({ data: pdfData }).promise;
  154. }).then(function (pdf) {
  155. let renderPage = function (pageNum) {
  156. return pdf.getPage(pageNum).then(function (page) {
  157. var viewport = page.getViewport({ scale: 1.5 });
  158. var canvas = document.createElement('canvas');
  159. canvas.classList.add('mb-3');
  160. var ctx = canvas.getContext('2d');
  161. canvas.height = viewport.height;
  162. canvas.width = viewport.width;
  163. var renderContext = { canvasContext: ctx, viewport: viewport };
  164. pdfContainer.appendChild(canvas);
  165. return page.render(renderContext).promise;
  166. });
  167. };
  168. // Render all pages sequentially
  169. let sequence = Promise.resolve();
  170. for (let pageNum = 1; pageNum <= pdf.numPages; pageNum++) {
  171. sequence = sequence.then(() => renderPage(pageNum));
  172. }
  173. return sequence;
  174. }).then(function () {
  175. var modalElement = document.getElementById('pdf-modal');
  176. modalElement.addEventListener('shown.bs.modal', function onShown() {
  177. pdfContainer.scrollTop = 0; // Reset scroll position
  178. modalElement.scrollTop = 0; // Reset modal scroll
  179. modalElement.removeEventListener('shown.bs.modal', onShown); // Clean up listener
  180. });
  181. pdfModal.show();
  182. }).catch(function (error) {
  183. alert('Error loading PDF: ' + error.message);
  184. });
  185. }