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.

973 lines
43 KiB

2 years ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
  1. <!DOCTYPE html>
  2. <html lang="en" dir="">
  3. <html xmlns:th="http://www.thymeleaf.org">
  4. <head th:replace="~{fragments/modules/base/head :: head}"></head>
  5. <style>
  6. .required{
  7. color: red;
  8. }
  9. /* Custom CSS for SweetAlert2 */
  10. .swal-container {
  11. display: flex;
  12. align-items: center;
  13. justify-content: center;
  14. }
  15. .swal-popup {
  16. width: 80% !important; /* Adjust width as needed */
  17. max-width: 600px; /* Max width for larger screens */
  18. border-radius: 8px; /* Optional: round the corners */
  19. padding: 2rem; /* Optional: adjust padding */
  20. }
  21. .swal-confirm-button {
  22. background-color: #dc3545; /* Example: red background for delete button */
  23. border: none;
  24. color: #fff;
  25. }
  26. .swal-cancel-button {
  27. background-color: #6c757d; /* Example: gray background for cancel button */
  28. border: none;
  29. color: #fff;
  30. }
  31. #addcategoryform .modal-body {
  32. max-height: 500px; /* Set max height */
  33. overflow-y: auto; /* Enable vertical scrolling when content overflows */
  34. }
  35. #editCategoryModal .modal-body {
  36. max-height: 500px; /* Set max height */
  37. overflow-y: auto; /* Enable vertical scrolling when content overflows */
  38. }
  39. </style>
  40. <body>
  41. <!--[if lt IE 8]>
  42. <p class="browserupgrade">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p>
  43. <![endif]-->
  44. <div class="wrapper">
  45. <!-- header top menu Start -->
  46. <header th:replace="~{fragments/modules/base/header :: header}"></header>
  47. <!-- header top menu end -->
  48. <div class="page-wrap">
  49. <!--=============== Left Menu side Start ================-->
  50. <div th:replace="~{fragments/modules/base/menu :: menu}"></div>
  51. <!--=============== Left side End ================-->
  52. <div class="main-content">
  53. <div class="container-fluid">
  54. <div class="page-header mb-2">
  55. <div class="row align-items-end">
  56. <div class="col-lg-8">
  57. <div class="page-header-title">
  58. <i class="fas fa-th-large bg-blue"></i>
  59. <div class="d-inline">
  60. <h5>Add Category</h5>
  61. <span>1913 Add Category</span>
  62. </div>
  63. </div>
  64. </div>
  65. <div class="col-lg-4">
  66. <nav class="breadcrumb-container" aria-label="breadcrumb">
  67. <ol class="breadcrumb">
  68. <li class="breadcrumb-item"><a href="/gcc/index"><i
  69. class="ik ik-home"></i></a></li>
  70. <li class="breadcrumb-item" aria-current="page">1913 Campaign</li>
  71. <li class="breadcrumb-item active" aria-current="page">Add Category</li>
  72. </ol>
  73. </nav>
  74. </div>
  75. </div>
  76. </div>
  77. <h4 class="h4 text-right text-mute" style="font-size: 12px;">
  78. Auot refresh in <font id="refresh-countdown">00</font> seconds
  79. </h4>
  80. <div class="row">
  81. <div class="col-md-12">
  82. <div class="card">
  83. <div class="card-block">
  84. <div class="page-header-title" >
  85. <h5 style="margin: 0;font-weight: bold;">Category List</h5><hr>
  86. </div>
  87. <div>
  88. <table id="categoryDatatable" class="table table-striped table-bordered table-hover dataTable" role="grid" width="100%">
  89. <thead class="thead-dark">
  90. <tr role="row">
  91. <th class="text-center no-sort">S.No</th>
  92. <th class="text-center">Category</th>
  93. <th class="text-center no-sort">Action</th>
  94. </tr>
  95. </thead>
  96. <tbody>
  97. <tr th:each="category, iterStat : ${categories}">
  98. <td class="text-center" th:text="${iterStat.index + 1}"></td>
  99. <td class="text-center" th:text="${category.category_name}"></td>
  100. <td class="text-center">
  101. <a href="#" th:onclick="return callEdit([[${category.category_id}]])" data-animation="true" data-toggle="tooltip" data-placement="top" title="Edit" data-original-title="Edit">
  102. <i class="ik ik-edit f-16 mr-15 text-green"></i>
  103. </a>
  104. <!-- Delete button -->
  105. <a href="javascript:void(0);" th:onclick="return openDeleteModal([[${category.category_id}]])" title="Delete">
  106. <i class="ik ik-trash-2 f-16 text-red ml-4"></i>
  107. </a>
  108. </td>
  109. </tr>
  110. </tbody>
  111. <tfoot class="thead-dark">
  112. <tr>
  113. <th class="text-center no-sort">S.No</th>
  114. <th class="text-center">Category</th>
  115. <th class="text-center no-sort">Action</th>
  116. </tr>
  117. </tfoot>
  118. </table>
  119. </div>
  120. </div>
  121. </div>
  122. </div>
  123. </div>
  124. </div>
  125. </div>
  126. <footer th:replace="~{fragments/modules/base/footer :: footer}"></footer>
  127. </div>
  128. </div>
  129. <!-- Category Modal Form -->
  130. <div class="modal fade" id="addcategoryform" tabindex="-1" role="dialog">
  131. <div class="modal-dialog modal-lg" role="document">
  132. <div class="modal-content">
  133. <div class="modal-header">
  134. <h5 class="modal-title">Category Form</h5>
  135. <button type="button" class="close" data-dismiss="modal">&times;</button>
  136. </div>
  137. <div class="modal-body">
  138. <form id="addCategoryForm">
  139. <div class="form-group">
  140. <label>Category Name <span class="required">*</span></label>
  141. <input type="text" class="form-control" id="categoryname" name="categoryname" placeholder="Enter Category Name" required>
  142. </div>
  143. <div id="columnInputs">
  144. <label>Column Name <span class="required">*</span></label>
  145. <div class="form-group row column-group">
  146. <div class="col-sm-10">
  147. <input type="text" class="form-control columnname" name="columns[]" placeholder="Column Name" required>
  148. </div>
  149. <div class="col-sm-2">
  150. <button type="button" class="btn btn-danger remove-column">&times;</button>
  151. </div>
  152. </div>
  153. </div>
  154. <button type="button" class="btn btn-primary" id="addMoreColumn">+ Add Column</button>
  155. <button type="button" class="btn btn-success" id="createCategoryBtn">Save Category</button>
  156. </form>
  157. </div>
  158. </div>
  159. </div>
  160. </div>
  161. <!-- Edit Category Modal -->
  162. <div class="modal fade" id="editCategoryModal" tabindex="-1" role="dialog" aria-labelledby="editCategoryModalLabel" aria-hidden="true">
  163. <div class="modal-dialog modal-lg" role="document">
  164. <div class="modal-content">
  165. <div class="modal-header">
  166. <h5 class="modal-title" id="editCategoryModalLabel">Edit Category</h5>
  167. <button type="button" class="close" data-dismiss="modal" aria-label="Close">
  168. <span aria-hidden="true">&times;</span>
  169. </button>
  170. </div>
  171. <div class="modal-body">
  172. <form id="editCategoryForm">
  173. <input type="hidden" id="categoryId" name="categoryId">
  174. <div class="form-group">
  175. <label for="showcategoryName">Category Name <span class="required">*</span></label>
  176. <input type="text" class="form-control" id="showcategoryName" name="showcategoryName" required readonly="readonly">
  177. </div>
  178. <div id="editColumnInputs"></div>
  179. <div id="editaddColumnInputs"></div>
  180. <hr>
  181. <button type="button" class="btn btn-success" id="addMoreEditColumn">+ Add Column</button>
  182. <button type="button" class="btn btn-primary" id="updateCategoryButton">Save Changes</button>
  183. <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
  184. </form>
  185. </div>
  186. </div>
  187. </div>
  188. </div>
  189. <!-- Delete Confirmation Modal -->
  190. <div class="modal fade" id="deleteCategoryModal" tabindex="-1" role="dialog" aria-labelledby="deleteCategoryModalLabel" aria-hidden="true">
  191. <div class="modal-dialog modal-lg" role="document"> <!-- Add modal-lg here -->
  192. <div class="modal-content">
  193. <div class="modal-header">
  194. <h5 class="modal-title" id="deleteCategoryModalLabel">Confirm Deletion</h5>
  195. <button type="button" class="close" data-dismiss="modal" aria-label="Close">
  196. <span aria-hidden="true">&times;</span>
  197. </button>
  198. </div>
  199. <div class="modal-body">
  200. <p>Are you sure you want to delete this category?</p>
  201. </div>
  202. <div class="modal-footer">
  203. <button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
  204. <button type="button" class="btn btn-danger" id="confirmDeleteButton">Delete</button>
  205. </div>
  206. </div>
  207. </div>
  208. </div>
  209. <div th:replace="~{fragments/modules/base/app_module_menu_box :: div}"></div>
  210. <script th:replace="~{fragments/modules/base/script :: script}"></script>
  211. <script src="node_modules/tempusdominus-bootstrap-4/build/js/tempusdominus-bootstrap-4.min.js"></script>
  212. <script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
  213. <script>
  214. $(document).ready(function () {
  215. // Initialize DataTables with export buttons
  216. var buttons = [
  217. {
  218. extend: 'pageLength',
  219. className: 'btn btn-warning'
  220. },
  221. {
  222. title: 'Data export',
  223. extend: 'copyHtml5',
  224. text: 'Copy',
  225. className: 'btn btn-secondary'
  226. },
  227. {
  228. extend: 'excelHtml5',
  229. text: 'Excel',
  230. className: 'btn btn-secondary'
  231. },
  232. {
  233. extend: 'csvHtml5',
  234. text: 'CSV',
  235. className: 'btn btn-secondary'
  236. },
  237. {
  238. extend: 'pdfHtml5',
  239. text: 'PDF',
  240. className: 'btn btn-secondary'
  241. },
  242. {
  243. text: '<i class="far fa-plus-square"></i> Add New Category',
  244. className: 'btn btn-warning',
  245. action: function () {
  246. callAdd(); // Now it will work
  247. }
  248. }
  249. ];
  250. $('#categoryDatatable').DataTable({
  251. dom: 'Bftip',
  252. columnDefs: [
  253. { targets: 'no-sort', orderable: false }
  254. ],
  255. lengthMenu: [
  256. [50, 100, 200, 500, -1],
  257. ['50 rows', '100 rows', '200 rows', '500 rows', 'Show all']
  258. ],
  259. scrollY: '30vh',
  260. fixedColumns: {
  261. left: 1,
  262. right: 1
  263. },
  264. buttons: buttons,
  265. fixedHeader: true,
  266. autoWidth: true,
  267. responsive: true,
  268. searching: false,
  269. select: false,
  270. processing: false,
  271. });
  272. // Show Modal
  273. function callAdd() {
  274. resetForm();
  275. $('#addcategoryform').modal({ backdrop: 'static', keyboard: false });
  276. $('#addcategoryform').modal('show');
  277. }
  278. // Reset Form
  279. function resetForm() {
  280. $('#addCategoryForm')[0].reset();
  281. $("#columnInputs .column-group:not(:first)").remove();
  282. $(".remove-column").hide();
  283. }
  284. //validateColumns
  285. function validateColumns(columns) {
  286. let columnSet = new Set();
  287. let regex = /^[A-Za-z0-9_ ]+$/; // Allow alphabets, numbers, underscores, and spaces
  288. let invalidRegex = /^[_ ]+$/; // Match column names with only underscores and/or spaces
  289. for (let col of columns) {
  290. if (!regex.test(col)) {
  291. Swal.fire({
  292. title: "Validation Error",
  293. text: "Column names must contain only alphabets (A-Z, a-z), numbers (0-9), underscores (_), and spaces.",
  294. icon: "warning",
  295. confirmButtonText: "OK"
  296. });
  297. return false;
  298. }
  299. if (invalidRegex.test(col)) {
  300. Swal.fire({
  301. title: "Validation Error",
  302. text: "Column names cannot contain only spaces and underscores (_).",
  303. icon: "warning",
  304. confirmButtonText: "OK"
  305. });
  306. return false;
  307. }
  308. let trimmedCol = col.trim().toLowerCase(); // Trim spaces for uniqueness check
  309. if (columnSet.has(trimmedCol)) {
  310. Swal.fire({
  311. title: "Validation Error",
  312. text: "Duplicate column names are not allowed.",
  313. icon: "warning",
  314. confirmButtonText: "OK"
  315. });
  316. return false;
  317. }
  318. columnSet.add(trimmedCol);
  319. }
  320. return true;
  321. }
  322. // Add default fields on page load
  323. /* var defaultFields = `
  324. <div class="form-group row column-group">
  325. <div class="col-sm-10">
  326. <input type="text" class="form-control" name="columns[]" value="name" readonly>
  327. <input type="text" class="form-control" name="columns[]" value="mobilenumber" readonly>
  328. <input type="text" class="form-control" name="columns[]" value="address" readonly>
  329. </div>
  330. </div>`;
  331. $('#columnInputs').append(defaultFields); */
  332. var defaultFields = `
  333. <div class="form-group row column-group">
  334. <div class="col-sm-10">
  335. <input type="text" class="form-control" name="columns[]" value="Name" >
  336. </div>
  337. </div>
  338. <div class="form-group row column-group">
  339. <div class="col-sm-10">
  340. <input type="text" class="form-control" name="columns[]" value="Mobilenumber" >
  341. </div>
  342. </div>
  343. </div>`;
  344. $('#columnInputs').append(defaultFields);
  345. $('#addcategoryform').on('shown.bs.modal', function () {
  346. $('#columnInputs').html(''); // Clear existing columns
  347. $('#columnInputs').append(defaultFields); // Append default values
  348. });
  349. $('#addcategoryform').on('hidden.bs.modal', function () {
  350. $('#categoryname').val(""); // Reset category name
  351. $('#columnInputs').html(""); // Clear all columns
  352. });
  353. $('#editCategoryModal').on('hidden.bs.modal', function () {
  354. $('#editColumnInputs').html(''); // Clear all columns when modal is closed
  355. $('#editaddColumnInputs').html(''); // Clear additional columns if applicable
  356. });
  357. // Add More Column Fields
  358. $('#addMoreColumn').click(function () {
  359. var newColumnField = `
  360. <div class="form-group row column-group">
  361. <div class="col-sm-10">
  362. <input type="text" class="form-control columnname" name="columns[]" placeholder="Column Name" required>
  363. </div>
  364. <div class="col-sm-2">
  365. <button type="button" class="btn btn-danger remove-column">&times;</button>
  366. </div>
  367. </div>`;
  368. $('#columnInputs').append(newColumnField);
  369. $('.remove-column').show();
  370. });
  371. // Remove Column Field
  372. $(document).on('click', '.remove-column', function () {
  373. $(this).closest('.column-group').remove();
  374. if ($('.column-group').length === 1) {
  375. $('.remove-column').hide();
  376. }
  377. });
  378. $('#createCategoryBtn').click(function () {
  379. var categoryName = $('#categoryname').val().trim();
  380. //var columnNames = $('.columnname').map(function () {
  381. var columnNames = $('input[name="columns[]"]').map(function () {
  382. return $(this).val().trim();
  383. }).get().filter(name => name !== "");
  384. console.log("categoryName=", categoryName);
  385. console.log("columnNames=", columnNames);
  386. if (categoryName === "") {
  387. Swal.fire({
  388. title: "Validation Error",
  389. text: "Please enter a category name.",
  390. icon: "warning",
  391. confirmButtonText: "OK"
  392. });
  393. return;
  394. }
  395. if (columnNames.length < 2) {
  396. Swal.fire({
  397. title: "Validation Error",
  398. text: "Please enter at least two column names.",
  399. icon: "warning",
  400. confirmButtonText: "OK"
  401. });
  402. return;
  403. }
  404. if (!validateColumns(columnNames)) {
  405. return;
  406. }
  407. $('#createCategoryBtn').prop('disabled', true).text('Processing...');
  408. $.ajax({
  409. url: '/gcc/api/category/save',
  410. type: 'POST',
  411. contentType: 'application/json',
  412. data: JSON.stringify({ categoryname: categoryName, columns: columnNames }),
  413. success: function (response) {
  414. $('#createCategoryBtn').prop('disabled', false).text('Save Category');
  415. Swal.fire({
  416. title: "Success",
  417. text: "Category saved successfully!",
  418. icon: "success",
  419. confirmButtonText: "OK"
  420. }).then(function () {
  421. $('#addcategoryform').modal('hide');
  422. $('#createCategoryBtn').prop('disabled', false).text('Save Category');
  423. location.reload();
  424. });
  425. },
  426. error: function (error) {
  427. $('#createCategoryBtn').prop('disabled', false).text('Save Category');
  428. Swal.fire({
  429. title: "Error",
  430. text: error.responseText,
  431. icon: "error",
  432. confirmButtonText: "OK"
  433. });
  434. }
  435. });
  436. });
  437. /* $('#createCategoryBtn').click(function () {
  438. var categoryName = $('#categoryname').val().trim();
  439. var columnNames = $('.columnname').map(function () {
  440. return $(this).val().trim();
  441. }).get().filter(name => name !== "");
  442. console.log("categoryName=========="+categoryName);
  443. console.log("columnNames=========="+columnNames);
  444. // Validation: Ensure category name is not empty and at least two columns are provided
  445. if (categoryName === "") {
  446. Swal.fire({
  447. title: 'Validation Error',
  448. text: 'Please enter a category name.',
  449. icon: 'warning',
  450. confirmButtonText: 'OK'
  451. });
  452. return;
  453. }
  454. if (columnNames.length < 2) {
  455. Swal.fire({
  456. title: 'Validation Error',
  457. text: 'Please enter at least two column names.',
  458. icon: 'warning',
  459. confirmButtonText: 'OK'
  460. });
  461. return;
  462. }
  463. // Proceed with AJAX request if validation passes
  464. $.ajax({
  465. url: '/gcc/api/category/save',
  466. type: 'POST',
  467. contentType: 'application/json',
  468. data: JSON.stringify({ categoryname: categoryName, columns: columnNames }),
  469. success: function (response) {
  470. Swal.fire({
  471. title: 'Success',
  472. text: 'Category saved successfully!',
  473. icon: 'success',
  474. confirmButtonText: 'OK'
  475. }).then(function () {
  476. $('#addcategoryform').modal('hide');
  477. location.reload();
  478. });
  479. },
  480. error: function (error) {
  481. Swal.fire({
  482. title: 'Error',
  483. text: error.responseText,
  484. icon: 'error',
  485. confirmButtonText: 'OK'
  486. });
  487. }
  488. });
  489. }); */
  490. // Function to fetch category details and populate the edit modal
  491. window.callEdit = function (categoryId) {
  492. fetchCategoryDetails(categoryId);
  493. return false;
  494. };
  495. function fetchCategoryDetails(categoryId) {
  496. $.ajax({
  497. url: '/gcc/api/category/showcategoryId',
  498. type: 'GET',
  499. data: { category_id: categoryId },
  500. success: function (response) {
  501. if (response) {
  502. $('#categoryId').val(response.category_id);
  503. $('#showcategoryName').val(response.category_name);
  504. $('#editColumnInputs').empty();
  505. $('#editaddColumnInputs').empty();
  506. if (response.columns && response.columns.length > 0) {
  507. response.columns.forEach(col => addEditColumnField(col.id, col.column_name));
  508. } else {
  509. addEditColumnField();
  510. }
  511. $('#editCategoryModal').modal({ backdrop: 'static', keyboard: false });
  512. } else {
  513. Swal.fire('Error', 'Category not found.', 'error');
  514. }
  515. },
  516. error: function (xhr) {
  517. Swal.fire('Error', 'Error fetching category details: ' + xhr.responseText, 'error');
  518. }
  519. });
  520. }
  521. function addEditColumnField(id = "", value = "", containerId = "editColumnInputs") {
  522. let removeButton = containerId === "editColumnInputs"
  523. ? `<button type="button" class="btn btn-danger" onclick="removeColumn(this, '${id}')">&times;</button>`
  524. : `<button type="button" class="btn btn-danger remove-column">&times;</button>`;
  525. let columnField = `
  526. <div class="form-group row column-group">
  527. <input type="hidden" class="showcolumnId" value="${id}">
  528. <div class="col-sm-10">
  529. <input type="text" class="form-control showcolumnname" name="columns[]" placeholder="Column Name" value="${value}" required>
  530. </div>
  531. <div class="col-sm-2">
  532. ${removeButton}
  533. </div>
  534. </div>`;
  535. $('#' + containerId).append(columnField);
  536. }
  537. $('#addMoreEditColumn').click(function () {
  538. addEditColumnField("", "", "editaddColumnInputs");
  539. });
  540. $(document).ready(function () {
  541. window.removeColumn = function (button, columnId) {
  542. if (columnId) {
  543. Swal.fire({
  544. title: "Are you sure?",
  545. text: "This column will be permanently deleted!",
  546. icon: "warning",
  547. showCancelButton: true,
  548. confirmButtonColor: "#d33",
  549. cancelButtonColor: "#3085d6",
  550. confirmButtonText: "Yes, delete it!"
  551. }).then((result) => {
  552. if (result.isConfirmed) {
  553. $.ajax({
  554. url: '/gcc/api/category/deleteColumnById',
  555. type: 'POST',
  556. data: { columnId: columnId },
  557. success: function (response) {
  558. if (response.success) {
  559. $(button).closest('.column-group').remove();
  560. Swal.fire({
  561. title: "Deleted!",
  562. text: "Column has been removed.",
  563. icon: "success",
  564. timer: 2000, // Auto-close after 2 seconds
  565. showConfirmButton: false
  566. });
  567. } else {
  568. Swal.fire({
  569. title: "Error",
  570. text: "Unable to delete column. Try again.",
  571. icon: "error",
  572. timer: 2000, // Auto-close after 2 seconds
  573. showConfirmButton: false
  574. });
  575. }
  576. },
  577. error: function (xhr) {
  578. Swal.fire("Error", "Something went wrong: " + xhr.responseText, "error");
  579. }
  580. });
  581. }
  582. });
  583. } else {
  584. console.log("columnId=" + columnId);
  585. Swal.fire("Error!", "Problem in columnId", "error");
  586. }
  587. };
  588. });
  589. // Event to remove column input dynamically
  590. $(document).on('click', '.remove-column', function () {
  591. $(this).closest('.column-group').remove();
  592. });
  593. $('#updateCategoryButton').click(function () {
  594. let categoryId = parseInt($('#categoryId').val(), 10);
  595. let existingColumns = [];
  596. $('#editColumnInputs .column-group').each(function () {
  597. let columnId = parseInt($(this).find('.showcolumnId').val(), 10);
  598. let columnName = $(this).find('.showcolumnname').val();
  599. if (columnName.trim() !== "") {
  600. existingColumns.push({ id: columnId, name: columnName });
  601. }
  602. });
  603. let newColumns = [];
  604. $('#editaddColumnInputs .column-group').each(function () {
  605. let columnName = $(this).find('.showcolumnname').val();
  606. if (columnName.trim() !== "") {
  607. newColumns.push({ name: columnName });
  608. }
  609. });
  610. console.log("Category ID:", categoryId);
  611. console.log("Existing Columns:", existingColumns);
  612. console.log("New Columns:", newColumns);
  613. let allColumnNames = [...existingColumns.map(col => col.name), ...newColumns.map(col => col.name)];
  614. console.log("allColumnNames="+allColumnNames);
  615. if ((existingColumns.length + newColumns.length) < 2) {
  616. Swal.fire({
  617. title: "Info",
  618. text: "You must have at least 2 columns!",
  619. icon: "info",
  620. confirmButtonText: "OK"
  621. });
  622. return;
  623. }
  624. if (!validateColumns(allColumnNames)) {
  625. return;
  626. }
  627. $('#updateCategoryButton').prop('disabled', true).text('Processing');
  628. $.ajax({
  629. url: '/gcc/api/category/updateCategoryColumns',
  630. type: 'POST',
  631. contentType: 'application/json',
  632. data: JSON.stringify({ categoryId: categoryId, columns: existingColumns }),
  633. success: function (response) {
  634. $('#updateCategoryButton').prop('disabled', false).text('Save Changes');
  635. if (response.success) {
  636. Swal.fire({
  637. title: "Success!",
  638. text: "Category updated successfully!",
  639. icon: "success",
  640. showConfirmButton: false,
  641. timer: 2000
  642. }).then(() => {
  643. $('#updateCategoryButton').prop('disabled', false).text('Save Changes');
  644. location.reload();
  645. });
  646. } else {
  647. $('#updateCategoryButton').prop('disabled', false).text('Save Changes');
  648. Swal.fire({
  649. title: "Error",
  650. text: "Unable to update column. Try again.",
  651. icon: "error",
  652. showConfirmButton: true
  653. });
  654. }
  655. },
  656. error: function (xhr) {
  657. $('#updateCategoryButton').prop('disabled', false).text('Save Changes');
  658. Swal.fire("Error", "Failed to update category: " + xhr.responseText, "error");
  659. }
  660. });
  661. if (newColumns.length > 0) {
  662. $('#updateCategoryButton').prop('disabled', true).text('Processing');
  663. $.ajax({
  664. url: '/gcc/api/category/addNewColumns',
  665. type: 'POST',
  666. contentType: 'application/json',
  667. data: JSON.stringify({ categoryId: categoryId, columns: newColumns }),
  668. success: function (response) {
  669. $('#updateCategoryButton').prop('disabled', false).text('Save Changes');
  670. if (response.success) {
  671. Swal.fire({
  672. title: "Success!",
  673. text: "Category updated successfully!",
  674. icon: "success",
  675. showConfirmButton: false,
  676. timer: 2000
  677. }).then(() => {
  678. $('#updateCategoryButton').prop('disabled', false).text('Save Changes');
  679. location.reload();
  680. });
  681. } else {
  682. $('#updateCategoryButton').prop('disabled', false).text('Save Changes');
  683. Swal.fire({
  684. title: "Error",
  685. text: "Unable to update column. Try again.",
  686. icon: "error",
  687. showConfirmButton: true
  688. });
  689. }
  690. },
  691. error: function (xhr) {
  692. $('#updateCategoryButton').prop('disabled', false).text('Save Changes');
  693. Swal.fire("Error", "Failed to add new columns: " + xhr.responseText, "error");
  694. }
  695. });
  696. $('#updateCategoryButton').prop('disabled', false).text('Save Changes');
  697. }
  698. });
  699. /* $('#updateCategoryButton').click(function () {
  700. let categoryId = parseInt($('#categoryId').val(), 10);
  701. // Collect existing columns
  702. let existingColumns = [];
  703. $('#editColumnInputs .column-group').each(function () {
  704. let columnId = parseInt($(this).find('.showcolumnId').val(), 10);
  705. let columnName = $(this).find('.showcolumnname').val();
  706. if (columnName.trim() !== "") {
  707. existingColumns.push({ id: columnId, name: columnName });
  708. }
  709. });
  710. // Collect new columns
  711. let newColumns = [];
  712. $('#editaddColumnInputs .column-group').each(function () {
  713. let columnName = $(this).find('.showcolumnname').val();
  714. if (columnName.trim() !== "") {
  715. newColumns.push({ name: columnName });
  716. }
  717. });
  718. // Debugging: Log values before AJAX calls
  719. console.log("Category ID:", categoryId);
  720. console.log("Existing Columns:", existingColumns);
  721. console.log("New Columns:", newColumns);
  722. if ((existingColumns.length + newColumns.length) < 2) {
  723. Swal.fire({
  724. title: "Info",
  725. text: "You must have at least 2 columns!",
  726. icon: "info",
  727. confirmButtonText: "OK"
  728. });
  729. return; // Stop execution if condition fails
  730. }
  731. // 1️⃣ Send existing columns update AJAX
  732. $.ajax({
  733. url: '/gcc/api/category/updateCategoryColumns',
  734. type: 'POST',
  735. contentType: 'application/json',
  736. data: JSON.stringify({ categoryId: categoryId, columns: existingColumns }),
  737. success: function (response) {
  738. if (response.success) {
  739. Swal.fire({
  740. title: "Success!",
  741. text: "Category updated successfully!",
  742. icon: "success",
  743. showConfirmButton: false,
  744. timer: 2000 // Show message for 2 seconds
  745. }).then(() => {
  746. location.reload(); // Reload the page after SweetAlert closes
  747. });
  748. } else {
  749. Swal.fire({
  750. title: "Error",
  751. text: "Unable to update column. Try again.",
  752. icon: "error",
  753. showConfirmButton: true
  754. });
  755. }
  756. },
  757. error: function (xhr) {
  758. Swal.fire("Error", "Failed to update category: " + xhr.responseText, "error");
  759. }
  760. });
  761. // 2️⃣ Send new columns addition AJAX (only if there are new columns)
  762. if (newColumns.length > 0) {
  763. $.ajax({
  764. url: '/gcc/api/category/addNewColumns',
  765. type: 'POST',
  766. contentType: 'application/json',
  767. data: JSON.stringify({ categoryId: categoryId, columns: newColumns }),
  768. success: function (response) {
  769. if (response.success) {
  770. Swal.fire({
  771. title: "Success!",
  772. text: "Category updated successfully!",
  773. icon: "success",
  774. showConfirmButton: false,
  775. timer: 2000 // Show message for 2 seconds
  776. }).then(() => {
  777. location.reload(); // Reload the page after SweetAlert closes
  778. });
  779. } else {
  780. Swal.fire({
  781. title: "Error",
  782. text: "Unable to update column. Try again.",
  783. icon: "error",
  784. showConfirmButton: true
  785. });
  786. }
  787. },
  788. error: function (xhr) {
  789. Swal.fire("Error", "Failed to add new columns: " + xhr.responseText, "error");
  790. }
  791. });
  792. }
  793. }); */
  794. window.openDeleteModal = function (categoryId) {
  795. $('#categoryId').val(categoryId); // Set the categoryId before showing the modal
  796. fetchDeleteCategoryDetails();
  797. return false; // Prevent default anchor click behavior
  798. };
  799. function fetchDeleteCategoryDetails() {
  800. Swal.fire({
  801. title: 'Confirm Deletion',
  802. text: 'Are you sure you want to delete this category?',
  803. icon: 'warning',
  804. showCancelButton: true,
  805. confirmButtonText: 'Delete',
  806. cancelButtonText: 'Cancel',
  807. customClass: {
  808. container: 'swal-container',
  809. popup: 'swal-popup',
  810. confirmButton: 'swal-confirm-button',
  811. cancelButton: 'swal-cancel-button'
  812. },
  813. width: '80%',
  814. padding: '3rem',
  815. heightAuto: false
  816. }).then((result) => {
  817. if (result.isConfirmed) {
  818. // Call the function to delete the category
  819. deleteCategory();
  820. }
  821. });
  822. }
  823. function deleteCategory() {
  824. var categoryId = $('#categoryId').val(); // Ensure this is correctly set
  825. console.log("Deleting category with ID: " + categoryId); // Debugging line
  826. $.ajax({
  827. url: '/gcc/api/category/delete/' + categoryId,
  828. type: 'DELETE',
  829. success: function (response) {
  830. Swal.fire({
  831. title: 'Deleted!',
  832. text: 'Category has been deleted.',
  833. icon: 'success'
  834. }).then(() => {
  835. location.reload(); // Refresh the page or update the UI as needed
  836. });
  837. },
  838. error: function (xhr, status, error) {
  839. Swal.fire({
  840. title: 'Error',
  841. text: 'Error deleting category: ' + xhr.responseText,
  842. icon: 'error'
  843. });
  844. }
  845. });
  846. }
  847. });
  848. </script>
  849. </body>
  850. </html>