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.

1080 lines
46 KiB

​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
  1. <!DOCTYPE html>
  2. <html lang="en" xmlns:th="http://www.thymeleaf.org">
  3. <head th:replace="~{fragments/modules/base/head :: head}"></head>
  4. <style>
  5. #btn_container button{
  6. width: 20%;
  7. }
  8. </style>
  9. <body>
  10. <div class="wrapper">
  11. <!-- header top menu Start -->
  12. <header th:replace="~{fragments/modules/base/header :: header}"></header>
  13. <!-- header top menu end -->
  14. <div class="page-wrap">
  15. <!--=============== Left Menu side Start ================-->
  16. <div th:replace="~{fragments/modules/base/menu :: menu}"></div>
  17. <!--=============== Left side End ================-->
  18. <div class="main-content">
  19. <div class="container-fluid">
  20. <div class="page-header mb-2">
  21. <div class="row align-items-end">
  22. <div class="col-lg-8">
  23. <div class="page-header-title">
  24. <!-- <i class="far fa-calendar-plus bg-blue"></i> -->
  25. <div class="d-inline">
  26. <h5>Polling Personnel Updation</h5>
  27. <span>Polling Personnel Update form</span>
  28. </div>
  29. </div>
  30. </div>
  31. </div>
  32. </div>
  33. <div class="container">
  34. <div class="row">
  35. <div class="card" style="padding: 10px;"><span th:text="${LoginUserId}" style="display:none;" id="userIdSpan"></span>
  36. <form id="newpollingform" enctype="multipart/form-data" >
  37. <div class=" mb-3" style="border: 1px solid grey;padding: 10px;border-radius: 5px;">
  38. <label class="form-label" for="slno">Unique No</label>
  39. <input type="text" class="form-control" id="slno" readonly>
  40. </div>
  41. <div class=" mb-3" style="border: 1px solid grey;padding: 10px;border-radius: 5px;">
  42. <div class="row" style="row-gap:10px;">
  43. <div id="existing_uniquenum" style="display: none;"></div>
  44. <div class="col-md-8 col-sm-12">
  45. <label class="form-label" for="official_name">Name of the Official<span class="text-danger">*</span></label>
  46. <input type="text" class="form-control" id="official_name" placeholder="Enter Full Name" required="required" pattern="[A-Za-z.\s]+" title="Only alphabets, spaces, and dots are allowed">
  47. </div>
  48. <div class="col-md-4 col-sm-12">
  49. <label class="form-label" for="official_age">Age</label>
  50. <input type="number" class="form-control" id="official_age" placeholder="Enter Age">
  51. </div>
  52. <div class="col-md-4 col-sm-12">
  53. <label class="form-label d-block">Sex<span class="text-danger">*</span></label>
  54. <div class="d-flex flex-wrap gap-3">
  55. <div class="form-check me-3">
  56. <input class="form-check-input" type="radio" name="gender" id="genderMale" value="M" required="required">
  57. <label class="form-check-label pr-4" for="genderMale">Male</label>
  58. </div>
  59. <div class="form-check me-3">
  60. <input class="form-check-input" type="radio" name="gender" id="genderFemale" value="F">
  61. <label class="form-check-label pr-4" for="genderFemale">Female</label>
  62. </div>
  63. <div class="form-check">
  64. <input class="form-check-input" type="radio" name="gender" id="genderTransgender" value="T">
  65. <label class="form-check-label pr-4" for="genderTransgender">Transgender</label>
  66. </div>
  67. </div>
  68. </div>
  69. <div class="col-md-4 col-sm-12" style="display: none">
  70. <label class="form-label">Designation<span class="text-danger">*</span></label>
  71. <select id="design_dropdown" class="form-control" required="required" readonly>
  72. <option value="">Select</option>
  73. </select>
  74. </div>
  75. <div class="col-md-4 col-sm-12">
  76. <label class="form-label" for="pollperson_desig">Designation</label>
  77. <input type="text" class="form-control" id="pollperson_desig" readonly>
  78. </div>
  79. <div class="col-md-4 col-sm-12">
  80. <label class="form-label">Upload Photo</label>
  81. <input type="file" class="form-control" id="profileimage" accept=".jpg,.jpeg,image/jpeg" name="profileimage">
  82. <div id="profileimage_preview" class="mt-2" style="cursor:pointer; color:blue; text-decoration:underline;display: none;"></div>
  83. </div>
  84. </div>
  85. </div>
  86. <!--<div class="card-body mb-3" style="border: 1px solid grey;padding: 10px;border-radius: 5px;">
  87. <div class="row" style="row-gap:10px;">
  88. <div class="col-md-4 col-sm-12">
  89. <label class="form-label" for="basic_pay">Basic pay</label>
  90. <input type="text" class="form-control" id="basic_pay" readonly>
  91. </div>
  92. <div class="col-md-4 col-sm-12">
  93. <label class="form-label" for="grade_pay">Grade pay</label>
  94. <input type="text" class="form-control" id="grade_pay" readonly>
  95. </div>
  96. <div class="col-md-4 col-sm-12">
  97. <label class="form-label" for="pay_band">Pay Band</label>
  98. <input type="text" class="form-control" id="pay_band" readonly>
  99. </div>
  100. </div>
  101. </div>-->
  102. <div class="card-body" style="padding: 10px;">
  103. <div class="row" style="row-gap:10px;">
  104. <div class="col-md-12 col-sm-12">
  105. <div class="card-header bg-dark text-white">
  106. <b>Residential Details</b>
  107. </div>
  108. <div class="card-body" style="border: 1px solid grey;border-top-color: white;border-bottom-left-radius: 5px;border-bottom-right-radius: 5px;">
  109. <div class="row">
  110. <div class="col-md-4">
  111. <label class="form-label" for="res_address1">House No/ House Name</label>
  112. <input type="text" class="form-control mb-3" id="res_address1">
  113. </div>
  114. <div class="col-md-4">
  115. <label class="form-label" for="res_address2">Street Name/ Area</label>
  116. <input type="text" class="form-control mb-3" id="res_address2">
  117. </div>
  118. <div class="col-md-4">
  119. <label class="form-label" for="res_address3">City</label>
  120. <input type="text" class="form-control mb-3" id="res_address3">
  121. </div>
  122. <div class="col-md-4">
  123. <label class="form-label" for="res_pincode">Pincode</label>
  124. <input type="text" class="form-control mb-3" id="res_pincode">
  125. </div>
  126. <div class="col-md-4">
  127. <label class="form-label" for="res_police">Nearest Police Station</label>
  128. <input type="text" class="form-control mb-3" id="res_police">
  129. </div>
  130. <div class="col-md-4">
  131. <label class="form-label" for="res_phoneno">Phone No</label>
  132. <div class="d-flex justify-content-start">
  133. <button class="btn btn-secondary" disabled="disabled" style="height: fit-content">STD</button>
  134. <input type="text" class="form-control mb-3 mx-2" id="res_phoneno">
  135. </div>
  136. </div>
  137. <div class="col-md-4">
  138. <label class="form-label" for="res_mobile">Mobile</label>
  139. <input type="text" class="form-control mb-3" id="res_mobile">
  140. </div>
  141. <div class="col-md-4">
  142. <div class="mb-3">
  143. <label class="form-label" for="nativetaluk_dropdown">Native Taluk/District</label>
  144. <select id="nativetaluk_dropdown" class="form-control mb-3">
  145. <option value="">Select</option>
  146. </select>
  147. </div>
  148. </div>
  149. <div class="mb-3">
  150. <label class="form-label" for="nativeassembly_dropdown">Native Assembly Constituency</label>
  151. <select id="nativeassembly_dropdown" class="form-control mb-3">
  152. <option value="">Select</option>
  153. </select>
  154. </div>
  155. <div class="col-md-4">
  156. <label class="form-label" for="residentialassembly_dropdown">Residential Assembly Constituency</label>
  157. <select id="residentialassembly_dropdown" class="form-control mb-3">
  158. <option value="">Select</option>
  159. </select>
  160. </div>
  161. </div>
  162. </div>
  163. </div>
  164. </div>
  165. </div>
  166. <div class="card-body mb-3" style="padding: 10px;">
  167. <div style="border: 1px solid grey;border-radius: 5px;">
  168. <div class="row" style="row-gap:10px;">
  169. <div class="col-md-12 col-sm-12">
  170. <div class="card-header">
  171. <b>Enrolled Details</b>
  172. </div>
  173. <div class="card-body">
  174. <div class="row pl-3 pb-2" style="row-gap:10px;">
  175. <span id="epic_verify_link" style="cursor:pointer; color:blue; text-decoration:underline;">
  176. Click here to verify EPIC No <i class="ik ik-external-link"></i>
  177. </span>
  178. </div>
  179. <div class="row" style="row-gap:10px;">
  180. <div class="col-md-6 col-sm-12">
  181. <label class="form-label" for="epic_no">EPIC No</label>
  182. <input type="text" class="form-control" id="epic_no">
  183. </div>
  184. <div class="col-md-6 col-sm-12">
  185. <label class="form-label" for="epic_name">Name</label>
  186. <input type="text" class="form-control" id="epic_name" readonly="readonly">
  187. </div>
  188. <div class="col-md-6 col-sm-12">
  189. <label class="form-label" for="enrolledassembly_dropdown">Enrolled Assembly Constituency</label>
  190. <select id="enrolledassembly_dropdown" class="form-control">
  191. <option value="">Select</option>
  192. </select>
  193. </div>
  194. </div>
  195. <div class="row mt-2" style="row-gap:10px;">
  196. <div class="col-md-6 col-sm-12">
  197. <label class="form-label" for="part_no">Part No</label>
  198. <input type="text" class="form-control" id="part_no">
  199. </div>
  200. <div class="col-md-6 col-sm-12">
  201. <label class="form-label" for="si_no">SI. No</label>
  202. <input type="text" class="form-control" id="si_no">
  203. </div>
  204. </div>
  205. </div>
  206. </div>
  207. </div>
  208. </div>
  209. </div>
  210. <div class="card-body" style="padding: 10px;">
  211. <div class="row" id="btn_container">
  212. <div class="col-12 d-flex justify-content-center">
  213. <button type="button" class="btn btn-secondary mx-2" onclick="goback()">Back</button>
  214. <button type="submit" class="btn btn-primary mx-2" id="saveBtn">Update</button>
  215. </div>
  216. </div>
  217. </div>
  218. </form>
  219. </div>
  220. </div>
  221. </div>
  222. </div>
  223. </div>
  224. <div class="modal fade" id="profileImageModal" tabindex="-1">
  225. <div class="modal-dialog">
  226. <div class="modal-content">
  227. <div class="modal-header">
  228. <h5 class="modal-title">Profile Photo</h5>
  229. <button type="button" class="close" data-dismiss="modal" aria-label="Close">
  230. <span aria-hidden="true">&times;</span>
  231. </button>
  232. </div>
  233. <div class="modal-body text-center">
  234. <img id="modal_profile_image" src="" class="img-fluid rounded" style="max-height:400px;" />
  235. </div>
  236. </div>
  237. </div>
  238. </div>
  239. <div id="pageLoader" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(255, 255, 255, 0.8); z-index: 9999; text-align: center;">
  240. <div style="position: relative; top: 50%; transform: translateY(-50%);">
  241. <div class="spinner-border text-primary" role="status" style="width: 3rem; height: 3rem;">
  242. <span class="sr-only">Loading...</span>
  243. </div>
  244. <!-- Add the 'Please wait' text below the spinner -->
  245. <p style="margin-top: 1rem; font-size: 1.2rem; color: #007bff;">Please wait...</p>
  246. </div>
  247. </div>
  248. <div th:replace="~{fragments/modules/base/app_module_menu_box :: div}"></div>
  249. <footer th:replace="~{fragments/modules/base/footer :: footer}"></footer>
  250. </div>
  251. </div>
  252. <script th:replace="~{fragments/modules/base/script :: script}"></script>
  253. <script type="text/javascript">
  254. $(document).ready(function() {
  255. let slno = sessionStorage.getItem("slno");
  256. console.log("slno from sessionStorage:", slno);
  257. if (!slno ) {
  258. window.location.href = "/election/update_pollingperson/update";
  259. }
  260. document.getElementById("slno").value = slno;
  261. // ❗ Remove values IMMEDIATELY so refresh loses them
  262. sessionStorage.removeItem("slno");
  263. let designationDropdown = document.getElementById('design_dropdown');
  264. fetch('/election/api/dataentry/batch/getAllDesignations')
  265. .then(response => response.json())
  266. .then(result => {
  267. if (result.status !== "success") {
  268. console.error("API error:", result.message);
  269. return;
  270. }
  271. let list = result.data;
  272. // Clear existing options
  273. designationDropdown.innerHTML = `<option value="">Select</option>`;
  274. // Add options from the API response
  275. list.forEach(design => {
  276. designationDropdown.innerHTML += `
  277. <option value="${design.new_designation}">
  278. ${design.new_designation}
  279. </option>`;
  280. });
  281. // ⭐ Activate Select2 after options added
  282. $('#design_dropdown').select2({
  283. placeholder: "Search designation...",
  284. allowClear: true,
  285. width: "100%"
  286. });
  287. getPollingDetails(slno);
  288. $('#design_dropdown').on('change', function () {
  289. let selectedDesgId = $(this).val();
  290. if (selectedDesgId) {
  291. console.log("selectedDesgId",selectedDesgId)
  292. getDesignationDetails(selectedDesgId);
  293. }
  294. else{
  295. document.getElementById("basic_pay").value = "";
  296. document.getElementById("grade_pay").value = "";
  297. document.getElementById("pay_band").value = "";
  298. }
  299. });
  300. })
  301. .catch(error => {
  302. console.error('Error fetching designation:', error);
  303. });
  304. let NativeTaulkDropdown = document.getElementById('nativetaluk_dropdown');
  305. fetch('/election/api/dataentry/batch/getAllDistricts')
  306. .then(response => response.json())
  307. .then(result => {
  308. if (result.status !== "success") {
  309. console.error("API error:", result.message);
  310. return;
  311. }
  312. let list = result.data;
  313. NativeTaulkDropdown.innerHTML = `<option value="">Select</option>`;
  314. // Add options from the API response
  315. list.forEach(nativedis => {
  316. NativeTaulkDropdown.innerHTML += `
  317. <option value="${nativedis.dist_no}">
  318. ${nativedis.dist_name}
  319. </option>`;
  320. });
  321. $('#nativetaluk_dropdown').select2({
  322. placeholder: "Search",
  323. allowClear: true,
  324. width: "100%"
  325. });
  326. if (window.editHomeDist) {
  327. $('#nativetaluk_dropdown').val(window.editHomeDist).trigger('change');
  328. }
  329. })
  330. .catch(error => {
  331. console.error('Error fetching in District :', error);
  332. });
  333. let NativeAcDropdown = document.getElementById('nativeassembly_dropdown');
  334. let ResiAcDropdown = document.getElementById('residentialassembly_dropdown');
  335. let EnrollAsDropdown = document.getElementById('enrolledassembly_dropdown');
  336. function loadOptions(dropdown, list) {
  337. dropdown.innerHTML = `<option value="">Select</option>`;
  338. list.forEach(item => {
  339. dropdown.innerHTML += `
  340. <option value="${item.ac_no}">
  341. ${item.ac_name}
  342. </option>`;
  343. });
  344. }
  345. fetch('/election/api/dataentry/batch/getAllAclist')
  346. .then(response => response.json())
  347. .then(result => {
  348. if (result.status !== "success") {
  349. console.error("API error:", result.message);
  350. return;
  351. }
  352. let list = result.data;
  353. // Load all three dropdowns using same function
  354. loadOptions(NativeAcDropdown, list);
  355. loadOptions(ResiAcDropdown, list);
  356. loadOptions(EnrollAsDropdown, list);
  357. $('#nativeassembly_dropdown, #residentialassembly_dropdown, #enrolledassembly_dropdown').select2({
  358. placeholder: "Search",
  359. allowClear: true,
  360. width: "100%"
  361. });
  362. // PRESELECT VALUES (ONLY IF NOT NULL)
  363. if (window.nativeAcNo) {
  364. $('#nativeassembly_dropdown').val(window.nativeAcNo).trigger('change');
  365. }
  366. if (window.resideAcNo) {
  367. $('#residentialassembly_dropdown').val(window.resideAcNo).trigger('change');
  368. }
  369. if (window.enrollAcNo) {
  370. $('#enrolledassembly_dropdown').val(window.enrollAcNo).trigger('change');
  371. }
  372. })
  373. .catch(error => {
  374. console.error('Error fetching Assembly Constituency:', error);
  375. });
  376. document.getElementById("official_name").addEventListener("input", function () {
  377. document.getElementById("epic_name").value = this.value;
  378. });
  379. document.getElementById("epic_verify_link").addEventListener("click", function () {
  380. window.open("https://electoralsearch.eci.gov.in/", "_blank");
  381. });
  382. // getOfficeDetails(officeId);
  383. // getPollingDetails(slno);
  384. $('#profileimage').on('input', function () {
  385. let fileInput = this;
  386. let file = fileInput.files[0];
  387. // Allowed extensions
  388. let allowedExtensions = /(\.jpg|\.jpeg)$/i;
  389. // File name
  390. let fileName = file.name;
  391. // File size (10 MB = 10 * 1024 * 1024)
  392. let maxSize = 10 * 1024 * 1024;
  393. // 1) Validate extension
  394. if (!allowedExtensions.test(fileName)) {
  395. Swal.fire({
  396. icon: 'error',
  397. title: 'Invalid File Type',
  398. text: 'Only JPG / JPEG images are allowed!'
  399. });
  400. fileInput.value = ""; // Reset file
  401. return;
  402. }
  403. // 2) Validate MIME type
  404. if (file.type !== "image/jpeg") {
  405. Swal.fire({
  406. icon: 'error',
  407. title: 'Invalid Image Format',
  408. text: 'Only JPEG images are allowed!'
  409. });
  410. fileInput.value = "";
  411. return;
  412. }
  413. // 3) Validate size
  414. if (file.size > maxSize) {
  415. Swal.fire({
  416. icon: 'error',
  417. title: 'File Too Large',
  418. text: 'File size must be 10 MB or less!'
  419. });
  420. fileInput.value = "";
  421. return;
  422. }
  423. });
  424. $('#res_pincode').on('input', function () {
  425. // Remove anything that is not a digit
  426. this.value = this.value.replace(/\D/g, '');
  427. // Limit to max 6 digits
  428. if (this.value.length > 6) {
  429. this.value = this.value.slice(0, 6);
  430. }
  431. });
  432. // PHONE NO: 8 to 10 digits
  433. $('#res_phoneno').on('input', function () {
  434. // Allow only digits
  435. this.value = this.value.replace(/\D/g, '');
  436. // Max 10 digits
  437. if (this.value.length > 10) {
  438. this.value = this.value.slice(0, 10);
  439. }
  440. });
  441. // MOBILE NO: exactly 10 digits
  442. $('#res_mobile').on('input', function () {
  443. // Allow only digits
  444. this.value = this.value.replace(/\D/g, '');
  445. // Max 10 digits
  446. if (this.value.length > 10) {
  447. this.value = this.value.slice(0, 10);
  448. }
  449. });
  450. // PART NO: 6 digits only
  451. $('#part_no').on('input', function () {
  452. this.value = this.value.replace(/\D/g, ''); // allow digits only
  453. if (this.value.length > 6) {
  454. this.value = this.value.slice(0, 6); // max 6 digits
  455. }
  456. });
  457. // SI NO: 6 digits only
  458. $('#si_no').on('input', function () {
  459. this.value = this.value.replace(/\D/g, ''); // allow digits only
  460. if (this.value.length > 6) {
  461. this.value = this.value.slice(0, 6); // max 6 digits
  462. }
  463. });
  464. $('#epic_no').on('input', function () {
  465. // Allow only A–Z, a–z, 0–9
  466. this.value = this.value.replace(/[^A-Za-z0-9]/g, '');
  467. // Limit to 16 characters
  468. if (this.value.length > 16) {
  469. this.value = this.value.slice(0, 16);
  470. }
  471. });
  472. $('#newpollingform').submit(function (e) {
  473. e.preventDefault();
  474. let formData = new FormData(this);
  475. $('#saveBtn').prop('disabled', true).text('Updating...');
  476. $('#pageLoader').show();
  477. function setIfPresent(formData, key, value) {
  478. if (value !== undefined && value !== null && value !== "") {
  479. formData.set(key, value);
  480. }
  481. }
  482. function setFileIfPresent(formData, key, fileInput) {
  483. if (fileInput && fileInput.files && fileInput.files.length > 0) {
  484. formData.set(key, fileInput.files[0]);
  485. }
  486. }
  487. let userId = document.getElementById('userIdSpan').textContent;
  488. // let batch_no = $('#batch_no').val().trim();
  489. let official_name = $('#official_name').val().trim();
  490. let official_age = $('#official_age').val().trim();
  491. // Convert to number
  492. let ageNum = parseInt(official_age, 10);
  493. // Validate age
  494. if(official_age){
  495. if (isNaN(ageNum) || ageNum < 18 || ageNum > 65) {
  496. $('#pageLoader').hide();
  497. $('#saveBtn').prop('disabled', false).text('Update');
  498. Swal.fire({
  499. icon: 'warning',
  500. title: 'Invalid Age',
  501. text: 'Age must be between 18 and 65'
  502. });
  503. return;
  504. }
  505. }
  506. let gender = $("input[name='gender']:checked").val();
  507. // let design_id=$('#design_dropdown').val();
  508. // let design_name = $('#design_dropdown').val();
  509. let design_name = $('#pollperson_desig').val().trim();
  510. let respincode=$('#res_pincode').val().trim();
  511. if(respincode){
  512. // Rule 1: Must be exactly 6 digits & should NOT start with 0
  513. if (!/^[1-9][0-9]{5}$/.test(respincode)) {
  514. $('#pageLoader').hide();
  515. $('#saveBtn').prop('disabled', false).text('Update');
  516. Swal.fire({
  517. icon: 'warning',
  518. title: 'Invalid Pincode',
  519. text: 'Pincode must be 6 digits and cannot start with 0.'
  520. });
  521. return;
  522. }
  523. // Rule 2: Reject 123456 (sequential)
  524. if (respincode === "123456") {
  525. $('#pageLoader').hide();
  526. $('#saveBtn').prop('disabled', false).text('Update');
  527. Swal.fire({
  528. icon: 'warning',
  529. title: 'Invalid Pincode',
  530. text: 'Sequential numbers like 123456 are not allowed.'
  531. });
  532. return;
  533. }
  534. // Rule 3: Reject all digits same (111111, 222222, etc.)
  535. if (/^(\d)\1{5}$/.test(respincode)) {
  536. $('#pageLoader').hide();
  537. $('#saveBtn').prop('disabled', false).text('Update');
  538. Swal.fire({
  539. icon: 'warning',
  540. title: 'Invalid Pincode',
  541. text: 'All digits cannot be the same.'
  542. });
  543. return;
  544. }
  545. }
  546. let phnumber=$('#res_phoneno').val().trim();
  547. if(phnumber){
  548. // Validate 8 to 10 digits only
  549. if (!/^\d{8,10}$/.test(phnumber)) {
  550. $('#pageLoader').hide();
  551. $('#saveBtn').prop('disabled', false).text('Update');
  552. Swal.fire({
  553. icon: 'warning',
  554. title: 'Invalid Phone Number',
  555. text: 'Phone number must be 8 to 10 digits.'
  556. });
  557. return;
  558. }
  559. }
  560. let mobnumber=$('#res_mobile').val().trim();
  561. if(mobnumber){
  562. // Rule 1: Must be exactly 10 digits & must not start with 0
  563. if (!/^[1-9][0-9]{9}$/.test(mobnumber)) {
  564. $('#pageLoader').hide();
  565. $('#saveBtn').prop('disabled', false).text('Update');
  566. Swal.fire({
  567. icon: 'warning',
  568. title: 'Invalid Mobile Number',
  569. text: 'Mobile number must be 10 digits and cannot start with 0.'
  570. });
  571. return;
  572. }
  573. // Rule 2: Reject sequential numbers like 1234567890
  574. if (mobnumber === "1234567890") {
  575. $('#pageLoader').hide();
  576. $('#saveBtn').prop('disabled', false).text('Update');
  577. Swal.fire({
  578. icon: 'warning',
  579. title: 'Invalid Mobile Number',
  580. text: 'Sequential numbers like 1234567890 are not allowed.'
  581. });
  582. return;
  583. }
  584. // Rule 3: Reject all digits same (1111111111, 2222222222, etc.)
  585. if (/^(\d)\1{9}$/.test(mobnumber)) {
  586. $('#pageLoader').hide();
  587. $('#saveBtn').prop('disabled', false).text('Update');
  588. Swal.fire({
  589. icon: 'warning',
  590. title: 'Invalid Mobile Number',
  591. text: 'All digits cannot be the same.'
  592. });
  593. return;
  594. }
  595. }
  596. let native_taluk=$('#nativetaluk_dropdown').val();
  597. let native_ac=$('#nativeassembly_dropdown').val();
  598. let res_ac=$('#residentialassembly_dropdown').val();
  599. let enrol_ac=$('#enrolledassembly_dropdown').val();
  600. let epic_no = $('#epic_no').val().trim();
  601. if(epic_no){
  602. // Allow only 8 to 16 alphanumeric characters
  603. let epicPattern = /^[A-Za-z0-9]{8,16}$/;
  604. if (!epicPattern.test(epic_no)) {
  605. $('#pageLoader').hide();
  606. $('#saveBtn').prop('disabled', false).text('Save');
  607. Swal.fire({
  608. icon: 'warning',
  609. title: 'Invalid EPIC Number',
  610. text: 'EPIC number must be 8 to 16 alphanumeric characters.'
  611. });
  612. return;
  613. }
  614. }
  615. let part_no =$('#part_no').val().trim();
  616. let si_no = $('#si_no').val().trim();
  617. if(part_no){
  618. // Validate part_no
  619. if (part_no.length > 6) {
  620. $('#pageLoader').hide();
  621. $('#saveBtn').prop('disabled', false).text('Save');
  622. Swal.fire({
  623. icon: 'warning',
  624. title: 'Invalid Part No',
  625. text: 'Maximum 6 digits allowed for Part No.'
  626. });
  627. return;
  628. }
  629. }
  630. if(si_no){
  631. // Validate si_no
  632. if (si_no.length > 6) {
  633. $('#pageLoader').hide();
  634. $('#saveBtn').prop('disabled', false).text('Save');
  635. Swal.fire({
  636. icon: 'warning',
  637. title: 'Invalid Sl. No',
  638. text: 'Maximum 6 digits allowed for Sl No.'
  639. });
  640. return;
  641. }
  642. }
  643. setFileIfPresent(formData, "pp_image", $('#profileimage')[0]);
  644. formData.append("userid", userId);
  645. let existing_uniquenum = $('#existing_uniquenum').text();
  646. formData.append("slno", existing_uniquenum);
  647. setIfPresent(formData, "pName", official_name);
  648. setIfPresent(formData, "pAge", official_age);
  649. setIfPresent(formData, "pGender", gender || "");
  650. setIfPresent(formData, "Designation", design_name);
  651. // setIfPresent(formData, "Designation", design_name);
  652. setIfPresent(formData, "address1", $('#res_address1').val().trim());
  653. setIfPresent(formData, "address2", $('#res_address2').val().trim());
  654. setIfPresent(formData, "address3", $('#res_address3').val().trim());
  655. setIfPresent(formData, "pincode",respincode);
  656. setIfPresent(formData, "policest", $('#res_police').val().trim());
  657. setIfPresent(formData, "phoneno",phnumber);
  658. setIfPresent(formData, "mobileno",mobnumber);
  659. setIfPresent(formData, "district",native_taluk);
  660. setIfPresent(formData, "nativeac",native_ac);
  661. setIfPresent(formData, "resideac",res_ac);
  662. setIfPresent(formData, "electoracno",enrol_ac);
  663. setIfPresent(formData, "electorpartno",part_no );
  664. setIfPresent(formData, "electorslno", si_no);
  665. setIfPresent(formData, "epicno",epic_no);
  666. setIfPresent(formData,"slno",slno);
  667. $.ajax({
  668. url: '/election/api/updatepollperson/updateppdetailsbyid',
  669. type: 'POST',
  670. data: formData,
  671. enctype: 'multipart/form-data',
  672. processData: false,
  673. contentType: false,
  674. success: function (response) {
  675. $('#pageLoader').hide();
  676. if (response.status) {
  677. Swal.fire({
  678. allowOutsideClick: false,
  679. allowEscapeKey: false,
  680. allowEnterKey: false,
  681. icon: 'success',
  682. title: 'Success',
  683. text:response.description
  684. }).then((result) => {
  685. window.location.href="/election/update_pollingperson/update";
  686. });
  687. } else {
  688. $('#pageLoader').hide();
  689. Swal.fire({
  690. icon: 'warning',
  691. title: 'Update Failed',
  692. text: response.description || 'Something went wrong!'
  693. });
  694. }
  695. $('#saveBtn').prop('disabled', false).text('Update');
  696. },
  697. error: function () {
  698. $('#pageLoader').hide();
  699. Swal.fire({
  700. icon: 'error',
  701. title: 'Submission Error',
  702. text: 'Something went wrong while submitting the form.'
  703. });
  704. $('#saveBtn').prop('disabled', false).text('Update');
  705. }
  706. });
  707. });
  708. });
  709. function getDesignationDetails(desgId) {
  710. fetch('/election/api/updatepollperson/getPayDetailsByDesig?DesgName=' + desgId)
  711. .then(response => response.json())
  712. .then(result => {
  713. if (result.status !== "success") {
  714. console.error("API error:", result.message);
  715. return;
  716. }
  717. let data = result.data; // your pay details row
  718. //console.log("Designation Pay Details:", data);
  719. // Example: set values into input fields
  720. document.getElementById("basic_pay").value = data.basic_pay;
  721. document.getElementById("grade_pay").value = data.grade_pay;
  722. document.getElementById("pay_band").value = data.pay_scale;
  723. })
  724. .catch(error => {
  725. console.error("Error fetching pay details:", error);
  726. });
  727. }
  728. function getOfficeDetails(officeId) {
  729. console.log("officeId="+officeId);
  730. fetch('/election/api/dataentry/batch/getOfficeDetailsById?officeId=' + officeId)
  731. .then(response => response.json())
  732. .then(result => {
  733. if (result.status !== "success") {
  734. console.error("API error:", result.message);
  735. return;
  736. }
  737. let data = result.data[0];
  738. console.log("office Details:", data);
  739. // Example: set values into input fields
  740. document.getElementById("off_office_name").value = data.office_name;
  741. document.getElementById("off_address1").value = data.address1;
  742. document.getElementById("off_address2").value = data.address2;
  743. document.getElementById("off_address3").value = data.address3;
  744. document.getElementById("off_pincode").value = data.pincode;
  745. document.getElementById("off_phoneno").value = data.phone_no;
  746. document.getElementById("off_taluk").value = data.taluk_name;
  747. document.getElementById("off_govt_type").value = data.govt_type;
  748. document.getElementById("off_pub_sec").value = data.public_sector;
  749. document.getElementById("off_localbody").value = data.local_body;
  750. document.getElementById("off_edu_ins").value = data.edu_institution;
  751. document.getElementById("off_category").value = data.office_category;
  752. document.getElementById("off_assembly").value = data.office_assembly;
  753. })
  754. .catch(error => {
  755. console.error("Error fetching Office details:", error);
  756. });
  757. }
  758. function getPollingDetails(slno){
  759. $('#pageLoader').show();
  760. console.log("slno="+slno);
  761. fetch('/election/api/updatepollperson/getPollingDetailsById?slno=' + slno)
  762. .then(response => response.json())
  763. .then(result => {
  764. if (result.status !== "success") {
  765. console.error("API error:", result.message);
  766. return;
  767. }
  768. let data = result.data[0];
  769. console.log("Polling Personnel Details:", data);
  770. // window.editDesignationId = data.designation;
  771. window.editDesignationId = data.designation ? data.designation.trim() : "";
  772. window.editHomeDist = data.home_dist;
  773. window.nativeAcNo = data.native_ac_no;
  774. window.resideAcNo = data.reside_ac_no;
  775. window.enrollAcNo = data.elector_ac_no;
  776. // Example: set values into input fields
  777. document.getElementById("official_name").value = data.name;
  778. document.getElementById("epic_name").value = data.name;
  779. document.getElementById("official_age").value = data.age;
  780. document.getElementById("pollperson_desig").value=data.designation;
  781. if (data.sex) {
  782. let genderValue = data.sex; // M / F / T
  783. const radio = document.querySelector(`input[name="gender"][value="${genderValue}"]`);
  784. if (radio) radio.checked = true;
  785. }
  786. $('#existing_uniquenum').text(data.slno);
  787. document.getElementById("res_address1").value = data.r_address1;
  788. document.getElementById("res_address2").value = data.r_address2;
  789. document.getElementById("res_address3").value = data.r_address3;
  790. document.getElementById("res_pincode").value = data.r_pincode;
  791. document.getElementById("res_police").value = data.r_policest;
  792. document.getElementById("res_phoneno").value = data.r_phone_no;
  793. document.getElementById("res_mobile").value = data.r_mobile_no;
  794. if (window.editHomeDist) {
  795. $('#nativetaluk_dropdown').val(window.editHomeDist).trigger('change');
  796. }
  797. if (window.nativeAcNo) {
  798. $('#nativeassembly_dropdown').val(window.nativeAcNo).trigger('change');
  799. }
  800. if (window.resideAcNo) {
  801. $('#residentialassembly_dropdown').val(window.resideAcNo).trigger('change');
  802. }
  803. if (window.enrollAcNo) {
  804. $('#enrolledassembly_dropdown').val(window.enrollAcNo).trigger('change');
  805. }
  806. if (window.editDesignationId) {
  807. $('#design_dropdown')
  808. .val(window.editDesignationId)
  809. .trigger('change');
  810. }
  811. document.getElementById("epic_no").value = data.epic_no;
  812. document.getElementById("part_no").value = data.elector_part_no;
  813. document.getElementById("si_no").value = data.elector_sl_no;
  814. if (data.img_full_path) {
  815. let url = data.img_full_path;
  816. // Extract full file name (e.g., profile_img_02122025195649_newuser.jpg)
  817. let fullName = url.substring(url.lastIndexOf("/") + 1);
  818. // Extract only the part after the last underscore → newuser.jpg
  819. let filename = fullName.includes("_")
  820. ? fullName.substring(fullName.lastIndexOf("_") + 1)
  821. : fullName;
  822. $("#profileimage_preview")
  823. .text(filename)
  824. .show()
  825. .off("click")
  826. .on("click", function () {
  827. $("#modal_profile_image").attr("src", url);
  828. let modal = new bootstrap.Modal(
  829. document.getElementById('profileImageModal')
  830. );
  831. modal.show();
  832. });
  833. } else {
  834. $("#profileimage_preview").hide().text('');
  835. }
  836. })
  837. .catch(error => {
  838. console.error("Error fetching Office details:", error);
  839. })
  840. .finally(() => {
  841. $('#pageLoader').hide(); // ALWAYS hide loader
  842. });
  843. }
  844. function goback(){
  845. //window.location.href="/election/dataentry/batches";
  846. window.history.back();
  847. }
  848. window.onload = function () {
  849. if (performance.getEntriesByType("navigation")[0].type === "reload") {
  850. goback();
  851. }
  852. };
  853. </script>
  854. </body>
  855. </html>