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.

566 lines
18 KiB

​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
  1. <!DOCTYPE html>
  2. <html lang="en" xmlns:th="http://www.thymeleaf.org">
  3. <head th:replace="~{fragments/modules/base/head :: head}">
  4. <style>
  5. body {
  6. background-color: #f8f9fa;
  7. }
  8. .header {
  9. font-size: 22px;
  10. font-weight: bold;
  11. margin-bottom: 20px;
  12. }
  13. .table {
  14. border: 1px solid #dee2e6;
  15. }
  16. .table th,
  17. .table td {
  18. border: 1px solid #dee2e6;
  19. padding: 10px;
  20. }
  21. .section-title {
  22. font-size: 18px;
  23. font-weight: bold;
  24. margin-top: 20px;
  25. border-bottom: 2px solid #007bff;
  26. padding-bottom: 5px;
  27. }
  28. .form-group {
  29. margin-top: 15px;
  30. }
  31. .radio-group {
  32. display: flex;
  33. gap: 20px;
  34. margin-top: 10px;
  35. }
  36. .card1 {
  37. padding: 0px;
  38. margin-top: -58px;
  39. margin-left: -230px;
  40. }
  41. /* ✅ Responsive Fix for Mobile Screens */
  42. @media (max-width: 768px) {
  43. .card1 {
  44. margin-top: 0 !important;
  45. padding: 15px;
  46. }
  47. .container {
  48. padding-left: 10px;
  49. padding-right: 10px;
  50. }
  51. }
  52. @media (max-width: 768px) {
  53. #toiletDataContainer table {
  54. display: block;
  55. overflow-x: auto;
  56. white-space: nowrap;
  57. }
  58. } </style>
  59. </head>
  60. <body>
  61. <div class="container mt-4">
  62. <header th:replace="~{fragments/modules/base/header :: header}"></header>
  63. <div th:replace="~{fragments/modules/base/menu :: menu}"></div>
  64. <div class="card p-3">
  65. <div class="card-header">
  66. <b>Toilets</b>
  67. </div>
  68. <br>
  69. <!-- View Table -->
  70. <div id="toiletDataContainer" style="display: none;">
  71. <table class="table table-bordered">
  72. <tr>
  73. <th>No of Toilet Blocks</th>
  74. <td id="td_blocks"></td>
  75. <th>Male Toilets (Urinals)</th>
  76. <td id="td_urinals"></td>
  77. </tr>
  78. <tr>
  79. <th>Male Toilets (W.C)</th>
  80. <td id="td_wc_male"></td>
  81. <th>Female Toilets (W.C)</th>
  82. <td id="td_wc_female"></td>
  83. </tr>
  84. <tr>
  85. <th>Differently Abled Toilets</th>
  86. <td id="td_disabled"></td>
  87. <th>Incinerator for Napkin Disposal</th>
  88. <td id="td_napkins"></td>
  89. </tr>
  90. </table>
  91. <div class="text-center">
  92. <button class="btn btn-primary" id="editToiletBtn">Update</button>
  93. </div>
  94. </div>
  95. <form id="toiletForm" novalidate>
  96. <input type="hidden" name="school_id">
  97. <input type="hidden" id="toilet_id" name="toilet_id" />
  98. <div class="row p-3">
  99. <div class="col-md-6 form-group">
  100. <label>No of Toilet Blocks *</label>
  101. <input type="text" class="form-control" name="total_toiletBlocks"
  102. id="total_toiletBlocks" required>
  103. </div>
  104. <div class="col-md-6 form-group">
  105. <label>Total Male Toilets (Urinals) *</label>
  106. <input type="text" class="form-control" name="total_male_urinals"
  107. id="total_male_urinals" required>
  108. </div>
  109. </div>
  110. <div class="row p-3">
  111. <div class="col-md-6 form-group">
  112. <label>Total Male Toilets (W.C) *</label>
  113. <input type="text" class="form-control" name="total_wc_male"
  114. id="total_wc_male" required>
  115. </div>
  116. <div class="col-md-6 form-group">
  117. <label>Total Female Toilets (W.C) *</label>
  118. <input type="text" class="form-control" name="total_wc_female"
  119. id="total_wc_female" required>
  120. </div>
  121. <div class="col-md-6 form-group">
  122. <label>Incinerator for Napkins Disposal *</label>
  123. <div class="radio-group">
  124. <input type="radio" name="is_napkins" value="true"> Yes
  125. <input type="radio" name="is_napkins" value="false"> No
  126. </div>
  127. </div>
  128. <div class="col-md-6 form-group">
  129. <label>Differently Abled Toilets *</label>
  130. <input type="text" class="form-control" name="total_diffAbled_toilet"
  131. id="total_diffAbled_toilet" required>
  132. </div>
  133. </div>
  134. <div class="card-footer text-center">
  135. <button type="submit" class="btn btn-primary"><i class="ik ik-save"></i>
  136. Submit</button>
  137. <button type="reset" class="btn btn-secondary"><i class="ik ik-refresh-cw"></i>
  138. Reset</button>
  139. </div>
  140. </form>
  141. </div>
  142. </div>
  143. <!-- Modal -->
  144. <div class="modal fade" id="toiletModal" tabindex="-1" aria-labelledby="toiletModalLabel" aria-hidden="true">
  145. <div class="modal-dialog">
  146. <div class="modal-content">
  147. <form id="toiletUpdateForm">
  148. <div class="modal-header">
  149. <h5 class="modal-title">Update Toilet Details</h5>
  150. <button type="button" class="close" data-bs-dismiss="modal"
  151. aria-label="Close"><span aria-hidden="true">&times;</span></button>
  152. </div>
  153. <div class="modal-body">
  154. <input type="hidden" id="modal_toilet_id" />
  155. <input type="hidden" id="modal_school_id" />
  156. <div class="mb-2"><label>No of Toilet Blocks *</label><input type="number" id="modal_blocks"
  157. class="form-control" required /></div>
  158. <div class="mb-2"><label>Male Toilets (Urinals) *</label><input type="number"
  159. id="modal_urinals" class="form-control" required /></div>
  160. <div class="mb-2"><label>Male Toilets (W.C) *</label><input type="number" id="modal_wc_male"
  161. class="form-control" required /></div>
  162. <div class="mb-2"><label>Female Toilets (W.C) *</label><input type="number"
  163. id="modal_wc_female" class="form-control" required /></div>
  164. <div class="mb-2"><label>Differently Abled Toilets *</label><input type="number"
  165. id="modal_disabled" class="form-control" required /></div>
  166. <div class="mb-2">
  167. <label>Incinerator for Napkin Disposal *</label><br>
  168. <input type="radio" name="modal_napkins" value="true" /> Yes
  169. <input type="radio" name="modal_napkins" value="false" /> No
  170. </div>
  171. </div>
  172. <div class="modal-footer">
  173. <button type="submit" class="btn btn-success">Save Changes</button>
  174. </div>
  175. </form>
  176. </div>
  177. </div>
  178. </div>
  179. <!-- Scripts -->
  180. <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js"></script>
  181. <script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
  182. <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
  183. <script th:replace="~{fragments/modules/base/script :: script}"></script>
  184. <script>
  185. $(document).ready(function () {
  186. const schoolId = new URLSearchParams(window.location.search).get("schoolId");
  187. $('input[name="school_id"]').val(schoolId);
  188. $('#modal_school_id').val(schoolId);
  189. /*$('#total_toiletBlocks').on('input', function () {
  190. const value = parseInt($(this).val()) || 0;
  191. if (value === 0) {
  192. $('#total_male_urinals').val(0);
  193. $('#total_wc_male').val(0);
  194. $('#total_wc_female').val(0);
  195. $('#total_diffAbled_toilet').val(0);
  196. }
  197. else{
  198. $('#total_male_urinals').val('');
  199. $('#total_wc_male').val('');
  200. $('#total_wc_female').val('');
  201. $('#total_diffAbled_toilet').val('');
  202. }
  203. });*/
  204. /* $('#modal_blocks').on('input', function () {
  205. const value = parseInt($(this).val()) || 0;
  206. if (value === 0) {
  207. $('#modal_urinals').val(0);
  208. $('#modal_wc_male').val(0);
  209. $('#modal_wc_female').val(0);
  210. $('#modal_disabled').val(0);
  211. }
  212. else{
  213. $('#modal_urinals').val('');
  214. $('#modal_wc_male').val('');
  215. $('#modal_wc_female').val('');
  216. $('#modal_disabled').val('');
  217. }
  218. });*/
  219. // ✅ Enforce only numeric input
  220. ['total_toiletBlocks', 'total_male_urinals', 'total_wc_male', 'total_wc_female', 'total_diffAbled_toilet']
  221. .forEach(id => {
  222. document.getElementById(id).addEventListener('input', function () {
  223. this.value = this.value.replace(/[^0-9]/g, '');
  224. if (parseInt(this.value) < 0) this.value = '';
  225. });
  226. });
  227. ['modal_blocks', 'modal_urinals', 'modal_wc_male', 'modal_wc_female', 'modal_disabled']
  228. .forEach(id => {
  229. document.getElementById(id).addEventListener('input', function () {
  230. this.value = this.value.replace(/[^0-9]/g, '');
  231. if (parseInt(this.value) < 0) this.value = '';
  232. });
  233. });
  234. // ✅ Function to reload table data after update
  235. function reloadToiletTable() {
  236. $.get('/gcc/api/gccschool/schoolproperty/checkToiletDetails', { school_id: schoolId }, function (res) {
  237. if (res && res[0]?.Data?.length > 0) {
  238. const d = res[0].Data[0];
  239. // Update table with fresh values
  240. $('#td_blocks').text(d.total_toiletBlocks);
  241. $('#td_urinals').text(d.total_male_urinals);
  242. $('#td_wc_male').text(d.total_wc_male);
  243. $('#td_wc_female').text(d.total_wc_female);
  244. $('#td_disabled').text(d.total_diffAbled_toilet);
  245. $('#td_napkins').text(d.is_napkins === true || d.is_napkins === "true" ? 'Yes' : 'No');
  246. $('#toiletDataContainer').show();
  247. $('#editToiletBtn').data('toiletData', d);
  248. }
  249. });
  250. }
  251. // ✅ Initial load
  252. $.get('/gcc/api/gccschool/schoolproperty/checkToiletDetails', { school_id: schoolId }, function (res) {
  253. if (res && res[0]?.Data?.length > 0) {
  254. const d = res[0].Data[0];
  255. $('#toilet_id').val(d.toilet_id);
  256. $('#toiletForm').hide();
  257. $('#toiletDataContainer').show();
  258. $('#td_blocks').text(d.total_toiletBlocks);
  259. $('#td_urinals').text(d.total_male_urinals);
  260. $('#td_wc_male').text(d.total_wc_male);
  261. $('#td_wc_female').text(d.total_wc_female);
  262. $('#td_disabled').text(d.total_diffAbled_toilet);
  263. $('#td_napkins').text(d.is_napkins === true ? 'Yes' : 'No');
  264. $('#editToiletBtn').data('toiletData', d);
  265. } else {
  266. $('#toiletForm').show();
  267. $('#toiletDataContainer').hide();
  268. }
  269. });
  270. // ✅ Save new toilet form (first time entry)
  271. $('#toiletForm').submit(function (e) {
  272. e.preventDefault();
  273. const blocks = parseInt($('#total_toiletBlocks').val()) || 0;
  274. const urinals = parseInt($('#total_male_urinals').val()) || 0;
  275. const wc_male = parseInt($('#total_wc_male').val()) || 0;
  276. const wc_female = parseInt($('#total_wc_female').val()) || 0;
  277. const diff_abled = parseInt($('#total_diffAbled_toilet').val()) || 0;
  278. const isNapkins = $('input[name="is_napkins"]:checked').val();
  279. /* if (blocks === 0) {
  280. $('#total_male_urinals').val(0);
  281. $('#total_wc_male').val(0);
  282. $('#total_wc_female').val(0);
  283. $('#total_diffAbled_toilet').val(0);
  284. }*/
  285. if ($('#total_toiletBlocks').val().trim() === '') {
  286. return Swal.fire({
  287. icon: 'warning',
  288. title: 'Validation Error',
  289. text: 'Enter Total Toilet Blocks ',
  290. allowOutsideClick: false,
  291. allowEscapeKey: false,
  292. allowEnterKey: false,
  293. showConfirmButton: true
  294. });
  295. }
  296. if ($('#total_male_urinals').val().trim() === '') {
  297. return Swal.fire({
  298. icon: 'warning',
  299. title: 'Validation Error',
  300. text: 'Enter number of Male Urinals (0 or more).',
  301. allowOutsideClick: false,
  302. allowEscapeKey: false,
  303. allowEnterKey: false,
  304. showConfirmButton: true
  305. });
  306. }
  307. if ($('#total_wc_male').val().trim() === '') {
  308. return Swal.fire({
  309. icon: 'warning',
  310. title: 'Validation Error',
  311. text: 'Enter number of Male WC (0 or more).',
  312. allowOutsideClick: false,
  313. allowEscapeKey: false,
  314. allowEnterKey: false,
  315. showConfirmButton: true
  316. });
  317. }
  318. if ($('#total_wc_female').val().trim() === '') {
  319. return Swal.fire({
  320. icon: 'warning',
  321. title: 'Validation Error',
  322. text: 'Enter number of Female WC (0 or more).',
  323. allowOutsideClick: false,
  324. allowEscapeKey: false,
  325. allowEnterKey: false,
  326. showConfirmButton: true
  327. });
  328. }
  329. if (typeof isNapkins === 'undefined') {
  330. return Swal.fire({
  331. icon: 'warning',
  332. title: 'Validation Error',
  333. text: 'Please select whether there is an Incinerator for Napkins Disposal.',
  334. allowOutsideClick: false,
  335. allowEscapeKey: false,
  336. allowEnterKey: false,
  337. showConfirmButton: true
  338. });
  339. }
  340. if ($('#total_diffAbled_toilet').val().trim() === '') {
  341. return Swal.fire({
  342. icon: 'warning',
  343. title: 'Validation Error',
  344. text: 'Enter number of Differently Abled Toilets (0 or more).',
  345. allowOutsideClick: false,
  346. allowEscapeKey: false,
  347. allowEnterKey: false,
  348. showConfirmButton: true
  349. });
  350. }
  351. // Total toilets entered
  352. /* const totalToilets = urinals + wc_male + wc_female + diff_abled;
  353. if (blocks !== totalToilets) {
  354. Swal.fire({
  355. icon: 'warning',
  356. title: 'Mismatch Detected',
  357. text: `The number of toilet blocks (${blocks}) must match the total toilets (${totalToilets}) entered.`,
  358. allowOutsideClick: false,
  359. allowEscapeKey: false,
  360. allowEnterKey: false,
  361. showConfirmButton: true
  362. });
  363. return;
  364. }*/
  365. const formData = new FormData(this);
  366. $.ajax({
  367. type: 'POST',
  368. url: '/gcc/api/gccschool/schoolproperty/saveToilets',
  369. data: formData,
  370. processData: false,
  371. contentType: false,
  372. success: res => {
  373. // Swal.fire('Saved', res, 'success').then(() => {
  374. Swal.fire({
  375. title: 'Saved',
  376. text: res,
  377. icon: 'success',
  378. allowOutsideClick: false,
  379. allowEscapeKey: false,
  380. allowEnterKey: false,
  381. showConfirmButton: true
  382. }).then(() => {
  383. location.reload();
  384. // $('#toiletForm').hide();
  385. // reloadToiletTable(); // refresh table
  386. });
  387. },
  388. error: xhr =>Swal.fire({
  389. title: 'Error',
  390. text: xhr.responseText || 'Unknown error',
  391. icon: 'error',
  392. allowOutsideClick: false,
  393. allowEscapeKey: false,
  394. allowEnterKey: false,
  395. showConfirmButton: true
  396. })
  397. //Swal.fire('Error', xhr.responseText || 'Unknown error', 'error')
  398. });
  399. });
  400. let originalModalData = {};
  401. $('#editToiletBtn').click(function () {
  402. const d = $(this).data("toiletData");
  403. $('#modal_toilet_id').val(d.toilet_id);
  404. $('#modal_blocks').val(d.total_toiletBlocks);
  405. $('#modal_urinals').val(d.total_male_urinals);
  406. $('#modal_wc_male').val(d.total_wc_male);
  407. $('#modal_wc_female').val(d.total_wc_female);
  408. $('#modal_disabled').val(d.total_diffAbled_toilet);
  409. $(`input[name="modal_napkins"][value="${d.is_napkins}"]`).prop('checked', true);
  410. // ✅ Store original values
  411. originalModalData = {
  412. total_toiletBlocks: d.total_toiletBlocks.toString(),
  413. total_male_urinals: d.total_male_urinals.toString(),
  414. total_wc_male: d.total_wc_male.toString(),
  415. total_wc_female: d.total_wc_female.toString(),
  416. total_diffAbled_toilet: d.total_diffAbled_toilet.toString(),
  417. is_napkins: d.is_napkins.toString()
  418. };
  419. const modal = new bootstrap.Modal(document.getElementById('toiletModal'));
  420. modal.show();
  421. });
  422. $('#toiletUpdateForm').submit(function (e) {
  423. e.preventDefault();
  424. const updateBlocks = parseInt($('#modal_blocks').val()) || 0;
  425. const updateUrinals = parseInt($('#modal_urinals').val()) || 0;
  426. const updateWCMale = parseInt($('#modal_wc_male').val()) || 0;
  427. const updateWCFemale = parseInt($('#modal_wc_female').val()) || 0;
  428. const updateDisabled = parseInt($('#modal_disabled').val()) || 0;
  429. /* if (!updateBlocks ) {
  430. return Swal.fire({
  431. icon: 'warning',
  432. title: 'Validation Error',
  433. text: 'Enter Total Toilet Blocks greater than 0.',
  434. allowOutsideClick: false,
  435. allowEscapeKey: false,
  436. allowEnterKey: false,
  437. showConfirmButton: true
  438. });
  439. }*/
  440. /* const updateTotal = updateUrinals + updateWCMale + updateWCFemale + updateDisabled;
  441. if (updateBlocks !== updateTotal) {
  442. Swal.fire({
  443. icon: 'warning',
  444. title: 'Mismatch Detected',
  445. text: `The number of toilet blocks (${updateBlocks}) must match the total toilets (${updateTotal}) entered.`,
  446. allowOutsideClick: false,
  447. allowEscapeKey: false,
  448. allowEnterKey: false,
  449. showConfirmButton: true
  450. });
  451. return;
  452. }*/
  453. const currentData = {
  454. total_toiletBlocks: $('#modal_blocks').val(),
  455. total_male_urinals: $('#modal_urinals').val(),
  456. total_wc_male: $('#modal_wc_male').val(),
  457. total_wc_female: $('#modal_wc_female').val(),
  458. total_diffAbled_toilet: $('#modal_disabled').val(),
  459. is_napkins: $('input[name="modal_napkins"]:checked').val()
  460. };
  461. // ✅ Check if any value has changed
  462. const hasChanged = Object.keys(currentData).some(key => currentData[key] !== originalModalData[key]);
  463. /* if (!hasChanged) {
  464. Swal.fire('No Changes', 'Please make a change before submitting.', 'info');
  465. return;
  466. }*/
  467. currentData.school_id = $('#modal_school_id').val();
  468. $.post('/gcc/api/gccschool/schoolproperty/updateToiletDetails', currentData, function () {
  469. // Swal.fire('Updated', 'Toilet data updated successfully!', 'success').then(() => {
  470. Swal.fire({
  471. title: 'Updated',
  472. text: 'Toilet data updated successfully!',
  473. icon: 'success',
  474. allowOutsideClick: false,
  475. allowEscapeKey: false,
  476. allowEnterKey: false,
  477. showConfirmButton: true
  478. }).then(() => {
  479. const modalInstance = bootstrap.Modal.getInstance(document.getElementById('toiletModal'));
  480. modalInstance.hide();
  481. location.reload();
  482. });
  483. }).fail(() => {
  484. // Swal.fire('Error', 'Update failed', 'error');
  485. Swal.fire({
  486. title: 'Error',
  487. text: 'Update failed',
  488. icon: 'error',
  489. allowOutsideClick: false,
  490. allowEscapeKey: false,
  491. allowEnterKey: false,
  492. showConfirmButton: true
  493. });
  494. });
  495. });
  496. });
  497. </script>
  498. </body>
  499. </html>