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.

1411 lines
64 KiB

​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
  1. <!DOCTYPE html>
  2. <html xmlns:th="http://www.thymeleaf.org">
  3. <head th:replace="~{fragments/head-headquarters :: head}"></head>
  4. <meta charset="UTF-8">
  5. <style>
  6. .small-input {
  7. width: 150px;
  8. /* Adjust the width as needed */
  9. }
  10. .small-table th,
  11. .small-table td {
  12. font-size: 14px;
  13. /* Adjust font size as needed */
  14. }
  15. /* Reduce padding for table cells */
  16. .small-table td,
  17. .small-table th {
  18. padding: 5px;
  19. /* Adjust padding as needed */
  20. }
  21. .multiselect {
  22. text-wrap: balance;
  23. }
  24. .selectBox {
  25. position: relative;
  26. }
  27. .selectBox select {
  28. width: 100%;
  29. }
  30. .overSelect {
  31. position: absolute;
  32. left: 0;
  33. right: 0;
  34. top: 0;
  35. bottom: 0;
  36. }
  37. .checkboxes {
  38. display: none;
  39. border: 0.5px #7c7c7c solid;
  40. background-color: #ffffff;
  41. max-height: 74px;
  42. overflow-y: scroll;
  43. }
  44. .checkboxes label {
  45. display: block;
  46. font-weight: normal;
  47. white-space: nowrap;
  48. min-height: 1.2em;
  49. background-color: #ffffff00;
  50. padding: 0 2.25rem 0 .75rem;
  51. }
  52. .checkboxes label:hover {
  53. background-color: #1e90ff;
  54. }
  55. .multiselect .selectBox {
  56. width: auto;
  57. /* Allow width to adjust automatically based on content */
  58. min-width: 150px;
  59. /* Set a minimum width */
  60. max-width: 100%;
  61. /* Prevent exceeding container width */
  62. overflow: hidden;
  63. border: 0.5px #7c7c7c solid;
  64. }
  65. .multiselect .selectBox select {
  66. height: auto;
  67. /* Allow height to adjust automatically */
  68. overflow: hidden;
  69. /* Hide overflow if necessary */
  70. text-wrap: balance;
  71. /* Optional: remove border if needed */
  72. }
  73. .multiselect .checkboxes {
  74. max-height: 200px;
  75. /* Adjust based on your design */
  76. overflow-y: auto;
  77. }
  78. /* Default style for the box */
  79. .box-filled {
  80. background-color: #2a807f;
  81. color: white;
  82. padding: 5px 10px;
  83. margin: 5px;
  84. border-radius: 15px;
  85. display: inline-block;
  86. }
  87. .box-empty {
  88. background-color: #f0f0f0;
  89. /* Light gray for empty state */
  90. color: #888;
  91. padding: 5px 10px;
  92. border-radius: 3px;
  93. display: inline-block;
  94. }
  95. </style>
  96. <body>
  97. <div id="page-container"
  98. class="sidebar-o sidebar-dark enable-page-overlay side-scroll page-header-fixed page-header-dark">
  99. <aside th:replace="~{fragments/aside-right :: aside}"></aside>
  100. <nav th:replace="~{fragments/nav-headquarters :: nav}"></nav>
  101. <header th:replace="~{fragments/header-headquarters :: header}"></header>
  102. <main id="main-container">
  103. <div class="content">
  104. <div class="block block-rounded">
  105. <div class="block-header block-header-default">
  106. <h3 class="block-title"> List of Blocked Halls</h3>
  107. <div class="block-options">
  108. <button type="button" class="btn btn-primary" id="addButton"><i
  109. class="far fa-plus-square"></i> Block the Halls
  110. </button>
  111. </div>
  112. </div>
  113. <div class="block-content p-0">
  114. <div class="p-sm-4 p-0">
  115. <div class="table-responsive">
  116. <table id="gccblockingTable"
  117. class="table table-bordered table-striped table-vcenter js-dataTable-responsive">
  118. <thead class="thead-light">
  119. <tr>
  120. <th class="text-center no-sort">S.No</th>
  121. <th class="text-center">Blocking Date</th>
  122. <th class="text-center">Start Date</th>
  123. <th class="text-center">End Date</th>
  124. <th class="text-center">Reason for Blocking</th>
  125. <th class="text-center">No of Halls</th>
  126. <th class="text-center">Action</th>
  127. </tr>
  128. </thead>
  129. <tbody>
  130. <tr th:each="gccblockedDate, gccIndex : ${gccblocked}">
  131. <td class="text-center" th:text="${gccIndex.index + 1}"></td>
  132. <td class="text-center"
  133. th:text="${#dates.format(gccblockedDate.cdate, 'yyyy-MM-dd')}"></td>
  134. <td class="text-center"
  135. th:text="${#dates.format(gccblockedDate.startDate, 'yyyy-MM-dd')}"></td>
  136. <td class="text-center"
  137. th:text="${#dates.format(gccblockedDate.endDate, 'yyyy-MM-dd')}"></td>
  138. <td class="text-center" th:text="${gccblockedDate.blockingReason}"></td>
  139. <td class="text-center">
  140. <button style="cursor: pointer;
  141. background-color:darkcyan;
  142. color: white;
  143. border: none;
  144. padding: 4px 10px;
  145. font-size: 12px;
  146. border-radius: 5px;
  147. " th:onclick="showBlockedHalls([[${gccblockedDate.hallId}]],
  148. [[${gccblockedDate.blockingReason}]],
  149. [[${gccblockedDate.startDate}]],
  150. [[${gccblockedDate.endDate}]],
  151. [[${gccblockedDate.blockingId}]],
  152. [[${gccblockedDate.bookingIds}]])"
  153. th:text="${hallCountMap[gccblockedDate.blockingId]}">
  154. </button>
  155. </td>
  156. <td class="text-center">
  157. <span type="button" class="badge bg-warning"
  158. th:data-blocking-id="${gccblockedDate.blockingId}"
  159. th:data-from-date="${#dates.format(gccblockedDate.startDate, 'yyyy-MM-dd')}"
  160. th:data-end-date="${#dates.format(gccblockedDate.endDate, 'yyyy-MM-dd')}"
  161. onclick="cancelBlockedevent(this)">Unblock</span>
  162. </td>
  163. </tr>
  164. </tbody>
  165. </table>
  166. </div>
  167. </div>
  168. </div>
  169. </div>
  170. </div>
  171. </main>
  172. <!-- Modal for displaying blocked halls -->
  173. <!-- Modal for displaying blocked halls -->
  174. <div class="modal fade" id="blockedHallsModal" tabindex="-1" role="dialog"
  175. aria-labelledby="blockedHallsModalLabel" aria-hidden="true">
  176. <div class="modal-dialog" role="document">
  177. <div class="modal-content" style="width: 160%; margin-left: -134px;">
  178. <div class="modal-header">
  179. <h5 class="modal-title" id="blockedHallsModalLabel">Blocked Halls</h5>
  180. <button type="button" class="close" data-bs-dismiss="modal" aria-label="Close">
  181. <span aria-hidden="true">&times;</span>
  182. </button>
  183. </div>
  184. <div class="modal-body">
  185. <div class="row" id="blockedHallsDetails">
  186. <p>
  187. Reason for Blocking: <strong><span id="blockingReason"></span></strong>
  188. </p>
  189. </div>
  190. <table class="table table-bordered">
  191. <thead>
  192. <tr>
  193. <th class="text-center">S.No</th>
  194. <th class="text-center">Hall Name</th>
  195. <th class="text-center">Zone</th>
  196. <th class="text-center">Division</th>
  197. <th class="text-center">No. of Bookings between Dates</th>
  198. <th class="text-center">Refunded Amount</th>
  199. </tr>
  200. </thead>
  201. <tbody id="blockedHallsTableBody">
  202. </tbody>
  203. </table>
  204. <div id="bookingDetailsSection" style="display:none;">
  205. <h5>Booking Details</h5>
  206. <table class="table table-bordered">
  207. <thead>
  208. <tr>
  209. <th class="text-center">S.No</th>
  210. <th class="text-center">Booking ID</th>
  211. <th class="text-center">Start Date</th>
  212. <th class="text-center">End Date</th>
  213. <th class="text-center">Booking Date</th>
  214. </tr>
  215. </thead>
  216. <tbody id="bookingDetailsTableBody">
  217. </tbody>
  218. </table>
  219. </div>
  220. </div>
  221. </div>
  222. </div>
  223. </div>
  224. <!-- Modal for GCC Blocked Details -->
  225. <div class="modal fade" id="gccBlockedModal" tabindex="-1" role="dialog" aria-labelledby="gccBlockedModalLabel"
  226. aria-hidden="true">
  227. <div class="modal-dialog modal-dialog-centered modal-lg" role="document">
  228. <div class="modal-content">
  229. <div class="modal-header">
  230. <h5 class="modal-title" id="modalHallName">GCC Blocked Events for Hall:</h5>
  231. <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
  232. </div>
  233. <div class="modal-body">
  234. <div class="table-responsive">
  235. <table id="gccBlockedEventsTable" class="table table-bordered table-striped table-vcenter">
  236. <thead class="thead-light">
  237. <tr>
  238. <th class="text-center">From Date</th>
  239. <th class="text-center">To Date</th>
  240. <th class="text-center">No of Days</th>
  241. <!--<th class="text-center">User Details</th>
  242. <th class="text-center">Booking Details</th>-->
  243. </tr>
  244. </thead>
  245. <tbody id="gccBlockedEventsBody">
  246. <!-- Rows will be dynamically appended here -->
  247. </tbody>
  248. </table>
  249. </div>
  250. </div>
  251. </div>
  252. </div>
  253. </div>
  254. <!--List of GCC Blocked Halls -->
  255. <div class="modal fade" id="viewdetails">
  256. <div class="modal-dialog modal-xl">
  257. <div class="modal-content">
  258. <!-- Modal Header -->
  259. <div class="modal-header">
  260. <h4 class="modal-title">List of GCC Blocked Halls </h4>
  261. <button type="button" class="btn" data-bs-dismiss="modal">&times;</button>
  262. </div>
  263. <!-- Modal Body -->
  264. <div class="modal-body">
  265. <div class="row">
  266. <!-- Zone dropdown taking up half of the row and centered -->
  267. <div class="col-sm-6 mx-auto">
  268. <label for="zoneMultiselect">Zones:</label>
  269. <div id="zoneMultiselect" class="multiselect">
  270. <div id="zoneSelectLabel" class="selectBox"
  271. onclick="toggleCheckboxArea('zoneSelectOptions')">
  272. <select class="form-select">
  273. <option>Select Zones</option>
  274. </select>
  275. <div class="overSelect"></div>
  276. </div>
  277. <div id="zoneSelectOptions" class="checkboxes">
  278. <!-- Zone checkboxes will be added here dynamically -->
  279. </div>
  280. </div>
  281. </div>
  282. <div class="col-sm-6 mx-auto">
  283. <label for="hallMultiselect">Hall Name:</label>
  284. <div id="hallMultiselect" class="multiselect">
  285. <div id="hallSelectLabel" class="selectBox"
  286. onclick="toggleCheckboxArea('hallSelectOptions')">
  287. <select class="form-select" id="hallSelect">
  288. <option>Select Halls</option>
  289. </select>
  290. <div class="overSelect"></div>
  291. </div>
  292. <div id="hallSelectOptions" class="checkboxes">
  293. <!-- Hall checkboxes will be added here dynamically -->
  294. </div>
  295. </div>
  296. </div>
  297. </div>
  298. <div class="row">
  299. <div class="col-sm">
  300. <label for="fromDate">From Date:</label>
  301. <input type="date" class="form-control" id="fromDate" name="fromDate" required>
  302. </div>
  303. <div class="col-sm">
  304. <label for="toDate">To Date:</label>
  305. <input type="date" class="form-control" id="toDate" name="toDate" required>
  306. </div>
  307. </div>
  308. <div class="row">
  309. <div class="col-sm-6">
  310. <label for="reasonforBlocking">Reason For Blocking</label>
  311. <input type="text" class="form-control" id="reasonforBlocking" name="reasonforBlocking"
  312. required>
  313. </div>
  314. </div>
  315. <div class="row" id="fileUploadSection">
  316. <!-- Upload document -->
  317. <div class="col-sm-4">
  318. <label for="uploadDocument0">Upload document</label>
  319. <input type="file" class="form-control uploadDocument" id="uploadDocument0"
  320. name="document" required>
  321. </div>
  322. <div class="col-sm-4">
  323. <label for="description0">Description</label>
  324. <input type="text" class="form-control description" id="description0"
  325. name="description">
  326. </div>
  327. <!-- Add More Button
  328. <div class="col-sm-2 align-self-end">
  329. <button type="button" class="btn btn-sm btn-success" id="addMoreFields">
  330. <i class="fas fa-plus"></i> Add More
  331. </button>
  332. </div>-->
  333. </div>
  334. <div class="row mt-3">
  335. <!-- Button at left end corner -->
  336. <div class="col text-left">
  337. <button type="button" class="btn btn-primary" id="viewButton" style="margin-left:46%"
  338. onclick="getBlockedevents()">View
  339. </button>
  340. </div>
  341. </div>
  342. <div class="content" id="bookinglistdataTable" style="display:none">
  343. <div class="block block-rounded">
  344. <div class="block-content p-0">
  345. <div class="p-sm-4 p-0">
  346. <div class="table-responsive">
  347. <table
  348. class="table table-bordered table-striped table-vcenter js-dataTable-responsive">
  349. <thead class="thead-light">
  350. <tr class="table-bordered">
  351. <th class="text-center no-sort">S.No
  352. <input type="checkbox" id="selectAllCheckbox">
  353. </th>
  354. <th class="text-center no-sort">Hall Name</th>
  355. <th class="text-center no-sort">Zone</th>
  356. <th class="text-center no-sort">Division</th>
  357. <th class="text-center no-sort">Reason For Booking</th>
  358. <th class="text-center no-sort">No of days</th>
  359. <th class="text-center no-sort">Hall Amount</th>
  360. <th class="text-center">From Date</th>
  361. <th class="text-center">To Date</th>
  362. <th class="text-center no-sort">Status</th>
  363. </tr>
  364. </thead>
  365. <tbody id="bookingTableBody"></tbody>
  366. </table>
  367. </div>
  368. <div class="row mt-3">
  369. <!-- Button at left end corner -->
  370. <div class="col text-left">
  371. <button type="button" class="btn btn-primary" id="cancelAll"
  372. style="margin-left:46%">Block All
  373. </button>
  374. </div>
  375. </div>
  376. </div>
  377. </div>
  378. </div>
  379. </div>
  380. </div>
  381. <!-- Modal Footer -->
  382. <div class="modal-footer">
  383. <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
  384. </div>
  385. </div>
  386. </div>
  387. </div>
  388. </div>
  389. <div th:replace="~{fragments/resetpassword :: div}"></div>
  390. <footer th:replace="~{fragments/footer2 :: footer}"></footer>
  391. </div>
  392. <script th:replace="~{fragments/loginscript :: script}"></script>
  393. <script>
  394. $(document).ready(function () {
  395. let fieldIndex = 1; // To uniquely identify each field set
  396. // Event handler for adding more fields
  397. $('#addMoreFields').click(function () {
  398. // Create new fields with a minus button
  399. var newFields = `
  400. <div class="row mt-3" id="fieldSet${fieldIndex}">
  401. <div class="col-sm-4">
  402. <label for="uploadDocument${fieldIndex}">Upload document</label>
  403. <input type="file" class="form-control" id="uploadDocument${fieldIndex}" name="uploadDocument" required>
  404. </div>
  405. <div class="col-sm-4">
  406. <label for="description${fieldIndex}">Description</label>
  407. <input type="text" class="form-control" id="description${fieldIndex}" name="description" required>
  408. </div>
  409. <div class="col-sm-2 align-self-end">
  410. <button type="button" class="btn btn-sm btn-danger removeFields">
  411. <i class="fas fa-minus"></i> Remove
  412. </button>
  413. </div>
  414. </div>`;
  415. // Append the new fields after the initial section
  416. $('#fileUploadSection').after(newFields);
  417. fieldIndex++; // Increment the index for uniqueness
  418. });
  419. // Event delegation to handle removing fields
  420. $(document).on('click', '.removeFields', function () {
  421. // Remove the entire row (field set) where the button is clicked
  422. $(this).closest('.row').remove();
  423. });
  424. });
  425. function showBlockedHalls(hallIds, blockingReason, startDate, endDate, blockingId) {
  426. //console.log('Sending parameters - hallIds:', hallIds, ', blockingId:', blockingId);
  427. if (!hallIds || hallIds === 'undefined') {
  428. //console.error('Invalid hallIds:', hallIds);
  429. return;
  430. }
  431. $.ajax({
  432. url: '/communityhall/admin/api/getblockedbookingdetails',
  433. method: 'GET',
  434. data: {
  435. hallIds: hallIds,
  436. blockingId: blockingId
  437. },
  438. success: function (data) {
  439. $('#blockedHallsTableBody').empty();
  440. $('#bookingDetailsSection').hide();
  441. const formatDate = (dateString) => {
  442. if (!dateString) return 'N/A';
  443. const date = new Date(dateString);
  444. return date.toLocaleDateString('en-CA');
  445. };
  446. $('#blockingReason').text(blockingReason || 'N/A');
  447. $('#startDate').text(formatDate(startDate));
  448. $('#endDate').text(formatDate(endDate));
  449. data.forEach(function (hall, index) {
  450. $('#blockedHallsTableBody').append(
  451. `<tr>
  452. <td class="text-center">${index + 1}</td>
  453. <td class="text-center">${hall.hallName}</td>
  454. <td class="text-center">${hall.zone}</td>
  455. <td class="text-center">${hall.division}</td>
  456. <td class="text-center">
  457. <button href="#" class="view-booking-details"
  458. data-booking-ids="${hall.bookingIds.join(',')}"
  459. data-hall-id="${hall.hallId}"
  460. data-blocking-id="${blockingId}"
  461. style="cursor: pointer;
  462. background-color: darkcyan;
  463. color: white;
  464. border: none;
  465. padding: 4px 10px;
  466. font-size: 12px;
  467. border-radius: 5px;">
  468. ${hall.bookingIds.length}
  469. </button>
  470. </td>
  471. <td class="text-center">${hall.refundedAmount || 'N/A'}</td>
  472. </tr>`
  473. );
  474. });
  475. $('#blockedHallsModal').modal('show');
  476. },
  477. error: function (error) {
  478. console.error('Error fetching blocked halls:', error);
  479. }
  480. });
  481. }
  482. $(document).on('click', '.view-booking-details', function (e) {
  483. e.preventDefault();
  484. const bookingIdsString = $(this).data('booking-ids');
  485. const bookingIds = bookingIdsString.toString().split(',');
  486. //console.log('Fetching booking details for bookingIds:', bookingIds);
  487. if (!bookingIds || bookingIds.length === 0) {
  488. console.error('Invalid bookingIds:', bookingIds);
  489. return;
  490. }
  491. $('#bookingDetailsTableBody').empty();
  492. let bookingDetailsFetched = 0;
  493. bookingIds.forEach(function (bookingId) {
  494. $.ajax({
  495. url: '/communityhall/admin/api/getbookingdetails',
  496. method: 'GET',
  497. data: {
  498. bookingId: bookingId
  499. },
  500. success: function (data) {
  501. const formatDate = (dateString) => {
  502. if (!dateString) return 'N/A';
  503. const date = new Date(dateString);
  504. return date.toLocaleDateString('en-CA');
  505. };
  506. data.forEach(function (booking, index) {
  507. $('#bookingDetailsTableBody').append(
  508. `<tr>
  509. <td class="text-center">${bookingDetailsFetched + index + 1}</td>
  510. <td class="text-center">${booking.bookingId}</td>
  511. <td class="text-center">${formatDate(booking.startDate)}</td>
  512. <td class="text-center">${formatDate(booking.endDate)}</td>
  513. <td class="text-center">${formatDate(booking.bookingDate)}</td>
  514. </tr>`
  515. );
  516. });
  517. bookingDetailsFetched += data.length;
  518. if (bookingDetailsFetched === bookingIds.length) {
  519. $('#bookingDetailsSection').show();
  520. }
  521. },
  522. error: function (error) {
  523. console.error('Error fetching booking details:', error);
  524. }
  525. });
  526. });
  527. });
  528. $(document).ready(function () {
  529. // Initialize DataTable with buttons
  530. var buttons = [{
  531. extend: 'pageLength',
  532. className: 'btn btn-primary'
  533. }, {
  534. extend: 'copyHtml5',
  535. text: 'Copy',
  536. className: 'btn btn-primary'
  537. }, {
  538. extend: 'excelHtml5',
  539. text: 'Excel',
  540. className: 'btn btn-primary'
  541. }, {
  542. extend: 'csvHtml5',
  543. text: 'CSV',
  544. className: 'btn btn-primary'
  545. }, {
  546. extend: 'pdfHtml5',
  547. text: 'PDF',
  548. className: 'btn btn-primary'
  549. }];
  550. var dataTable = $('#gccblockingTable').DataTable({
  551. dom: 'Bftip',
  552. columnDefs: [{
  553. targets: 'no-sort',
  554. orderable: false
  555. }],
  556. lengthMenu: [
  557. [50, 100, 200, 500, -1],
  558. ['50 rows', '100 rows', '200 rows', '500 rows', 'Show all']
  559. ],
  560. scrollY: '50vh',
  561. fixedColumns: {
  562. left: 1,
  563. right: 1
  564. },
  565. buttons: buttons,
  566. responsive: true,
  567. searching: true,
  568. select: false,
  569. processing: false,
  570. });
  571. $('#gccblockingTable').on('click', '.gcc-blocked-badge', function (e) {
  572. e.preventDefault();
  573. var bookingRow = $(this).closest('tr');
  574. var hallName = bookingRow.find('td:nth-child(2)').text().trim();
  575. var hallId = $(this).data('hall-id');
  576. $('#modalHallName').text('GCC Blocked Events for Hall: ' + hallName);
  577. $.ajax({
  578. url: '/communityhall/admin/api/Gccblocking',
  579. type: 'GET',
  580. data: { hallId: hallId },
  581. success: function (response) {
  582. $('#gccBlockedEventsBody').empty();
  583. response.forEach(function (event) {
  584. var startDate = new Date(event.startDate);
  585. var endDate = new Date(event.endDate);
  586. var noOfDays = Math.ceil((endDate - startDate) / (1000 * 3600 * 24)) + 1;
  587. var formattedStartDate = startDate.toLocaleDateString('en-GB', {
  588. year: 'numeric',
  589. month: '2-digit',
  590. day: '2-digit'
  591. }).replace(/\//g, '-');
  592. var formattedEndDate = endDate.toLocaleDateString('en-GB', {
  593. year: 'numeric',
  594. month: '2-digit',
  595. day: '2-digit'
  596. }).replace(/\//g, '-');
  597. var rowHtml = '<tr>' +
  598. '<td class="text-center">' + formattedStartDate + '</td>' +
  599. '<td class="text-center">' + formattedEndDate + '</td>' +
  600. '<td class="text-center">' + noOfDays + '</td>' +
  601. '</tr>';
  602. $('#gccBlockedEventsBody').append(rowHtml);
  603. });
  604. }
  605. });
  606. $('#gccBlockedModal').modal('show');
  607. });
  608. // Booking details click handler
  609. $(document).on('click', '.view-booking-details', function () {
  610. var bookingId = $(this).data('booking-id');
  611. // Implement booking detail fetching logic here
  612. });
  613. });
  614. $(document).ready(function () {
  615. // Show modal when Add button is clicked
  616. $("#addButton").click(function () {
  617. $("#viewdetails").modal('show');
  618. getZone();
  619. });
  620. // Event handler for the View button
  621. $("#viewButton").click(function () {
  622. var selectedHalls = Array.from(document.querySelectorAll('#hallSelectOptions input[type="checkbox"]:checked'))
  623. .map(cb => cb.value)
  624. .filter(value => !isNaN(value)); // Filter out non-numeric values
  625. var fromDate = $("#fromDate").val();
  626. var toDate = $("#toDate").val();
  627. // Make AJAX call to backend API
  628. $.ajax({
  629. url: '/communityhall/admin/api/filter',
  630. type: 'GET',
  631. data: {
  632. hallIds: selectedHalls.join(','), // Pass selected hall IDs as comma-separated values
  633. fromDate: fromDate,
  634. toDate: toDate
  635. },
  636. success: function (response) {
  637. var bookings = response.bookings;
  638. var blockedEvents = response.blockedEvents;
  639. // Check if there are any blocked events
  640. if (blockedEvents && blockedEvents.length > 0) {
  641. Swal.fire({
  642. title: 'Dates Blocked',
  643. text: 'The selected dates are blocked by others. Please contact the department to unblock.',
  644. icon: 'warning'
  645. });
  646. return; // Exit the function if blocked dates are found
  647. }
  648. // Clear previous table rows
  649. $("#bookingTableBody").empty();
  650. // Populate the table with fetched data
  651. $.each(bookings, function (index, booking) {
  652. // Always show 'Booked', but show 'Unblock' only if blockingId is present
  653. var statusBadge = '<span class="badge bg-success">User Booked</span>';
  654. // Create table row
  655. var row = '<tr>' +
  656. '<td class="text-center">' +
  657. '<input type="checkbox" class="bookingCheckbox" id="snoCheckbox' + index + '" name="snoCheckbox" value="' + booking.bookingId + '" data-additional-value="' + booking.hallDetails.hallId + '"> ' + (index + 1) +
  658. '</td>' +
  659. '<td class="text-center">' + booking.hallDetails.hallName + '</td>' +
  660. '<td class="text-center">' + booking.hallDetails.zone + '</td>' +
  661. '<td class="text-center">' + booking.hallDetails.division + '</td>' +
  662. '<td class="text-center">' + booking.reason + '</td>' +
  663. '<td class="text-center">' + booking.noOfDays + '</td>' +
  664. '<td class="text-center">' + booking.hallAmount + '</td>' +
  665. '<td class="text-center">' + booking.startDate + '</td>' +
  666. '<td class="text-center">' + booking.endDate + '</td>' +
  667. '<td class="text-center">' + statusBadge + '</td>' +
  668. '</tr>';
  669. // Append the row to the table body
  670. $("#bookingTableBody").append(row);
  671. });
  672. // Show the table
  673. $("#bookinglistdataTable").show();
  674. $(".bookingCheckbox").change(function () {
  675. var hallId = $(this).data('additional-value');
  676. var isChecked = $(this).is(':checked');
  677. // Update all checkboxes with the same hall ID
  678. $(".bookingCheckbox").each(function () {
  679. if ($(this).data('additional-value') === hallId) {
  680. $(this).prop('checked', isChecked);
  681. }
  682. //updateHallCheckboxes();
  683. updateHallDisplay();
  684. });
  685. });
  686. },
  687. error: function (xhr, status, error) {
  688. console.error(xhr.responseText); // Log the error for debugging
  689. // Handle error
  690. }
  691. });
  692. });
  693. // Event handler for the Select All checkbox
  694. $("#selectAllCheckbox").click(function () {
  695. var isChecked = $(this).prop('checked');
  696. $("#bookingTableBody input[type='checkbox']").prop('checked', isChecked);
  697. //updateHallCheckboxes();
  698. updateHallDisplay(); // Update hall display based on selected hall IDs
  699. });
  700. // Event handler for the Cancel All button
  701. $("#cancelAll").click(function () {
  702. var fromDate = $("#fromDate").val();
  703. var toDate = $("#toDate").val();
  704. var reasonForBlocking = $("#reasonforBlocking").val();
  705. var uploadDocument = document.getElementById('uploadDocument0');
  706. if (!uploadDocument.files || uploadDocument.files.length === 0) {
  707. Swal.fire('Error!', 'Please upload a document.', 'error');
  708. return;
  709. }
  710. // Validate required inputs
  711. if (!reasonForBlocking.trim()) {
  712. Swal.fire({
  713. icon: 'warning',
  714. title: 'Missing Input',
  715. text: 'Please provide a reason for blocking.',
  716. });
  717. return;
  718. }
  719. if (!fromDate || !toDate) {
  720. Swal.fire({
  721. icon: 'warning',
  722. title: 'Missing Dates',
  723. text: 'Please select valid From and To dates.',
  724. });
  725. return;
  726. }
  727. var allCheckboxes = $("#bookingTableBody input[type='checkbox']"); // Get all checkboxes
  728. var selectedCheckboxes = $("#bookingTableBody input[type='checkbox']:checked"); // Get all checked checkboxes
  729. if (allCheckboxes.length !== selectedCheckboxes.length) {
  730. Swal.fire({
  731. icon: "warning",
  732. title: "Incomplete Selection",
  733. text: "Please select all checkboxes before blocking.",
  734. });
  735. return; // Stop further execution
  736. }
  737. // Get selected checkboxes and their values and additional values
  738. var selectedBookings = Array.from(document.querySelectorAll('#bookingTableBody input[type="checkbox"]:checked'))
  739. .map(cb => ({
  740. value: cb.value,
  741. additionalValue: cb.getAttribute('data-additional-value')
  742. }));
  743. // Separate arrays for values and additional values
  744. var selectedValues = selectedBookings.map(booking => booking.value);
  745. var selectedDataHallIds = selectedBookings.map(booking => booking.additionalValue);
  746. // Collect descriptions and file attachments dynamically
  747. var descriptions = [];
  748. var documents = [];
  749. $('.description').each(function () {
  750. const desc = $(this).val().trim();
  751. if (desc) descriptions.push(desc); // Only add non-empty descriptions
  752. });
  753. $('.uploadDocument').each(function () {
  754. if (this.files && this.files[0]) {
  755. documents.push(this.files[0]); // Collect files if present
  756. }
  757. });
  758. // Validate file size (Optional)
  759. const MAX_FILE_SIZE_MB = 5;
  760. if (documents.some(file => file.size > MAX_FILE_SIZE_MB * 1024 * 1024)) {
  761. Swal.fire({
  762. icon: 'error',
  763. title: 'File Too Large',
  764. text: 'Please upload files smaller than ${MAX_FILE_SIZE_MB} MB.',
  765. });
  766. return;
  767. }
  768. // Collect selected hall IDs
  769. var hallIds = Array.from(document.querySelectorAll('#hallSelectOptions input[type="checkbox"]:checked'))
  770. .map(cb => cb.value)
  771. .filter(value => !isNaN(value))
  772. .join(',');
  773. // console.log("hallIds: " + hallIds);
  774. // Create FormData for AJAX
  775. var formData = new FormData();
  776. formData.append('fromDate', fromDate);
  777. formData.append('toDate', toDate);
  778. formData.append('hallID', hallIds);
  779. formData.append('reasonforblocking', reasonForBlocking);
  780. formData.append('selectedBookings', selectedValues.join(",")); // Add selected values as comma-separated
  781. // Append descriptions and documents to FormData
  782. descriptions.forEach(desc => formData.append('description', desc));
  783. documents.forEach(doc => formData.append('document', doc));
  784. // Log formData for debugging (Optional)
  785. for (let [key, value] of formData.entries()) {
  786. //console.log(${key}: ${value});
  787. }
  788. // Show SweetAlert loading popup
  789. const loadingSwal = Swal.fire({
  790. title: 'Processing...',
  791. text: 'Please wait while we process your request.',
  792. allowOutsideClick: false,
  793. didOpen: () => {
  794. Swal.showLoading(); // Show loading spinner
  795. },
  796. });
  797. // AJAX request
  798. $.ajax({
  799. url: '/communityhall/admin/api/cancelAll',
  800. type: 'POST',
  801. data: formData,
  802. processData: false, // Prevent jQuery from processing FormData
  803. contentType: false, // Allow FormData to set its own content type
  804. success: function (response) {
  805. loadingSwal.close();
  806. Swal.fire({
  807. icon: 'success',
  808. title: 'Success',
  809. text: 'You have successfully blocked.',
  810. }).then(() => {
  811. location.reload(); // Reload page after success
  812. });
  813. },
  814. error: function (xhr, status, error) {
  815. console.error("Cancel All Error:", xhr.responseText);
  816. loadingSwal.close();
  817. Swal.fire({
  818. icon: 'error',
  819. title: 'Error',
  820. text: 'Something went wrong. Please try again later.',
  821. });
  822. }
  823. });
  824. // Reset checkboxes and update UI
  825. resetBookingCheckboxes();
  826. updateHallDisplay();
  827. });
  828. // Function to reset booking checkboxes
  829. function resetBookingCheckboxes() {
  830. $("#bookingTableBody input[type='checkbox']").prop('checked', false);
  831. }
  832. // Function to update hall checkboxes based on selected bookings
  833. function updateHallCheckboxes() {
  834. // Get selected bookings' hall IDs
  835. var selectedHallIds = Array.from(document.querySelectorAll('#bookingTableBody input[type="checkbox"]:checked'))
  836. .map(cb => cb.getAttribute('data-additional-value'));
  837. // Update hall checkboxes
  838. document.querySelectorAll('#hallSelectOptions input[type="checkbox"]').forEach(cb => {
  839. const hallId = cb.value;
  840. if (selectedHallIds.includes(hallId)) {
  841. cb.style.display = ''; // Show checkboxes for selected hall IDs
  842. cb.checked = true; // Keep hall IDs in selectedHallIds checked
  843. } else {
  844. cb.style.display = ''; // Ensure that the checkbox remains visible
  845. cb.checked = false; // Uncheck hall IDs not in selectedHallIds
  846. }
  847. });
  848. updateSelectOptions(selectedHallIds);
  849. }
  850. function updateSelectOptions(selectedHallIds) {
  851. var selectElement = document.querySelector('#hallSelectLabel select');
  852. var selectedIdsSet = new Set(selectedHallIds);
  853. // Remove options that are no longer selected
  854. Array.from(selectElement.options).forEach(option => {
  855. if (!selectedIdsSet.has(option.value)) {
  856. selectElement.remove(option.index);
  857. }
  858. });
  859. // Add new options for IDs that are selected but not yet in the dropdown
  860. selectedIdsSet.forEach(id => {
  861. // Check if an option with this ID already exists
  862. if (![...selectElement.options].some(option => option.value === id)) {
  863. var newOption = document.createElement('option');
  864. newOption.value = id;
  865. newOption.textContent = `${id}`; // Ensure text is set correctly
  866. selectElement.appendChild(newOption);
  867. }
  868. });
  869. // Update the text content of the select box to show selected IDs
  870. var selectBoxText = Array.from(selectedIdsSet).map(id => `${id}`).join(', ');
  871. var firstOption = selectElement.options[0];
  872. if (firstOption) {
  873. firstOption.textContent = selectBoxText || 'Select Halls';
  874. } else {
  875. // Handle the case where no options are left
  876. var newOption = document.createElement('option');
  877. newOption.value = '';
  878. newOption.textContent = selectBoxText || 'Select Halls';
  879. selectElement.appendChild(newOption);
  880. }
  881. // Log the current state of options for debugging
  882. //console.log("Current dropdown options:");
  883. Array.from(selectElement.options).forEach(option => {
  884. //console.log(Value: ${option.value}, Text: ${option.textContent});
  885. });
  886. }
  887. // Ensure this function is called whenever the checkboxes are changed
  888. $(".bookingCheckbox").change(function () {
  889. // Collect selected hall IDs
  890. var selectedHallIds = Array.from(document.querySelectorAll('#hallSelectOptions input[type="checkbox"]:checked'))
  891. .map(cb => cb.value);
  892. updateSelectOptions(selectedHallIds);
  893. });
  894. // Function to update the display of selected hall IDs
  895. function updateHallDisplay() {
  896. var checkedHallIds = Array.from(document.querySelectorAll('#hallSelectOptions input[type="checkbox"]:checked'))
  897. .map(cb => cb.value);
  898. //console.log("Selected Hall IDs:", checkedHallIds.join(', '));
  899. // Optional: Update a UI element with the selected hall IDs
  900. // For example, set the text of a span element:
  901. // $("#selectedHallIdsDisplay").text(checkedHallIds.join(', '));
  902. }
  903. });
  904. function getBlockedevents() {
  905. var selectedZones = Array.from(document.querySelectorAll('#zoneSelectOptions input[type="checkbox"]:checked'))
  906. .map(cb => cb.value);
  907. var selectedHalls = Array.from(document.querySelectorAll('#hallSelectOptions input[type="checkbox"]:checked'))
  908. .map(cb => cb.value)
  909. .filter(value => !isNaN(value)); // Filter out non-numeric values
  910. var fromDate = $("#fromDate").val();
  911. var toDate = $("#toDate").val();
  912. var reasonforBlocking = $("#reasonforBlocking").val();
  913. // Validate all mandatory fields
  914. if (!selectedZones || selectedZones.length === 0) {
  915. Swal.fire('Error!', 'Please select at least one Zone.', 'error');
  916. return;
  917. }
  918. if (!selectedHalls || selectedHalls.length === 0) {
  919. Swal.fire('Error!', 'Please select at least one Hall.', 'error');
  920. return;
  921. }
  922. if (!fromDate) {
  923. Swal.fire('Error!', 'From Date is required.', 'error');
  924. return;
  925. }
  926. if (!toDate) {
  927. Swal.fire('Error!', 'To Date is required.', 'error');
  928. return;
  929. }
  930. if (!reasonforBlocking || !reasonforBlocking.trim()) {
  931. Swal.fire('Error!', 'Reason For Blocking is required.', 'error');
  932. return;
  933. }
  934. $.ajax({
  935. url: '/communityhall/admin/api/blockedevents',
  936. type: 'GET',
  937. data: {
  938. hallIds: selectedHalls.join(','), // Pass selected hall IDs as comma-separated values
  939. fromDate: fromDate,
  940. toDate: toDate,
  941. reasonforBlocking: reasonforBlocking,
  942. },
  943. success: function (response) {
  944. },
  945. error: function (xhr, status, error) {
  946. console.error(xhr.responseText); // Log the error for debugging
  947. // Handle error
  948. }
  949. });
  950. }
  951. function cancelBlockedevent(element) {
  952. var blockingId = element.getAttribute('data-blocking-id');
  953. var fromDate = element.getAttribute('data-from-date');
  954. var endDate = element.getAttribute('data-end-date');
  955. Swal.fire({
  956. title: 'Are you sure?',
  957. text: 'Do you want to unblock this item?',
  958. icon: 'warning',
  959. showCancelButton: true,
  960. confirmButtonText: 'Yes, unblock it!',
  961. cancelButtonText: 'No, keep it blocked'
  962. }).then((result) => {
  963. if (result.isConfirmed) {
  964. $.ajax({
  965. url: '/communityhall/admin/api/cancelByid',
  966. type: 'GET',
  967. data: {
  968. blockingId: blockingId,
  969. fromDate: fromDate,
  970. endDate: endDate
  971. },
  972. success: function (response) {
  973. // console.log("Unblock response:", response);
  974. $("#viewdetails").modal('hide');
  975. window.location.reload();
  976. $("#viewdetails").modal('hide');
  977. },
  978. error: function (xhr, status, error) {
  979. console.error("Error unblocking:", xhr.responseText); // Log the error for debugging
  980. // Handle error
  981. }
  982. });
  983. }
  984. });
  985. }
  986. // function unblockSpecificBlockedevent(blockingId, bookingId, fromDate, hallId) {
  987. // Swal.fire({
  988. // title: 'Are you sure?',
  989. // text: 'Do you want to unblock this item?',
  990. // icon: 'warning',
  991. // showCancelButton: true,
  992. // confirmButtonText: 'Yes, unblock it!',
  993. // cancelButtonText: 'No, keep it blocked'
  994. // }).then((result) => {
  995. // if (result.isConfirmed) {
  996. // $.ajax({
  997. // url: '/communityhall/admin/api/cancelByid',
  998. // type: 'GET',
  999. // data: {
  1000. // blockingId: blockingId,
  1001. // bookingId: bookingId,
  1002. // fromDate: fromDate,
  1003. // hallId: hallId
  1004. // },
  1005. // success: function (response) {
  1006. // $("#viewdetails").modal('hide');
  1007. // window.location.reload();
  1008. // },
  1009. // error: function (xhr, status, error) {
  1010. // console.error("Error unblocking:", xhr.responseText); // Log the error for debugging
  1011. // // Handle error
  1012. // }
  1013. // });
  1014. // }
  1015. // });
  1016. // }
  1017. function formatDate(date) {
  1018. var d = new Date(date),
  1019. month = '' + (d.getMonth() + 1),
  1020. day = '' + d.getDate(),
  1021. year = d.getFullYear();
  1022. if (month.length < 2) month = '0' + month;
  1023. if (day.length < 2) day = '0' + day;
  1024. return [year, month, day].join('-');
  1025. }
  1026. document.addEventListener("DOMContentLoaded", function () {
  1027. var today = new Date();
  1028. var yyyy = today.getFullYear();
  1029. var mm = String(today.getMonth() + 1).padStart(2, '0');
  1030. var dd = String(today.getDate()).padStart(2, '0');
  1031. var formattedToday = yyyy + '-' + mm + '-' + dd;
  1032. // Set min attribute to today for both date inputs
  1033. document.getElementById("fromDate").setAttribute("min", formattedToday);
  1034. document.getElementById("toDate").setAttribute("min", formattedToday);
  1035. });
  1036. // Function to show/hide checkboxes
  1037. // Function to show/hide checkboxes
  1038. function toggleCheckboxArea(id, onlyHide = false) {
  1039. var checkboxes = document.getElementById(id);
  1040. var displayValue = checkboxes.style.display;
  1041. if (displayValue !== "block") {
  1042. if (onlyHide === false) {
  1043. checkboxes.style.display = "block";
  1044. }
  1045. } else {
  1046. checkboxes.style.display = "none";
  1047. }
  1048. }
  1049. // Function to initialize the zones
  1050. function getZone() {
  1051. $.ajax({
  1052. type: "GET",
  1053. url: '/communityhall/user/api/getZone',
  1054. success: function (data) {
  1055. const uniqueZones = [...new Set(data.map(item => item.zone))];
  1056. const zoneMenu = document.getElementById('zoneSelectOptions');
  1057. zoneMenu.innerHTML = ''; // Clear existing options
  1058. // Add "All Zones" checkbox
  1059. const allZonesCheckbox = document.createElement('input');
  1060. allZonesCheckbox.type = 'checkbox';
  1061. allZonesCheckbox.value = 'All Zones';
  1062. allZonesCheckbox.name = 'zone';
  1063. allZonesCheckbox.addEventListener('change', function () {
  1064. toggleAllZones(this.checked);
  1065. });
  1066. const allZonesLabel = document.createElement('label');
  1067. allZonesLabel.htmlFor = 'allZonesCheckbox';
  1068. allZonesLabel.textContent = 'All Zones';
  1069. allZonesLabel.prepend(allZonesCheckbox);
  1070. zoneMenu.appendChild(allZonesLabel);
  1071. uniqueZones.forEach(zone => {
  1072. const label = document.createElement('label');
  1073. const checkbox = document.createElement('input');
  1074. checkbox.type = 'checkbox';
  1075. checkbox.value = zone;
  1076. checkbox.id = zone;
  1077. checkbox.name = 'zone';
  1078. label.htmlFor = zone;
  1079. label.textContent = zone;
  1080. label.prepend(checkbox);
  1081. zoneMenu.appendChild(label);
  1082. // Bind change event
  1083. checkbox.addEventListener('change', function () {
  1084. loadHallsbyzone();
  1085. checkboxStatusChange('zoneSelectOptions', 'zoneSelectLabel');
  1086. });
  1087. });
  1088. },
  1089. error: function (xhr, status, error) {
  1090. console.error('Error loading zones:', error);
  1091. }
  1092. });
  1093. }
  1094. // Function to toggle all zones checkboxes
  1095. function toggleAllZones(checked) {
  1096. const zoneCheckboxes = document.querySelectorAll('#zoneSelectOptions input[type="checkbox"]');
  1097. zoneCheckboxes.forEach(checkbox => {
  1098. checkbox.checked = checked;
  1099. });
  1100. loadHallsbyzone();
  1101. checkboxStatusChange('zoneSelectOptions', 'zoneSelectLabel');
  1102. }
  1103. function addHallCheckbox(hallMenu, hall) {
  1104. const label = document.createElement('label');
  1105. const checkbox = document.createElement('input');
  1106. checkbox.type = 'checkbox';
  1107. checkbox.value = hall.hallId;
  1108. checkbox.id = hall.hallName;
  1109. checkbox.name = 'hall';
  1110. label.htmlFor = hall.hallId;
  1111. // Remove leading comma if present
  1112. const hallName = hall.hallName.trim(); // Remove leading and trailing whitespace
  1113. label.textContent = hallName.replace(/^, */, ''); // Remove leading comma and spaces, if any
  1114. label.prepend(checkbox);
  1115. hallMenu.appendChild(label);
  1116. // Bind change event
  1117. checkbox.addEventListener('change', function () {
  1118. checkboxStatusChange('hallSelectOptions', 'hallSelectLabel');
  1119. });
  1120. }
  1121. // Function to load halls based on selected zones
  1122. function loadHallsbyzone() {
  1123. const selectedZones = Array.from(document.querySelectorAll('#zoneSelectOptions input[type="checkbox"]:checked')).map(cb => cb.value);
  1124. if (selectedZones.length === 0) {
  1125. document.getElementById('hallSelectOptions').innerHTML = '';
  1126. return;
  1127. }
  1128. $.ajax({
  1129. url: '/communityhall/user/api/hallsbyzone',
  1130. method: 'GET',
  1131. data: { zones: selectedZones.join(',') }, // Pass selected zones to the backend
  1132. success: function (response) {
  1133. const hallMenu = document.getElementById('hallSelectOptions');
  1134. hallMenu.innerHTML = ''; // Clear existing options
  1135. // Add "All Halls" checkbox
  1136. const allHallsCheckbox = document.createElement('input');
  1137. allHallsCheckbox.type = 'checkbox';
  1138. allHallsCheckbox.addEventListener('change', function () {
  1139. toggleAllHalls(this.checked);
  1140. });
  1141. const allHallsLabel = document.createElement('label');
  1142. allHallsLabel.htmlFor = 'allHallsCheckbox';
  1143. allHallsLabel.textContent = 'All Halls';
  1144. allHallsLabel.prepend(allHallsCheckbox);
  1145. hallMenu.appendChild(allHallsLabel);
  1146. // Add individual hall checkboxes
  1147. response.forEach(function (hall) {
  1148. addHallCheckbox(hallMenu, hall);
  1149. });
  1150. },
  1151. error: function (xhr, status, error) {
  1152. console.error('Error loading halls:', error);
  1153. }
  1154. });
  1155. }
  1156. // Function to toggle all halls checkboxes
  1157. function toggleAllHalls(checked) {
  1158. const hallCheckboxes = document.querySelectorAll('#hallSelectOptions input[type="checkbox"]');
  1159. hallCheckboxes.forEach(checkbox => {
  1160. checkbox.checked = checked;
  1161. });
  1162. checkboxStatusChange('hallSelectOptions', 'hallSelectLabel');
  1163. }
  1164. function checkboxStatusChange(optionsId, labelId) {
  1165. var multiselect = document.getElementById(labelId);
  1166. var multiselectOption = multiselect.getElementsByTagName('option')[0];
  1167. var values = [];
  1168. var checkboxes = document.getElementById(optionsId);
  1169. var checkedCheckboxes = checkboxes.querySelectorAll('input[type=checkbox]:checked');
  1170. // Check if all zones are selected
  1171. var allZonesCheckbox = document.getElementById('allZonesCheckbox');
  1172. var zoneCheckboxes = document.querySelectorAll('#zoneSelectOptions input[type="checkbox"]');
  1173. var allZonesChecked = Array.from(zoneCheckboxes).every(checkbox => checkbox.checked);
  1174. for (const item of checkedCheckboxes) {
  1175. var checkboxValue = item.getAttribute('id');
  1176. if (allZonesChecked && checkboxValue === 'All Zones') {
  1177. // Skip the "All Zones" label if all zones are selected
  1178. continue;
  1179. }
  1180. values.push(checkboxValue);
  1181. }
  1182. var dropdownValue = "Nothing is selected";
  1183. if (values.length > 0) {
  1184. dropdownValue = values.join(', ').replace(/^, */, ''); // Remove leading comma and spaces if any
  1185. }
  1186. multiselectOption.innerText = dropdownValue;
  1187. }
  1188. window.onload = function () {
  1189. document.addEventListener("click", function (evt) {
  1190. var zoneFlyoutElement = document.getElementById('zoneMultiselect'),
  1191. hallFlyoutElement = document.getElementById('hallMultiselect'),
  1192. targetElement = evt.target; // clicked element
  1193. do {
  1194. if (targetElement == zoneFlyoutElement || targetElement == hallFlyoutElement) {
  1195. return; // Click inside
  1196. }
  1197. targetElement = targetElement.parentNode;
  1198. } while (targetElement);
  1199. // Click outside
  1200. toggleCheckboxArea('zoneSelectOptions', true);
  1201. toggleCheckboxArea('hallSelectOptions', true);
  1202. });
  1203. };
  1204. document.addEventListener('DOMContentLoaded', function () {
  1205. function clearModalFields() {
  1206. // Clear text inputs
  1207. document.querySelectorAll('#viewdetails input[type="text"], #viewdetails input[type="date"]').forEach(input => {
  1208. input.value = '';
  1209. });
  1210. // Reset select elements
  1211. document.querySelectorAll('#viewdetails select').forEach(select => {
  1212. select.selectedIndex = 0; // Reset to default option
  1213. });
  1214. // Uncheck checkboxes and clear their container
  1215. document.querySelectorAll('#viewdetails .checkboxes input[type="checkbox"]').forEach(checkbox => {
  1216. checkbox.checked = false;
  1217. });
  1218. document.querySelectorAll('#viewdetails .checkboxes').forEach(container => {
  1219. container.innerHTML = ''; // Clear all checkboxes from the container
  1220. });
  1221. // Add default options for zones and halls
  1222. document.querySelector('#zoneMultiselect select').innerHTML = '<option>Select Zones</option>';
  1223. document.querySelector('#hallMultiselect select').innerHTML = '<option>Select Halls</option>';
  1224. // Optionally, hide content area if needed
  1225. document.getElementById('bookinglistdataTable').style.display = 'none';
  1226. }
  1227. // Event listener for when the modal is hidden
  1228. document.getElementById('viewdetails').addEventListener('hidden.bs.modal', clearModalFields);
  1229. });
  1230. function formatDate(date) {
  1231. let d = new Date(date),
  1232. month = '' + (d.getMonth() + 1),
  1233. day = '' + d.getDate(),
  1234. year = d.getFullYear();
  1235. if (month.length < 2) month = '0' + month;
  1236. if (day.length < 2) day = '0' + day;
  1237. return [year, month, day].join('-');
  1238. }
  1239. // Get today's date
  1240. let today = new Date();
  1241. let todayFormatted = formatDate(today);
  1242. // Set the minimum date for fromDate input to today
  1243. let fromDateInput = document.getElementById('fromDate');
  1244. fromDateInput.setAttribute('min', todayFormatted);
  1245. // Add event listener to fromDate to update toDate min value and reset its value
  1246. fromDateInput.addEventListener('change', function () {
  1247. let selectedFromDate = this.value;
  1248. let toDateInput = document.getElementById('toDate');
  1249. toDateInput.setAttribute('min', selectedFromDate);
  1250. toDateInput.value = ''; // Reset the value of toDate
  1251. });
  1252. </script>
  1253. </body>
  1254. </html>