| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626 |
- /**
- * DataTables Advanced (js)
- */
-
- 'use strict';
-
- document.addEventListener('DOMContentLoaded', function (e) {
- const startDateEle = document.querySelector('.start_date');
- const endDateEle = document.querySelector('.end_date');
-
- // Advanced Search Functions Starts
- // --------------------------------------------------------------------
-
- // Datepicker for advanced filter
- const rangePickr = document.querySelector('.flatpickr-range'),
- dateFormat = 'MM/DD/YYYY';
-
- if (rangePickr) {
- rangePickr.flatpickr({
- mode: 'range',
- dateFormat: 'm/d/Y',
- orientation: isRtl ? 'auto right' : 'auto left',
- locale: {
- format: dateFormat
- },
- onClose: function (selectedDates, dateStr, instance) {
- let startDate = '';
- let endDate = new Date();
-
- if (selectedDates[0] !== undefined) {
- startDate = new Date(selectedDates[0]).toLocaleDateString('en-US', {
- month: '2-digit',
- day: '2-digit',
- year: 'numeric'
- });
- startDateEle.value = startDate; // Using `.value` to update input fields in vanilla JS
- }
-
- if (selectedDates[1] !== undefined) {
- endDate = new Date(selectedDates[1]).toLocaleDateString('en-US', {
- month: '2-digit',
- day: '2-digit',
- year: 'numeric'
- });
- endDateEle.value = endDate; // Using `.value` to update input fields in vanilla JS
- }
-
- // Trigger custom events without jQuery
- rangePickr.dispatchEvent(new Event('change'));
- rangePickr.dispatchEvent(new Event('keyup'));
- }
- });
- }
-
- // Advance filter function
- // We pass the column location, the start date, and the end date
- // Clear existing custom filters
- if (typeof $.fn !== 'undefined' && typeof $.fn.dataTableExt !== 'undefined') {
- $.fn.dataTableExt.afnFiltering.length = 0;
- }
-
- const filterByDate = function (column, startDate, endDate) {
- // Custom filter syntax requires pushing the new filter to the global filter array
- if (typeof $.fn !== 'undefined' && typeof $.fn.dataTableExt !== 'undefined') {
- $.fn.dataTableExt.afnFiltering.push(function (oSettings, aData, iDataIndex) {
- const rowDate = normalizeDate(aData[column]);
- const start = normalizeDate(startDate);
- const end = normalizeDate(endDate);
-
- // If our date from the row is between the start and end
- if (start <= rowDate && rowDate <= end) {
- return true;
- } else if (rowDate >= start && end === '' && start !== '') {
- return true;
- } else if (rowDate <= end && start === '' && end !== '') {
- return true;
- } else {
- return false;
- }
- });
- }
- };
-
- // Convert date strings to a Date object, then normalize into YYYYMMDD format
- const normalizeDate = function (dateString) {
- const date = new Date(dateString);
- const normalized =
- date.getFullYear() +
- ('0' + (date.getMonth() + 1)).slice(-2) + // Ensure month is two digits
- ('0' + date.getDate()).slice(-2); // Ensure day is two digits
- return normalized;
- };
-
- // Advanced Search Functions Ends
-
- // Ajax Sourced Server-side
- // --------------------------------------------------------------------
- const dt_ajax_table = document.querySelector('.datatables-ajax');
- if (dt_ajax_table) {
- let dt_ajax = new DataTable(dt_ajax_table, {
- processing: true,
- ajax: {
- url: assetsPath + 'json/ajax.php',
- dataSrc: 'data'
- },
- layout: {
- topStart: {
- rowClass: 'row mx-3 my-0 justify-content-between',
- features: [
- {
- pageLength: {
- menu: [7, 10, 25, 50, 100],
- text: 'Show_MENU_entries'
- }
- }
- ]
- },
- topEnd: {
- search: {
- placeholder: ''
- }
- },
- bottomStart: {
- rowClass: 'row mx-3 justify-content-between',
- features: ['info']
- },
- bottomEnd: 'paging'
- },
- language: {
- paginate: {
- next: '<i class="icon-base bx bx-chevron-right scaleX-n1-rtl icon-18px"></i>',
- previous: '<i class="icon-base bx bx-chevron-left scaleX-n1-rtl icon-18px"></i>',
- first: '<i class="icon-base bx bx-chevrons-left scaleX-n1-rtl icon-18px"></i>',
- last: '<i class="icon-base bx bx-chevrons-right scaleX-n1-rtl icon-18px"></i>'
- }
- }
- });
- }
-
- // Column Search
- // --------------------------------------------------------------------
-
- const dt_filter_table = document.querySelector('.dt-column-search');
- if (dt_filter_table) {
- // Setup - add a text input to each footer cell
- const thead = document.querySelector('.dt-column-search thead');
-
- // Clone the first row and append it as the second row
- const cloneRow = thead.querySelector('tr').cloneNode(true);
- thead.appendChild(cloneRow);
-
- // Select the newly added second row (the cloned one)
- const secondRowCells = thead.querySelectorAll('tr:nth-child(2) th');
-
- secondRowCells.forEach((th, i) => {
- const title = th.textContent;
- const input = document.createElement('input');
- input.type = 'text';
- input.className = 'form-control';
- input.placeholder = `Search ${title}`;
-
- // Add left and right border styles to the parent element
- th.style.borderLeft = 'none';
- if (i === secondRowCells.length - 1) {
- th.style.borderRight = 'none';
- }
-
- th.innerHTML = '';
- th.appendChild(input);
-
- // Event listener for search functionality
- input.addEventListener('keyup', function () {
- if (dt_filter.column(i).search() !== this.value) {
- dt_filter.column(i).search(this.value).draw();
- }
- });
-
- input.addEventListener('change', function () {
- if (dt_filter.column(i).search() !== this.value) {
- dt_filter.column(i).search(this.value).draw();
- }
- });
- });
-
- let dt_filter = new DataTable(dt_filter_table, {
- ajax: assetsPath + 'json/table-datatable.json',
- columns: [
- { data: 'full_name' },
- { data: 'email' },
- { data: 'post' },
- { data: 'city' },
- { data: 'start_date' },
- { data: 'salary' }
- ],
- orderCellsTop: true,
- layout: {
- topStart: {
- rowClass: 'row mx-3 my-0 justify-content-between',
- features: [
- {
- pageLength: {
- menu: [7, 10, 25, 50, 100],
- text: 'Show_MENU_entries'
- }
- }
- ]
- },
- topEnd: {
- search: {
- placeholder: 'Type search here'
- }
- },
- bottomStart: {
- rowClass: 'row mx-3 justify-content-between',
- features: ['info']
- },
- bottomEnd: 'paging'
- },
- language: {
- paginate: {
- next: '<i class="icon-base bx bx-chevron-right scaleX-n1-rtl icon-18px"></i>',
- previous: '<i class="icon-base bx bx-chevron-left scaleX-n1-rtl icon-18px"></i>',
- first: '<i class="icon-base bx bx-chevrons-left scaleX-n1-rtl icon-18px"></i>',
- last: '<i class="icon-base bx bx-chevrons-right scaleX-n1-rtl icon-18px"></i>'
- }
- }
- });
- }
-
- // Advanced Search
- // --------------------------------------------------------------------
-
- const dt_adv_filter_table = document.querySelector('.dt-advanced-search');
- let dt_adv_filter;
- // Advanced Filter table
- if (dt_adv_filter_table) {
- dt_adv_filter = new DataTable(dt_adv_filter_table, {
- ajax: assetsPath + 'json/table-datatable.json',
- columns: [
- { data: '' },
- { data: 'full_name' },
- { data: 'email' },
- { data: 'post' },
- { data: 'city' },
- { data: 'start_date' },
- { data: 'salary' }
- ],
- columnDefs: [
- {
- className: 'control',
- orderable: false,
- targets: 0,
- render: function (data, type, full, meta) {
- return '';
- }
- }
- ],
- layout: {
- topStart: {
- rowClass: 'm-0',
- features: []
- },
- topEnd: {},
- bottomStart: {
- rowClass: 'row mx-3 justify-content-between',
- features: ['info']
- },
- bottomEnd: 'paging'
- },
- language: {
- paginate: {
- next: '<i class="icon-base bx bx-chevron-right scaleX-n1-rtl icon-18px"></i>',
- previous: '<i class="icon-base bx bx-chevron-left scaleX-n1-rtl icon-18px"></i>',
- first: '<i class="icon-base bx bx-chevrons-left scaleX-n1-rtl icon-18px"></i>',
- last: '<i class="icon-base bx bx-chevrons-right scaleX-n1-rtl icon-18px"></i>'
- }
- },
- orderCellsTop: true,
- responsive: {
- details: {
- display: DataTable.Responsive.display.modal({
- header: function (row) {
- var data = row.data();
- return 'Details of ' + data['full_name'];
- }
- }),
- type: 'column',
- renderer: function (api, rowIdx, columns) {
- const data = columns
- .map(function (col) {
- return col.title !== '' // Do not show row in modal popup if title is blank (for check box)
- ? `<tr data-dt-row="${col.rowIndex}" data-dt-column="${col.columnIndex}">
- <td>${col.title}:</td>
- <td>${col.data}</td>
- </tr>`
- : '';
- })
- .join('');
-
- if (data) {
- const div = document.createElement('div');
- div.classList.add('table-responsive');
- const table = document.createElement('table');
- div.appendChild(table);
- table.classList.add('table');
- const tbody = document.createElement('tbody');
- tbody.innerHTML = data;
- table.appendChild(tbody);
- return div;
- }
- return false;
- }
- }
- }
- });
- }
-
- // on keyup from input field
- document.querySelectorAll('input.dt-input').forEach(input => {
- input.addEventListener('keyup', function () {
- const column = this.getAttribute('data-column');
- const value = this.value;
- filterColumn(column, value);
- });
- });
-
- // Filter column wise function
- function filterColumn(i, val) {
- if (i == 5) {
- const startDate = startDateEle.value;
- const endDate = endDateEle.value;
-
- if (startDate !== '' && endDate !== '') {
- // Reset custom filter
- $.fn.dataTable.ext.search.length = 0;
-
- // Custom date filtering logic
- filterByDate(i, startDate, endDate);
- }
-
- // Redraw the DataTable
- dt_adv_filter.draw();
- } else {
- // Search the column using the DataTable instance
- dt_adv_filter
- .column(i) // Access the correct column
- .search(val, false, true) // Apply the search
- .draw(); // Redraw the table
- }
- }
-
- // Responsive Table
- // --------------------------------------------------------------------
-
- const dt_responsive_table = document.querySelector('.dt-responsive');
- if (dt_responsive_table) {
- let dt_responsive = new DataTable(dt_responsive_table, {
- ajax: assetsPath + 'json/table-datatable.json',
- columns: [
- { data: 'id' },
- { data: 'full_name' },
- { data: 'email' },
- { data: 'post' },
- { data: 'city' },
- { data: 'start_date' },
- { data: 'salary' },
- { data: 'age' },
- { data: 'experience' },
- { data: 'status' }
- ],
- columnDefs: [
- {
- className: 'control',
- orderable: false,
- targets: 0,
- searchable: false,
- render: function (data, type, full, meta) {
- return '';
- }
- },
- {
- // Label
- targets: -1,
- render: function (data, type, full, meta) {
- const statusNumber = full.status;
- const statuses = {
- 1: { title: 'Current', class: 'bg-label-primary' },
- 2: { title: 'Professional', class: 'bg-label-success' },
- 3: { title: 'Rejected', class: 'bg-label-danger' },
- 4: { title: 'Resigned', class: 'bg-label-warning' },
- 5: { title: 'Applied', class: 'bg-label-info' }
- };
-
- if (typeof statuses[statusNumber] === 'undefined') {
- return data;
- }
-
- return `
- <span class="badge ${statuses[statusNumber].class}">
- ${statuses[statusNumber].title}
- </span>
- `;
- }
- }
- ],
- destroy: true,
- layout: {
- topStart: {
- rowClass: 'row mx-3 my-0 justify-content-between',
- features: [
- {
- pageLength: {
- menu: [7, 10, 25, 50, 100],
- text: 'Show_MENU_entries'
- }
- }
- ]
- },
- topEnd: {
- search: {
- placeholder: ''
- }
- },
- bottomStart: {
- rowClass: 'row mx-3 justify-content-between',
- features: ['info']
- },
- bottomEnd: 'paging'
- },
- language: {
- paginate: {
- next: '<i class="icon-base bx bx-chevron-right scaleX-n1-rtl icon-18px"></i>',
- previous: '<i class="icon-base bx bx-chevron-left scaleX-n1-rtl icon-18px"></i>',
- first: '<i class="icon-base bx bx-chevrons-left scaleX-n1-rtl icon-18px"></i>',
- last: '<i class="icon-base bx bx-chevrons-right scaleX-n1-rtl icon-18px"></i>'
- }
- },
- responsive: {
- details: {
- display: DataTable.Responsive.display.modal({
- header: function (row) {
- var data = row.data();
- return 'Details of ' + data['full_name'];
- }
- }),
- type: 'column',
- renderer: function (api, rowIdx, columns) {
- const data = columns
- .map(function (col) {
- return col.title !== '' // Do not show row in modal popup if title is blank (for check box)
- ? `<tr data-dt-row="${col.rowIndex}" data-dt-column="${col.columnIndex}">
- <td>${col.title}:</td>
- <td>${col.data}</td>
- </tr>`
- : '';
- })
- .join('');
-
- if (data) {
- const div = document.createElement('div');
- div.classList.add('table-responsive');
- const table = document.createElement('table');
- div.appendChild(table);
- table.classList.add('table');
- const tbody = document.createElement('tbody');
- tbody.innerHTML = data;
- table.appendChild(tbody);
- return div;
- }
- return false;
- }
- }
- }
- });
- }
-
- // Responsive with Child Rows
- // --------------------------------------------------------------------
-
- const dt_responsive_child_table = document.querySelector('.dt-responsive-child');
- let dt_responsive_child;
- if (dt_responsive_child_table) {
- dt_responsive_child = new DataTable(dt_responsive_child_table, {
- ajax: assetsPath + 'json/table-datatable.json',
- columns: [
- { data: null },
- { data: 'full_name' },
- { data: 'email' },
- { data: 'city' },
- { data: 'start_date' },
- { data: 'age' },
- { data: 'status' }
- ],
- columnDefs: [
- {
- className: 'dt-control',
- orderable: false,
- targets: 0,
- searchable: false,
- defaultContent: ''
- },
- {
- // Label
- targets: -1,
- render: function (data, type, full, meta) {
- const statusNumber = full.status;
- const statuses = {
- 1: { title: 'Current', class: 'bg-label-primary' },
- 2: { title: 'Professional', class: 'bg-label-success' },
- 3: { title: 'Rejected', class: 'bg-label-danger' },
- 4: { title: 'Resigned', class: 'bg-label-warning' },
- 5: { title: 'Applied', class: 'bg-label-info' }
- };
-
- if (typeof statuses[statusNumber] === 'undefined') {
- return data;
- }
-
- return `
- <span class="badge ${statuses[statusNumber].class}">
- ${statuses[statusNumber].title}
- </span>
- `;
- }
- }
- ],
- layout: {
- topStart: {
- rowClass: 'row mx-3 my-0 justify-content-between',
- features: [
- {
- pageLength: {
- menu: [7, 10, 25, 50, 100],
- text: 'Show_MENU_entries'
- }
- }
- ]
- },
- topEnd: {
- search: {
- placeholder: ''
- }
- },
- bottomStart: {
- rowClass: 'row mx-3 justify-content-between',
- features: ['info']
- },
- bottomEnd: 'paging'
- },
- scrollX: true,
- language: {
- paginate: {
- next: '<i class="icon-base bx bx-chevron-right scaleX-n1-rtl icon-18px"></i>',
- previous: '<i class="icon-base bx bx-chevron-left scaleX-n1-rtl icon-18px"></i>',
- first: '<i class="icon-base bx bx-chevrons-left scaleX-n1-rtl icon-18px"></i>',
- last: '<i class="icon-base bx bx-chevrons-right scaleX-n1-rtl icon-18px"></i>'
- }
- }
- });
- }
-
- // Formatting function for row details - modify as you need
- function format(d) {
- // `d` is the original data object for the row
- return (
- '<dl>' +
- '<dt>Full name:</dt>' +
- '<dd>' +
- d.full_name +
- '</dd>' +
- '<dt>Post:</dt>' +
- '<dd>' +
- d.post +
- '</dd>' +
- '<dt>Salary:</dt>' +
- '<dd>' +
- d.salary +
- '</dd>' +
- '<dt>Experience:</dt>' +
- '<dd>' +
- d.experience +
- '</dd>' +
- '</dl>'
- );
- }
-
- // Add event listener for opening and closing details
- dt_responsive_child.on('click', 'td.dt-control', function (e) {
- let tr = e.target.closest('tr');
- let row = dt_responsive_child.row(tr);
-
- if (row.child.isShown()) {
- // This row is already open - close it
- row.child.hide();
- } else {
- // Open this row
- row.child(format(row.data())).show();
- }
- });
-
- // Filter form control to default size
- // ? setTimeout used for multilingual table initialization
- setTimeout(() => {
- const elementsToModify = [
- { selector: '.dt-buttons .btn', classToRemove: 'btn-secondary' },
- { selector: '.dt-search .form-control', classToRemove: 'form-control-sm', classToAdd: 'ms-4' },
- { selector: '.dt-length .form-select', classToRemove: 'form-select-sm' },
- { selector: '.dt-layout-table', classToRemove: 'row mt-2' },
- { selector: '.dt-layout-end', classToAdd: 'mt-0' },
- { selector: '.dt-layout-end .dt-search', classToAdd: 'mt-md-6 mt-0' },
- { selector: '.dt-layout-full', classToRemove: 'col-md col-12', classToAdd: 'table-responsive' }
- ];
-
- // Delete record
- elementsToModify.forEach(({ selector, classToRemove, classToAdd }) => {
- document.querySelectorAll(selector).forEach(element => {
- if (classToRemove) {
- classToRemove.split(' ').forEach(className => element.classList.remove(className));
- }
- if (classToAdd) {
- classToAdd.split(' ').forEach(className => element.classList.add(className));
- }
- });
- });
- }, 100);
- });
|