No Description
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.

app-ecommerce-category-list.js 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. /**
  2. * App eCommerce Category List
  3. */
  4. 'use strict';
  5. // Comment editor
  6. const commentEditor = document.querySelector('.comment-editor');
  7. if (commentEditor) {
  8. new Quill(commentEditor, {
  9. modules: {
  10. toolbar: '.comment-toolbar'
  11. },
  12. placeholder: 'Write a Comment...',
  13. theme: 'snow'
  14. });
  15. }
  16. // Datatable (js)
  17. document.addEventListener('DOMContentLoaded', function (e) {
  18. var dt_category_list_table = document.querySelector('.datatables-category-list');
  19. //select2 for dropdowns in offcanvas
  20. var select2 = $('.select2');
  21. if (select2.length) {
  22. select2.each(function () {
  23. var $this = $(this);
  24. $this.wrap('<div class="position-relative"></div>').select2({
  25. dropdownParent: $this.parent(),
  26. placeholder: $this.data('placeholder') //for dynamic placeholder
  27. });
  28. });
  29. }
  30. // Customers List Datatable
  31. if (dt_category_list_table) {
  32. var dt_category = new DataTable(dt_category_list_table, {
  33. ajax: assetsPath + 'json/ecommerce-category-list.json', // JSON file to add data
  34. columns: [
  35. // columns according to JSON
  36. { data: 'id' },
  37. { data: 'id', orderable: false, render: DataTable.render.select() },
  38. { data: 'categories' },
  39. { data: 'total_products' },
  40. { data: 'total_earnings' },
  41. { data: 'id' }
  42. ],
  43. columnDefs: [
  44. {
  45. // For Responsive
  46. className: 'control',
  47. searchable: false,
  48. orderable: false,
  49. responsivePriority: 1,
  50. targets: 0,
  51. render: function (data, type, full, meta) {
  52. return '';
  53. }
  54. },
  55. {
  56. // For Checkboxes
  57. targets: 1,
  58. orderable: false,
  59. searchable: false,
  60. responsivePriority: 4,
  61. checkboxes: true,
  62. render: function () {
  63. return '<input type="checkbox" class="dt-checkboxes form-check-input">';
  64. },
  65. checkboxes: {
  66. selectAllRender: '<input type="checkbox" class="form-check-input">'
  67. }
  68. },
  69. {
  70. targets: 2,
  71. responsivePriority: 2,
  72. render: function (data, type, full, meta) {
  73. const name = full['categories'];
  74. const categoryDetail = full['category_detail'];
  75. const image = full['cat_image'];
  76. const id = full['id'];
  77. let output;
  78. if (image) {
  79. // For Product image
  80. output = `<img src="${assetsPath}img/ecommerce-images/${image}" alt="Product-${id}" class="rounded">`;
  81. } else {
  82. // For Product badge
  83. const stateNum = Math.floor(Math.random() * 6);
  84. const states = ['success', 'danger', 'warning', 'info', 'dark', 'primary', 'secondary'];
  85. const state = states[stateNum];
  86. const initials = (categoryDetail.match(/\b\w/g) || []).slice(0, 2).join('').toUpperCase();
  87. output = `<span class="avatar-initial rounded-2 bg-label-${state}">${initials}</span>`;
  88. }
  89. // Creates full output for Categories and Category Detail
  90. const rowOutput = `
  91. <div class="d-flex align-items-center">
  92. <div class="avatar-wrapper me-3 rounded-2 bg-label-secondary">
  93. <div class="avatar">${output}</div>
  94. </div>
  95. <div class="d-flex flex-column justify-content-center">
  96. <span class="text-heading text-wrap fw-medium">${name}</span>
  97. <span class="text-truncate mb-0 d-none d-sm-block"><small>${categoryDetail}</small></span>
  98. </div>
  99. </div>`;
  100. return rowOutput;
  101. }
  102. },
  103. {
  104. // Total products
  105. targets: 3,
  106. responsivePriority: 3,
  107. render: function (data, type, full, meta) {
  108. const total_products = full['total_products'];
  109. return '<div class="text-sm-end">' + total_products + '</div>';
  110. }
  111. },
  112. {
  113. // Total Earnings
  114. targets: 4,
  115. orderable: false,
  116. render: function (data, type, full, meta) {
  117. const total_earnings = full['total_earnings'];
  118. return "<div class='mb-0 text-sm-end'>" + total_earnings + '</div';
  119. }
  120. },
  121. {
  122. // Actions
  123. targets: -1,
  124. title: 'Actions',
  125. searchable: false,
  126. orderable: false,
  127. render: function (data, type, full, meta) {
  128. return `
  129. <div class="d-flex align-items-sm-center justify-content-sm-center">
  130. <button class="btn btn-icon"><i class="icon-base bx bx-edit icon-md"></i></button>
  131. <button class="btn btn-icon dropdown-toggle hide-arrow" data-bs-toggle="dropdown">
  132. <i class="icon-base bx bx-dots-vertical-rounded icon-md"></i>
  133. </button>
  134. <div class="dropdown-menu dropdown-menu-end m-0">
  135. <a href="javascript:void(0);" class="dropdown-item">View</a>
  136. <a href="javascript:void(0);" class="dropdown-item">Suspend</a>
  137. </div>
  138. </div>
  139. `;
  140. }
  141. }
  142. ],
  143. select: {
  144. style: 'multi',
  145. selector: 'td:nth-child(2)'
  146. },
  147. order: [2, 'desc'],
  148. layout: {
  149. topStart: {
  150. rowClass: 'row m-3 my-0 justify-content-between',
  151. features: [
  152. {
  153. search: {
  154. placeholder: 'Search Category',
  155. text: '_INPUT_'
  156. }
  157. }
  158. ]
  159. },
  160. topEnd: {
  161. rowClass: 'row m-3 my-0 justify-content-between',
  162. features: {
  163. pageLength: {
  164. menu: [10, 25, 50, 100],
  165. text: '_MENU_'
  166. },
  167. buttons: [
  168. {
  169. text: `<i class="icon-base bx bx-plus icon-sm me-0 me-sm-2"></i><span class="d-none d-sm-inline-block">Add Category</span>`,
  170. className: 'add-new btn btn-primary',
  171. attr: {
  172. 'data-bs-toggle': 'offcanvas',
  173. 'data-bs-target': '#offcanvasEcommerceCategoryList'
  174. }
  175. }
  176. ]
  177. }
  178. },
  179. bottomStart: {
  180. rowClass: 'row mx-3 justify-content-between',
  181. features: ['info']
  182. },
  183. bottomEnd: 'paging'
  184. },
  185. language: {
  186. paginate: {
  187. next: '<i class="icon-base bx bx-chevron-right scaleX-n1-rtl icon-18px"></i>',
  188. previous: '<i class="icon-base bx bx-chevron-left scaleX-n1-rtl icon-18px"></i>',
  189. first: '<i class="icon-base bx bx-chevrons-left scaleX-n1-rtl icon-18px"></i>',
  190. last: '<i class="icon-base bx bx-chevrons-right scaleX-n1-rtl icon-18px"></i>'
  191. }
  192. },
  193. // For responsive popup
  194. responsive: {
  195. details: {
  196. display: DataTable.Responsive.display.modal({
  197. header: function (row) {
  198. const data = row.data();
  199. return 'Details of ' + data['categories'];
  200. }
  201. }),
  202. type: 'column',
  203. renderer: function (api, rowIdx, columns) {
  204. const data = columns
  205. .map(function (col) {
  206. return col.title !== '' // Do not show row in modal popup if title is blank (for check box)
  207. ? `<tr data-dt-row="${col.rowIndex}" data-dt-column="${col.columnIndex}">
  208. <td>${col.title}:</td>
  209. <td>${col.data}</td>
  210. </tr>`
  211. : '';
  212. })
  213. .join('');
  214. if (data) {
  215. const div = document.createElement('div');
  216. div.classList.add('table-responsive');
  217. const table = document.createElement('table');
  218. div.appendChild(table);
  219. table.classList.add('table');
  220. const tbody = document.createElement('tbody');
  221. tbody.innerHTML = data;
  222. table.appendChild(tbody);
  223. return div;
  224. }
  225. return false;
  226. }
  227. }
  228. }
  229. });
  230. }
  231. // Filter form control to default size
  232. // ? setTimeout used for category-list table initialization
  233. setTimeout(() => {
  234. const elementsToModify = [
  235. { selector: '.dt-buttons .btn', classToRemove: 'btn-secondary' },
  236. { selector: '.dt-search .form-control', classToRemove: 'form-control-sm', classToAdd: 'ms-0' },
  237. { selector: '.dt-search', classToAdd: 'mb-0 mb-md-6' },
  238. { selector: '.dt-length .form-select', classToRemove: 'form-select-sm' },
  239. { selector: '.dt-layout-table', classToRemove: 'row mt-2', classToAdd: 'border-top' },
  240. { selector: '.dt-layout-start', classToAdd: 'px-3 mt-0' },
  241. { selector: '.dt-layout-end', classToAdd: 'px-3 column-gap-2 mt-0 mb-md-0 mb-4' },
  242. { selector: '.dt-layout-full', classToAdd: 'table-responsive' }
  243. ];
  244. elementsToModify.forEach(({ selector, classToRemove, classToAdd }) => {
  245. document.querySelectorAll(selector).forEach(element => {
  246. if (classToRemove) {
  247. classToRemove.split(' ').forEach(className => element.classList.remove(className));
  248. }
  249. if (classToAdd) {
  250. classToAdd.split(' ').forEach(className => element.classList.add(className));
  251. }
  252. });
  253. });
  254. }, 100);
  255. });
  256. //For form validation
  257. (function () {
  258. const eCommerceCategoryListForm = document.getElementById('eCommerceCategoryListForm');
  259. //Add New customer Form Validation
  260. const fv = FormValidation.formValidation(eCommerceCategoryListForm, {
  261. fields: {
  262. categoryTitle: {
  263. validators: {
  264. notEmpty: {
  265. message: 'Please enter category title'
  266. }
  267. }
  268. },
  269. slug: {
  270. validators: {
  271. notEmpty: {
  272. message: 'Please enter slug'
  273. }
  274. }
  275. }
  276. },
  277. plugins: {
  278. trigger: new FormValidation.plugins.Trigger(),
  279. bootstrap5: new FormValidation.plugins.Bootstrap5({
  280. // Use this for enabling/changing valid/invalid class
  281. eleValidClass: 'is-valid',
  282. rowSelector: function (field, ele) {
  283. // field is the field name & ele is the field element
  284. return '.form-control-validation';
  285. }
  286. }),
  287. submitButton: new FormValidation.plugins.SubmitButton(),
  288. // Submit the form when all fields are valid
  289. // defaultSubmit: new FormValidation.plugins.DefaultSubmit(),
  290. autoFocus: new FormValidation.plugins.AutoFocus()
  291. }
  292. });
  293. })();