|
|
<!DOCTYPE html><html lang="en" xmlns:th="http://www.thymeleaf.org"><head th:replace="~{fragments/modules/base/head :: head}"></head><style>
</style><body>
<div class="wrapper"> <!-- header top menu Start --> <header th:replace="~{fragments/modules/base/header :: header}"></header> <!-- header top menu end --> <div class="page-wrap"> <!--=============== Left Menu side Start ================--> <div th:replace="~{fragments/modules/base/menu :: menu}"></div> <!--=============== Left side End ================--> <div class="main-content"> <div class="container-fluid"> <div class="page-header mb-2"> <div class="row align-items-end"> <div class="col-lg-8"> <div class="page-header-title"> <!-- <i class="far fa-calendar-plus bg-blue"></i> --> <div class="d-inline"> <h5 >Micro-Observer Verification Checklist</h5> <span>Review and verify applicant information</span> </div> </div> </div>
</div> </div>
<div class="row">
<div class="col-md-12"> <div class="card" style="margin-top: 15px;">
<div class="card-body">
<input type="hidden" id="loginUserId" th:value="${loginUserId}">
<div class="form-group"> <div class="row" style="row-gap:10px;"> <div class="col-sm-12 col-md-3"> <label class="form-label" for="batchno">Batch No</label> <input type="text" class="form-control" id="batchno" placeholder="Enter Batch No" required> </div>
<!-- Start SLNO --> <div class="col-sm-12 col-md-4"> <label class="form-label" for="serialno"> Unique Number </label> <input type="text" class="form-control" id="startSerialno" placeholder="Enter From Unique Number" required> </div>
<!-- TO (Optional Text) --> <div class="col-sm-12 col-md-1 text-center"> <label class="form-label d-block"> </label> <span class="fw-bold">To</span> <small class="text-muted d-block">(Optional)</small> </div>
<!-- End SLNO --> <div class="col-sm-12 col-md-4"> <label class="form-label" for="serialno"> </label> <input type="text" class="form-control" id="endSerialno" placeholder="Enter To Unique Number"> </div>
</div>
<br>
<div class="row" style="row-gap:10px;">
<div class="col-sm-12 col-md-4" > <label class="form-label" for="mobilenumber">Mobile Number</label> <input type="text" class="form-control" id="mobilenumber" placeholder="Enter Mobile Number" required> </div>
<!-- Department --> <div class="col-sm-12 col-md-4"> <label class="form-label" for="department">Department
</label> <select class="form-control" id="department" required> <option value=""> Select Department </option> </select> </div> <!-- Office Name --> <div class="col-sm-12 col-md-4"> <label class="form-label" for="officename">Office Name
</label> <select class="form-control" id="officename" required> <option value="">Select Office Name </option> </select> </div>
</div>
<br>
<div class="row" style="row-gap:10px;">
<!-- Left Side: Label + Radio Buttons --> <div class="col-sm-12 col-md-8"> <label class="form-label d-block">Not Exist</label>
<div class="form-check form-check-inline"> <input class="form-check-input" type="radio" name="notExistOption" id="voterId" value="voterid"> <label class="form-check-label" for="voterId">EPIC Number</label> </div>
<div class="form-check form-check-inline"> <input class="form-check-input" type="radio" name="notExistOption" id="mobile" value="mobile"> <label class="form-check-label" for="mobile">Mobile Number</label> </div>
<div class="form-check form-check-inline"> <input class="form-check-input" type="radio" name="notExistOption" id="both" value="both"> <label class="form-check-label" for="both">Both</label> </div> </div> </div>
<div class="row mt-3"> <div class="col-12 d-flex justify-content-center"> <button type="button" class="btn btn-primary mx-2" id="searchBtn">Search</button> <button type="reset" class="btn btn-danger mx-2" id="resetBtn">Reset</button> </div> </div> </div>
</div>
</div> </div> </div> </div>
<!-- verification data table -->
<div class="row"> <div class="col-12"> <div class="card"> <div class="card-header"> <h3><b>Applicants for Checklist</b></h3> </div>
<div class="card-body">
<table id="batchDatatable" class="table table-striped table-bordered table-hover dataTable" role="grid" > <thead class="thead-dark" > <tr role="row"> <th class="text-center">S.No</th> <th class="text-center">Unique No / Batch No</th> <th class="text-center">Name / Pay Scale / Cur.Basic /Grade Pay</th> <th class="text-center">Sex</th> <th class="text-center">Designation</th> <th class="text-center">State /Central</th> <th class="text-center">Office Address</th> <th class="text-center">Mobile</th> <th class="text-center">Residential Address</th> <th class="text-center">Native Constituency</th> <th class="text-center">Residential Constituency</th> <th class="text-center">Working Constituency</th> <th class="text-center">Enrolled - Part / Sl.No / EPIC / Assembly Constituency</th> <th class="text-center">Photo & Signature</th> <!--<th class="text-center">Verification</th>-->
</tr> </thead> <tbody style="text-align:center;">
</tbody>
</table>
<div class="row mt-3"> <div class="col-12 d-flex justify-content-center"> <button id="printBtn" class="btn btn-primary mt-2"> <i class="fa fa-print"></i> Print </button> </div> </div> </div>
</div> </div>
</div>
</div>
<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;"> <div style="position: relative; top: 50%; transform: translateY(-50%);"> <div class="spinner-border text-primary" role="status" style="width: 3rem; height: 3rem;"> <span class="sr-only">Loading...</span> </div> <!-- Add the 'Please wait' text below the spinner --> <p style="margin-top: 1rem; font-size: 1.2rem; color: #007bff;">Please wait...</p> </div> </div> <div th:replace="~{fragments/modules/base/app_module_menu_box :: div}"></div>
<footer th:replace="~{fragments/modules/base/footer :: footer}"></footer> </div>
</div>
<script th:replace="~{fragments/modules/base/script :: script}"></script><script type="text/javascript">
document.getElementById('resetBtn').addEventListener('click', function () { event.preventDefault();
location.reload();
});
$(document).ready(function () { // MOBILE NO: exactly 10 digits $('#mobilenumber').on('input', function () { // Allow only digits this.value = this.value.replace(/\D/g, '');
// Max 10 digits if (this.value.length > 10) { this.value = this.value.slice(0, 10); } }); $('#startSerialno').on('input', function () { // Allow only digits this.value = this.value.replace(/\D/g, ''); }); $('#endSerialno').on('input', function () { // Allow only digits this.value = this.value.replace(/\D/g, ''); }); $('#batchno').on('input', function () { // Allow only digits this.value = this.value.replace(/\D/g, ''); }); var table = $('#batchDatatable').DataTable({ dom: 'Bftip', // columnDefs: [ // { targets: 'no-sort', orderable: false }
columnDefs: [ { width: "150px", targets: 1 }, // Name / Pay Scale column { width: "150px", targets: 2 }, // Office Address column { width: "250px", targets: 6 }, {width: "150px", targets: 12}, {width: "100px", targets: 7}, {width: "200px", targets: 8}
], lengthMenu: [ [50, 100, 200, 500, -1], ['50 rows', '100 rows', '200 rows', 'Show all'] ], scrollY: '80vh', scrollX: true,
buttons: [ { extend: 'pageLength', className: 'btn btn-warning' }, { title: 'Data export', extend: 'copyHtml5', text: 'Copy', className: 'btn btn-secondary', id: 'copyBtn' }, { extend: 'excelHtml5', text: 'Excel', className: 'btn btn-secondary', id: 'excelBtn' }, { extend: 'csvHtml5', text: 'CSV', className: 'btn btn-secondary', id: 'csvBtn' }, { extend: 'pdfHtml5', text: 'PDF', className: 'btn btn-secondary', id: 'pdfBtn' } ], fixedHeader: true, autoWidth: true, responsive: false, searching: true, select: false, processing: false });
$.ajax({ url: "/election/api/dataentryadmin/getalldepartments", method: "GET", success: function (data) { let department = $("#department"); department.empty().append('<option value="">-- Select Department --</option>'); data.forEach(dept => { department.append( `<option value="${dept.dept_id}">${dept.dept_name}</option>` ); }); // ✅ Enable search inside dropdown department.select2({ placeholder: "Select Department", allowClear: true, width: '100%' }); } });
/* $.ajax({ url: "/election/api/dataentryadmin/getalldepartments", method: "GET", success: function (data) {
console.log("Departments data:", data); let department = $("#department"); department.empty().append('<option value="">-- Select Department --</option>');
data.forEach(dept => { department.append(`<option value="${dept.dept_id}">${dept.dept_name}</option>`); }); } }); */
// load office name $("#department").on("change", function () { let deptId = $(this).val(); let office = $("#officename"); // Reset office dropdown office.empty().append('<option value="">-- Select Office Name --</option>'); //office.select2('destroy'); // ✅ important if (deptId !== "") { $.ajax({ url: "/election/api/dataentryadmin/getallofficenames", method: "GET", data: { deptId: deptId }, success: function (data) { data.forEach(o => { office.append( `<option value="${o.id}">${o.office_full_address}</option>` ); }); // ✅ Enable searchable dropdown office.select2({ placeholder: "Select Office Name", allowClear: true, width: '100%' }); } }); } });
/* // load office name
$("#department").on("change", function () {
let deptId = $(this).val();
console.log("dpetId",deptId)
$("#officename").empty().append('<option value="">-- Select Office Name --</option>');
if (deptId !== "") {
$.ajax({ url: "/election/api/dataentryadmin/getallofficenames", method: "GET", data: { deptId: deptId }, // <-- Correct parameter name success: function (data) { console.log("data",data)
data.forEach(o => { $("#officename").append( `<option value="${o.id}">${o.office_name}</option>` ); }); } }); } }); */
$(document).ready(function () {
const initialParams = new URLSearchParams({ batchNo: "", fromSLno: "", toSLno: "", mobileNo: "", category: "", officeName: "", notExist: "" });
loadApplicants(initialParams.toString());
});
function loadApplicants(paramString) {
$('#pageLoader').show();
$.ajax({ type: "GET", url: `/election/api/checklistadminmob/getApplicants?${paramString}`,
success: function (response) {
console.log("API Response:", response); $('#pageLoader').hide();
if (response.message === "success" && Array.isArray(response.data)) {
$('#batchDatatable').DataTable({ destroy: true, searching: true, autoWidth: true, paging: true, info: true, data: response.data,
columns: [ { data: null, className: 'text-center', render: (d,t,r,m) => m.row + 1 },
{ data: null, className: "text-center", render: r => `${r.slno || '-'}<br>/ ${r.batch_no || '-'}` },
{ data: null, className: "text-center", render: r => ` ${r.name || '-'}<br> <small> ${r.pay_scale || '-'} / ${r.basic_pay || '-'} / ${r.grade_pay || '-'} </small>` },
{ data: 'sex', className: 'text-center' }, { data: 'new_designation', className: 'text-center' }, { data: 'govt_type', className: 'text-center' }, { data: null, className: "text-center", render: r => `${r.office_name || '-'}<br>/ ${r.address || '-'}` }, { data: null, className: 'text-center', render: r => `${r.r_mobile_no || ''}` },
{ data: null, className: 'text-center', render: r => `${r.r_address1 || ''} ${r.r_address2 || ''} ${r.r_address3 || ''} - ${r.r_pincode || ''}` },
{ data: null, className: 'text-center', render : r => `${r.native_ac_no || ''} - ${r.native_constituency || ''}` }, { data: null, className: 'text-center', render : r => `${r.reside_ac_no || ''} - ${r.residential_constituency || ''}` }, { data: null, className: 'text-center', render : r => `${r.work_ac_no || ''} - ${r.working_constituency || ''}` },
{ data: null, className: 'text-center', render: { display: r => ` Part: ${r.elector_part_no || '-'}<br> Sl: ${r.elector_sl_no || '-'}<br> ${r.elector_epic_no || '-'}<br> ${r.elector_ac_no || '-'} - ${r.elector_constituency || '-'} `, export: r => `Part: ${r.elector_part_no || '-'}\n` + `Sl: ${r.elector_sl_no || '-'}\n` + `${r.elector_epic_no || '-'}\n` + `${r.elector_ac_no || '-'} - ${r.elector_constituency || '-'}` } },
{ data: 'img_full_path', className: 'text-center', render: function (url, type, row) { if (!url) { return `<span style="color:red;">No Image</span>`; } return ` <img src="${url}" style="height: 100px; width: 100px; object-fit: cover; border:1px solid #ccc;" alt="Photo"> `; } },
/*{ data: 'poll_person_verify', className: 'text-center', render: function (flag, type, row) {
if (flag == 1) { return `<span class="badge bg-success px-3 py-2"">Verified</span>`; } else { return ` <input type="checkbox" class="verify-checkbox" value="${row.id}"> `; } } }*/ /*{ data: null, className: 'text-center', render: function (data, type, row) { return `<button class="btn btn-warning btn-sm" onclick="verifyApplicant(${row.id})"> Verify </button>`; } }*/ ],
dom: 'Bfrtip', buttons: [ { extend: 'pageLength', className: 'btn btn-warning' }, { title: 'Data export', extend: 'copyHtml5', text: 'Copy', className: 'btn btn-secondary', id: 'copyBtn' }, { extend: 'excelHtml5', text: 'Excel', className: 'btn btn-secondary', id: 'excelBtn', filename: function () { return 'micro_observer_details_' + getTimestamp(); } }, { extend: 'csvHtml5', text: 'CSV', className: 'btn btn-secondary', id: 'csvBtn', filename: function () { return 'micro_observer_details_' + getTimestamp(); } }, { extend: 'pdfHtml5', text: 'PDF', className: 'btn btn-secondary', id: 'pdfBtn', title:'Micro Observer Details', filename: function () { return 'micro_observer_details_' + getTimestamp(); }, orientation: 'landscape', // ⭐ important line pageSize: 'A4',
customize: function (doc) {
doc.pageOrientation = 'landscape';
// Reduce page margins to use full width doc.pageMargins = [10, 10, 10, 10];
// Reduce default font size so columns fit doc.defaultStyle.fontSize = 7; doc.styles.tableHeader.fontSize = 8;
// ⭐ Force table to shrink inside page doc.content[1].table.widths = [ 20, // S.No 40, // Unique/Batch 80, // Name / Pay Scale 20, // Sex 60, // Designation 30, // State / Central 100, // Office Address 50, // Mobile 90, // Residence Address 40, // Native 40, // Reside 40, // Work 70, // Enrolled 50, // Photo ];
// ⭐ Remove large default paddings var objLayout = {}; objLayout['hLineWidth'] = function(i) { return 0.3; }; objLayout['vLineWidth'] = function(i) { return 0.3; }; objLayout['hLineColor'] = function(i) { return '#000'; }; objLayout['vLineColor'] = function(i) { return '#000'; };
objLayout['paddingLeft'] = function(i) { return 2; }; objLayout['paddingRight'] = function(i) { return 2; }; objLayout['paddingTop'] = function(i) { return 2; }; objLayout['paddingBottom'] = function(i) { return 2; };
doc.content[1].layout = objLayout; }
} ],
columnDefs: [ { width: "150px", targets: 1 }, { width: "150px", targets: 2 }, { width: "250px", targets: 6 }, {width: "150px", targets: 12}, {width: "100px", targets: 7}, {width: "200px", targets: 8} ],
scrollY: '80vh', scrollX: true, responsive: false });
} else { Swal.fire("No Data", "No records found", "warning"); } },
error: function (xhr) { $('#pageLoader').hide(); console.log(" Server Error:", xhr.responseText);
Swal.fire({ icon: 'error', title: 'Error', text: 'Server error! Check console.', confirmButtonText: 'OK', allowOutsideClick: false, allowEscapeKey: false, allowEnterKey: false }).then(() => { location.reload(); // optional action }); } }); }
document.getElementById('searchBtn').addEventListener('click', function () {
let batchNo = document.getElementById('batchno').value || ""; let fromSLno = document.getElementById('startSerialno').value || ""; let toSLno = document.getElementById('endSerialno').value || ""; let mobileNo = document.getElementById('mobilenumber').value || ""; let category = document.getElementById('department').value || ""; let officeName = document.getElementById('officename').value || "";
let notExistRadio = document.querySelector('input[name="notExistOption"]:checked'); let notExist = notExistRadio ? notExistRadio.value : "";
if ( !batchNo && !fromSLno && !toSLno && !mobileNo && !category && !officeName && !notExist ) { Swal.fire({ icon: 'warning', title: 'Validation Error', text: 'Please select at least one field to search.', confirmButtonText: 'OK', allowOutsideClick: false, allowEscapeKey: false }); return; } if (!fromSLno && toSLno) { Swal.fire({ icon: 'warning', title: 'Validation Error', text: 'Please Enter SL No (From) to search.', confirmButtonText: 'OK', allowOutsideClick: false, allowEscapeKey: false }); return; } if(mobileNo){ // Rule 1: Must be exactly 10 digits & must not start with 0 if (!/^[1-9][0-9]{9}$/.test(mobileNo)) { $('#pageLoader').hide(); $('#saveBtn').prop('disabled', false).text('Update'); Swal.fire({ icon: 'warning', title: 'Invalid Mobile Number', text: 'Mobile number must be 10 digits and cannot start with 0.' }); return; }
// Rule 2: Reject sequential numbers like 1234567890 if (mobileNo === "1234567890") { $('#pageLoader').hide(); $('#saveBtn').prop('disabled', false).text('Update'); Swal.fire({ icon: 'warning', title: 'Invalid Mobile Number', text: 'Sequential numbers like 1234567890 are not allowed.' }); return; }
// Rule 3: Reject all digits same (1111111111, 2222222222, etc.) if (/^(\d)\1{9}$/.test(mobileNo)) { $('#pageLoader').hide(); $('#saveBtn').prop('disabled', false).text('Update'); Swal.fire({ icon: 'warning', title: 'Invalid Mobile Number', text: 'All digits cannot be the same.' }); return; } }
const params = new URLSearchParams({ batchNo, fromSLno, toSLno, mobileNo, category, officeName, notExist });
loadApplicants(params.toString()); });
});
/* $(document).on("change", ".verify-checkbox", function () {
let checkedCount = $(".verify-checkbox:checked").length;
if (checkedCount > 0) { $("#verifySelectedBtn").show(); } else { $("#verifySelectedBtn").hide(); }
});*/
/*$("#verifySelectedBtn").click(function () {
let selectedIds = [];
$(".verify-checkbox:checked").each(function () { selectedIds.push($(this).val()); });
if (selectedIds.length === 0) { Swal.fire("Warning", "Select at least one record", "warning"); return; }
Swal.fire({ title: "Confirm Verification?", text: `Verify ${selectedIds.length} applicant(s)?`, icon: "question", showCancelButton: true, confirmButtonText: "Yes, Verify", allowOutsideClick: false, allowEscapeKey: false, allowEnterKey: false
}).then((result) => {
if (!result.isConfirmed) return;
$.ajax({ url: "/election/api/checklistadmin/verifyApplicants", type: "POST", traditional: true, data: { id: selectedIds },
success: function (response) {
if (response === "success") {
Swal.fire({ icon: "success", title: "Success", text: "Applicants Verified Successfully", confirmButtonText: "OK", allowOutsideClick: false, allowEscapeKey: false, allowEnterKey: false }).then((result) => {
if (result.isConfirmed) { location.reload(); // ✅ Reload ONLY after OK click }
});
$("#verifySelectedBtn").hide(); } },
error: function () { Swal.fire({ icon: "error", title: "Error", text: "Verification Failed", confirmButtonText: "OK", allowOutsideClick: false, allowEscapeKey: false, allowEnterKey: false }); } });
});
});*/ $(document).on("click", "#printBtn", function () { $('#pageLoader').show();
let batchNo = $('#batchno').val() || ""; let fromSLno = $('#startSerialno').val() || ""; let toSLno = $('#endSerialno').val() || ""; let mobileNo = $('#mobilenumber').val() || ""; let category = $('#department').val() || ""; let officeName = $('#officename').val() || "";
let notExist = $("input[name='notExistOption']:checked").val() || "";
const params = { batchNo, fromSLno, toSLno, mobileNo, category, officeName, notExist };
$.ajax({ url: "/election/api/report/mobchecklist", method: "GET", data: params, xhrFields: { responseType: 'blob' // IMPORTANT }, success: function (data, status, xhr) { $('#pageLoader').hide(); /* console.log("Data: ", data); console.log("Status: ", status); console.log("Xhr: ", xhr); */
if (xhr.status === 204 || data.size === 0) { Swal.fire("No Data Found", "No records available", "warning"); return; }
// Get filename from backend header let disposition = xhr.getResponseHeader("Content-Disposition"); let fileName = "mob_checklist_report_.pdf"; // fallback
if (disposition && disposition.indexOf("filename=") !== -1) { fileName = disposition.split("filename=")[1].trim(); }
const blob = new Blob([data], { type: "application/pdf" });
const link = document.createElement("a"); link.href = window.URL.createObjectURL(blob); link.download = fileName; // <-- use backend filename link.click(); },
error: function () { $('#pageLoader').hide(); Swal.fire("Error", "PDF download failed", "error"); } });
});
/* $(document).on("click", "#printBtn", function () {
let table = $('#batchDatatable').DataTable();
let rows = table.rows({ search: 'applied' }).nodes();
let thead = $(".dataTables_scrollHead thead").clone();
let printTable = ` <table border="1" style="width:100%; border-collapse:collapse; text-align:center; font-size:12px;"> ${thead.prop("outerHTML")} <tbody> `;
rows.each(function (row) { printTable += `<tr>${row.innerHTML}</tr>`; });
printTable += `</tbody></table>`;
let printWindow = window.open("", "", "width=1200,height=800");
printWindow.document.write(` <!DOCTYPE html> <html> <head> <title>Verification Checklist</title> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css"> <style> @page { size: landscape; } body { padding: 20px; font-family: Arial, sans-serif; font-size: 14px; } h4 { text-align: center; margin-bottom: 20px; font-size: 20px; font-weight: bold; } th, td { border: 1px solid #000; padding: 8px; text-align: center; vertical-align: top; white-space: normal; word-wrap: break-word; overflow-wrap: break-word; font-size: 15px;
}
th:nth-child(7), td:nth-child(7) { width: 220px; text-align: left; } table { width: 100%; border-collapse: collapse; table-layout: fixed; font-size: 13px; }
input[type="checkbox"] { display: none; }
button { display: none; }
thead { display: table-header-group; } </style>
</head>
<body>
<h4>Verification Checklist Report</h4>
${printTable}
<script> window.onload = function () { window.print(); window.close(); }; <\/script>
</body> </html> `);
printWindow.document.close(); }); */
function getTimestamp() { const now = new Date(); const yyyy = now.getFullYear(); const mm = String(now.getMonth() + 1).padStart(2, '0'); const dd = String(now.getDate()).padStart(2, '0'); const hh = String(now.getHours()).padStart(2, '0'); const mi = String(now.getMinutes()).padStart(2, '0'); const ss = String(now.getSeconds()).padStart(2, '0');
return `${yyyy}${mm}${dd}_${hh}${mi}${ss}`; }
</script></body></html>
|