/** * App user list */ 'use strict'; // Datatable (js) document.addEventListener('DOMContentLoaded', function (e) { const dtUserTable = document.querySelector('.datatables-users'), statusObj = { 1: { title: 'Pending', class: 'bg-label-warning' }, 2: { title: 'Active', class: 'bg-label-success' }, 3: { title: 'Inactive', class: 'bg-label-secondary' } }; let dt_User, userView = baseUrl + 'app/user/view/account'; // Users List datatable if (dtUserTable) { const userRole = document.createElement('div'); userRole.classList.add('user_role'); const userPlan = document.createElement('div'); userPlan.classList.add('user_plan'); dt_User = new DataTable(dtUserTable, { ajax: assetsPath + 'json/user-list.json', // JSON file to add data columns: [ // columns according to JSON { data: 'id' }, { data: 'id', orderable: false, render: DataTable.render.select() }, { data: 'full_name' }, { data: 'role' }, { data: 'current_plan' }, { data: 'billing' }, { data: 'status' }, { data: 'id' } ], columnDefs: [ { // For Responsive className: 'control', orderable: false, searchable: false, responsivePriority: 5, targets: 0, render: function (data, type, full, meta) { return ''; } }, { // For Checkboxes targets: 1, orderable: false, searchable: false, responsivePriority: 3, checkboxes: true, render: function () { return ''; }, checkboxes: { selectAllRender: '' } }, { targets: 2, responsivePriority: 1, render: function (data, type, full, meta) { const name = full['full_name']; const email = full['email']; const image = full['avatar']; let output; if (image) { // For Avatar image output = `Avatar`; } else { // For Avatar badge const stateNum = Math.floor(Math.random() * 6) + 1; const states = ['success', 'danger', 'warning', 'info', 'dark', 'primary', 'secondary']; const state = states[stateNum]; const initials = (name.match(/\b\w/g) || []).slice(0, 2).join('').toUpperCase(); output = `${initials}`; } // Creates full output for row const rowOutput = `
${output}
${name} @${email}
`; return rowOutput; } }, { targets: 3, render: function (data, type, full, meta) { const role = full['role']; const roleBadgeObj = { Subscriber: '', Author: '', Maintainer: '', Editor: '', Admin: '' }; return `${roleBadgeObj[role] || ''}${role}`; } }, { // Plans targets: 4, render: function (data, type, full, meta) { let plan = full['current_plan']; return '' + plan + ''; } }, { // User Status targets: 6, render: function (data, type, full, meta) { let status = full['status']; return ( '' + statusObj[status].title + '' ); } }, { targets: -1, title: 'Actions', searchable: false, orderable: false, render: function (data, type, full, meta) { return `
`; } } ], select: { style: 'multi', selector: 'td:nth-child(2)' }, order: [[2, 'desc']], layout: { topStart: { rowClass: 'row me-3 ms-2 justify-content-between', features: [ { pageLength: { menu: [10, 25, 50, 100], text: '_MENU_' } } ] }, topEnd: { features: [ { search: { placeholder: 'Search User', text: '_INPUT_' } }, userRole, userPlan ] }, bottomStart: { rowClass: 'row mx-3 justify-content-between', features: ['info'] }, bottomEnd: 'paging' }, language: { paginate: { next: '', previous: '', first: '', last: '' } }, // For responsive popup responsive: { details: { display: DataTable.Responsive.display.modal({ header: function (row) { const 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) ? ` ${col.title}: ${col.data} ` : ''; }) .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; } } }, initComplete: function () { // Adding role filter once table initialized this.api() .columns(3) .every(function () { const column = this; const select = document.createElement('select'); select.id = 'UserRole'; select.className = 'form-select text-capitalize'; select.innerHTML = ''; userRole.appendChild(select); select.addEventListener('change', function () { const val = select.value; column.search(val ? '^' + val + '$' : '', true, false).draw(); }); column .data() .unique() .sort() .each(function (d) { const option = document.createElement('option'); option.value = d; option.className = 'text-capitalize'; option.textContent = d; select.appendChild(option); }); }); this.api() .columns(4) .every(function () { var column = this; var select = $( '' ) .appendTo('.user_plan') .on('change', function () { var val = $.fn.dataTable.util.escapeRegex($(this).val()); column.search(val ? '^' + val + '$' : '', true, false).draw(); }); column .data() .unique() .sort() .each(function (d, j) { select.append(''); }); }); } }); //? The 'delete-record' class is necessary for the functionality of the following code. function deleteRecord(event) { let row = document.querySelector('.dtr-expanded'); if (event) { row = event.target.parentElement.closest('tr'); } if (row) { dt_User.row(row).remove().draw(); } } function bindDeleteEvent() { const userTable = document.querySelector('.datatables-users'); const modal = document.querySelector('.dtr-bs-modal'); if (userTable && userTable.classList.contains('collapsed')) { if (modal) { modal.addEventListener('click', function (event) { if (event.target.parentElement.classList.contains('delete-record')) { deleteRecord(); const closeButton = modal.querySelector('.btn-close'); if (closeButton) closeButton.click(); // Simulates a click on the close button } }); } } else { const tableBody = userTable?.querySelector('tbody'); if (tableBody) { tableBody.addEventListener('click', function (event) { if (event.target.parentElement.classList.contains('delete-record')) { deleteRecord(event); } }); } } } // Initial event binding bindDeleteEvent(); // Re-bind events when modal is shown or hidden document.addEventListener('show.bs.modal', function (event) { if (event.target.classList.contains('dtr-bs-modal')) { bindDeleteEvent(); } }); document.addEventListener('hide.bs.modal', function (event) { if (event.target.classList.contains('dtr-bs-modal')) { bindDeleteEvent(); } }); } // Filter form control to default size // ? setTimeout used for multilingual table initialization setTimeout(() => { const elementsToModify = [ { selector: '.dt-search .form-control', classToRemove: 'form-control-sm' }, { selector: '.dt-search', classToAdd: 'mb-md-6 mb-2' }, { selector: '.dt-length .form-select', classToRemove: 'form-select-sm' }, { selector: '.dt-length', classToAdd: 'mb-md-6 mb-0' }, { selector: '.dt-layout-start', classToAdd: 'ps-2 mt-0' }, { selector: '.dt-layout-end', classToRemove: 'justify-content-between', classToAdd: 'justify-content-md-between justify-content-center d-flex flex-wrap gap-4 mb-sm-0 mb-4 mt-0' }, { selector: '.dt-layout-table', classToRemove: 'row mt-2' }, { selector: '.user_role', classToAdd: 'w-px-200 my-md-0 mt-6 mb-2' }, { selector: '.user_plan', classToAdd: 'w-px-200 mb-6 mb-md-0' } ]; // 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); // On edit role click, update text var roleEditList = document.querySelectorAll('.role-edit-modal'), roleAdd = document.querySelector('.add-new-role'), roleTitle = document.querySelector('.role-title'); roleAdd.onclick = function () { roleTitle.innerHTML = 'Add New Role'; // reset text }; if (roleEditList) { roleEditList.forEach(function (roleEditEl) { roleEditEl.onclick = function () { roleTitle.innerHTML = 'Edit Role'; // reset text }; }); } });