Enhance SIDAK with two-way KK-KTP linkage, scanner mobile optimization, NIK validation, and UI improvements
- Implement bidirectional KK-KTP linkage system (address-based & NIK-based) - Optimize scanner for mobile devices (touch slop, larger hit areas, modal locking) - Add NIK validation (16-digit numeric) with client-side feedback - Set default RT/RW values to '000' for both KK and KTP forms - Change 'Kpl Keluarga' label to 'Kepala Keluarga' - Improve scanner error messages and user feedback - Remove redundant 'Deteksi Dokumen' button - Add database schema updates and Docker support files
This commit is contained in:
@@ -88,10 +88,10 @@
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-2 col-form-label">RT/RW</label>
|
||||
<div class="col-sm-3">
|
||||
<input type="text" class="form-control" id="rt" name="rt" placeholder="RT" required>
|
||||
<input type="text" class="form-control" id="rt" name="rt" placeholder="RT" value="000" required>
|
||||
</div>
|
||||
<div class="col-sm-3">
|
||||
<input type="text" class="form-control" id="rw" name="rw" placeholder="RW" required>
|
||||
<input type="text" class="form-control" id="rw" name="rw" placeholder="RW" value="000" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -140,11 +140,62 @@
|
||||
</div>
|
||||
|
||||
<script>
|
||||
window.addEventListener('load', function() {
|
||||
// Scanner Logic
|
||||
var inputImage = document.getElementById('foto_ktp');
|
||||
var preview = document.getElementById('preview_ktp');
|
||||
var hiddenInput = document.getElementById('foto_cropped');
|
||||
window.addEventListener('load', function() {
|
||||
// Pre-fill form from URL parameters
|
||||
var urlParams = new URLSearchParams(window.location.search);
|
||||
if (urlParams.has('nik')) document.getElementsByName('nik')[0].value = urlParams.get('nik');
|
||||
if (urlParams.has('nama')) document.getElementsByName('nama')[0].value = urlParams.get('nama');
|
||||
if (urlParams.has('desa')) document.getElementsByName('desa')[0].value = urlParams.get('desa');
|
||||
if (urlParams.has('rt')) document.getElementsByName('rt')[0].value = urlParams.get('rt');
|
||||
if (urlParams.has('rw')) document.getElementsByName('rw')[0].value = urlParams.get('rw');
|
||||
if (urlParams.has('kecamatan')) document.getElementsByName('kecamatan')[0].value = urlParams.get('kecamatan');
|
||||
if (urlParams.has('kabupaten')) document.getElementsByName('kabupaten')[0].value = urlParams.get('kabupaten');
|
||||
if (urlParams.has('provinsi')) document.getElementsByName('provinsi')[0].value = urlParams.get('provinsi');
|
||||
|
||||
// NIK Validation (16 digits, numeric)
|
||||
var nikInput = document.getElementsByName('nik')[0];
|
||||
function validateNIK(nik) {
|
||||
nik = nik.trim();
|
||||
if (nik.length !== 16) return false;
|
||||
return /^\d+$/.test(nik); // Only digits
|
||||
}
|
||||
function showNIKError(message) {
|
||||
Swal.fire({
|
||||
icon: 'warning',
|
||||
title: 'Format NIK Salah',
|
||||
text: message,
|
||||
confirmButtonText: 'OK'
|
||||
});
|
||||
}
|
||||
// Validate on blur
|
||||
if (nikInput) {
|
||||
nikInput.addEventListener('blur', function() {
|
||||
var nik = this.value.trim();
|
||||
if (nik === '') return;
|
||||
if (!validateNIK(nik)) {
|
||||
showNIKError('NIK harus terdiri dari 16 digit angka.');
|
||||
this.focus();
|
||||
}
|
||||
});
|
||||
}
|
||||
// Validate on form submit
|
||||
var form = document.querySelector('form');
|
||||
if (form) {
|
||||
form.addEventListener('submit', function(e) {
|
||||
var nik = nikInput.value.trim();
|
||||
if (nik !== '' && !validateNIK(nik)) {
|
||||
e.preventDefault();
|
||||
showNIKError('NIK harus terdiri dari 16 digit angka.');
|
||||
nikInput.focus();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Scanner Logic
|
||||
var inputImage = document.getElementById('foto_ktp');
|
||||
var preview = document.getElementById('preview_ktp');
|
||||
var hiddenInput = document.getElementById('foto_cropped');
|
||||
|
||||
// Defines callback for scanner modal
|
||||
window.handleScannerResult = function(base64) {
|
||||
@@ -331,69 +382,142 @@ window.addEventListener('load', function() {
|
||||
}
|
||||
|
||||
//mulai proses simpan data
|
||||
$nik = $_POST['nik'];
|
||||
$cek_nik = mysqli_query($koneksi, "SELECT * FROM tb_pdd WHERE nik='$nik'");
|
||||
if(mysqli_num_rows($cek_nik) > 0){
|
||||
echo "<script>
|
||||
Swal.fire({title: 'Gagal',text: 'NIK sudah terdaftar dalam sistem!',icon: 'error',confirmButtonText: 'OK'
|
||||
}).then((result) => {if (result.value){
|
||||
window.location = 'index.php?page=add-pend';
|
||||
}
|
||||
})</script>";
|
||||
return;
|
||||
}
|
||||
$nik = mysqli_real_escape_string($koneksi, trim($_POST['nik']));
|
||||
$cek_nik = mysqli_query($koneksi, "SELECT * FROM tb_pdd WHERE nik='$nik'");
|
||||
if(mysqli_num_rows($cek_nik) > 0){
|
||||
echo "<script>
|
||||
Swal.fire({title: 'Gagal',text: 'NIK sudah terdaftar dalam sistem!',icon: 'error',confirmButtonText: 'OK'
|
||||
}).then((result) => {if (result.value){
|
||||
window.location = 'index.php?page=add-pend';
|
||||
}
|
||||
})</script>";
|
||||
return;
|
||||
}
|
||||
|
||||
// Sanitize Input to prevent SQL Injection & Syntax Errors
|
||||
$nama = mysqli_real_escape_string($koneksi, trim($_POST['nama']));
|
||||
$tempat_lh = mysqli_real_escape_string($koneksi, trim($_POST['tempat_lh']));
|
||||
$tgl_lh = mysqli_real_escape_string($koneksi, trim($_POST['tgl_lh']));
|
||||
$jekel = mysqli_real_escape_string($koneksi, trim($_POST['jekel']));
|
||||
$desa = mysqli_real_escape_string($koneksi, trim($_POST['desa']));
|
||||
$rt = mysqli_real_escape_string($koneksi, trim($_POST['rt']));
|
||||
$rw = mysqli_real_escape_string($koneksi, trim($_POST['rw']));
|
||||
$agama = mysqli_real_escape_string($koneksi, trim($_POST['agama']));
|
||||
$kawin = mysqli_real_escape_string($koneksi, trim($_POST['kawin']));
|
||||
$pekerjaan = mysqli_real_escape_string($koneksi, trim($_POST['pekerjaan']));
|
||||
$kecamatan = mysqli_real_escape_string($koneksi, trim($_POST['kecamatan']));
|
||||
$kabupaten = mysqli_real_escape_string($koneksi, trim($_POST['kabupaten']));
|
||||
$provinsi = mysqli_real_escape_string($koneksi, trim($_POST['provinsi']));
|
||||
$kewarganegaraan = mysqli_real_escape_string($koneksi, trim($_POST['kewarganegaraan']));
|
||||
|
||||
// Sanitize Input to prevent SQL Injection & Syntax Errors
|
||||
$nik = mysqli_real_escape_string($koneksi, $_POST['nik']);
|
||||
$nama = mysqli_real_escape_string($koneksi, $_POST['nama']);
|
||||
$tempat_lh = mysqli_real_escape_string($koneksi, $_POST['tempat_lh']);
|
||||
$tgl_lh = mysqli_real_escape_string($koneksi, $_POST['tgl_lh']);
|
||||
$jekel = mysqli_real_escape_string($koneksi, $_POST['jekel']);
|
||||
$desa = mysqli_real_escape_string($koneksi, $_POST['desa']);
|
||||
$rt = mysqli_real_escape_string($koneksi, $_POST['rt']);
|
||||
$rw = mysqli_real_escape_string($koneksi, $_POST['rw']);
|
||||
$agama = mysqli_real_escape_string($koneksi, $_POST['agama']);
|
||||
$kawin = mysqli_real_escape_string($koneksi, $_POST['kawin']);
|
||||
$pekerjaan = mysqli_real_escape_string($koneksi, $_POST['pekerjaan']);
|
||||
$kecamatan = mysqli_real_escape_string($koneksi, $_POST['kecamatan']);
|
||||
$kabupaten = mysqli_real_escape_string($koneksi, $_POST['kabupaten']);
|
||||
$provinsi = mysqli_real_escape_string($koneksi, $_POST['provinsi']);
|
||||
$kewarganegaraan = mysqli_real_escape_string($koneksi, $_POST['kewarganegaraan']);
|
||||
|
||||
$sql_simpan = "INSERT INTO tb_pdd (nik, nama, tempat_lh, tgl_lh, jekel, desa, rt, rw, agama, kawin, pekerjaan, foto_ktp, status, kecamatan, kabupaten, provinsi, kewarganegaraan) VALUES (
|
||||
'$nik',
|
||||
'$nama',
|
||||
'$tempat_lh',
|
||||
'$tgl_lh',
|
||||
'$jekel',
|
||||
'$desa',
|
||||
'$rt',
|
||||
'$rw',
|
||||
'$agama',
|
||||
'$kawin',
|
||||
'$pekerjaan',
|
||||
'$nama_file',
|
||||
'Ada',
|
||||
'$kecamatan',
|
||||
'$kabupaten',
|
||||
'$provinsi',
|
||||
'$kewarganegaraan')";
|
||||
$query_simpan = mysqli_query($koneksi, $sql_simpan);
|
||||
mysqli_close($koneksi);
|
||||
|
||||
if ($query_simpan) {
|
||||
echo "<script>
|
||||
Swal.fire({title: 'Tambah Data Berhasil',text: '',icon: 'success',confirmButtonText: 'OK'
|
||||
}).then((result) => {if (result.value){
|
||||
window.location = 'index.php?page=data-pend';
|
||||
}
|
||||
})</script>";
|
||||
}else{
|
||||
echo "<script>
|
||||
Swal.fire({title: 'Tambah Data Gagal',text: '<?php echo mysqli_error($koneksi); ?>',icon: 'error',confirmButtonText: 'OK'
|
||||
}).then((result) => {if (result.value){
|
||||
window.location = 'index.php?page=add-pend';
|
||||
}
|
||||
})</script>";
|
||||
}}
|
||||
$sql_simpan = "INSERT INTO tb_pdd (nik, nama, tempat_lh, tgl_lh, jekel, desa, rt, rw, agama, kawin, pekerjaan, foto_ktp, status, kecamatan, kabupaten, provinsi, kewarganegaraan) VALUES (
|
||||
'$nik',
|
||||
'$nama',
|
||||
'$tempat_lh',
|
||||
'$tgl_lh',
|
||||
'$jekel',
|
||||
'$desa',
|
||||
'$rt',
|
||||
'$rw',
|
||||
'$agama',
|
||||
'$kawin',
|
||||
'$pekerjaan',
|
||||
'$nama_file',
|
||||
'Ada',
|
||||
'$kecamatan',
|
||||
'$kabupaten',
|
||||
'$provinsi',
|
||||
'$kewarganegaraan')";
|
||||
$query_simpan = mysqli_query($koneksi, $sql_simpan);
|
||||
|
||||
if ($query_simpan) {
|
||||
$id_pend_baru = mysqli_insert_id($koneksi);
|
||||
|
||||
// KTP → KK: Cari KK yang cocok berdasarkan alamat
|
||||
$sql_cari_kk = "SELECT k.id_kk, k.no_kk, k.kepala, k.desa, k.rt, k.rw
|
||||
FROM tb_kk k
|
||||
WHERE k.desa='$desa' AND k.rt='$rt' AND k.rw='$rw'
|
||||
AND k.kec='$kecamatan' AND k.kab='$kabupaten' AND k.prov='$provinsi'";
|
||||
$q_cari_kk = mysqli_query($koneksi, $sql_cari_kk);
|
||||
$kk_cocok = mysqli_fetch_assoc($q_cari_kk);
|
||||
|
||||
if ($kk_cocok) {
|
||||
// Tawarkan untuk menghubungkan dengan KK
|
||||
$no_kk = $kk_cocok['no_kk'];
|
||||
$kepala_kk = $kk_cocok['kepala'];
|
||||
$id_kk = $kk_cocok['id_kk'];
|
||||
|
||||
// Cek apakah sudah terhubung
|
||||
$sql_cek_hubungan = "SELECT * FROM tb_anggota WHERE id_kk='$id_kk' AND id_pend='$id_pend_baru'";
|
||||
$q_cek_hubungan = mysqli_query($koneksi, $sql_cek_hubungan);
|
||||
|
||||
if (mysqli_num_rows($q_cek_hubungan) == 0) {
|
||||
// Simpan sementara data untuk konfirmasi JavaScript
|
||||
$_SESSION['kk_link_data'] = [
|
||||
'id_pend' => $id_pend_baru,
|
||||
'id_kk' => $id_kk,
|
||||
'no_kk' => $no_kk,
|
||||
'kepala_kk' => $kepala_kk,
|
||||
'nama_pend' => $nama
|
||||
];
|
||||
|
||||
echo "<script>
|
||||
Swal.fire({
|
||||
title: 'Data Penduduk Disimpan!',
|
||||
html: '<b>Data berhasil disimpan.</b><br><br>Ditemukan KK dengan alamat yang sama:<br><b>No KK: $no_kk</b><br>Kepala Keluarga: $kepala_kk<br><br>Hubungkan ke KK ini sebagai anggota?',
|
||||
icon: 'success',
|
||||
showCancelButton: true,
|
||||
confirmButtonText: 'Ya, Hubungkan',
|
||||
cancelButtonText: 'Tidak, Simpan Saja'
|
||||
}).then((result) => {
|
||||
if (result.value) {
|
||||
// Kirim permintaan untuk menghubungkan
|
||||
fetch('admin/pend/link_to_kk.php', {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
|
||||
body: 'id_pend=$id_pend_baru&id_kk=$id_kk&hubungan=ANGGOTA'
|
||||
}).then(resp => resp.json()).then(data => {
|
||||
if(data.success) {
|
||||
Swal.fire('Berhasil!', 'Data telah dihubungkan dengan KK.', 'success').then(() => {
|
||||
window.location = 'index.php?page=data-pend';
|
||||
});
|
||||
} else {
|
||||
Swal.fire('Gagal', 'Gagal menghubungkan: ' + data.message, 'error').then(() => {
|
||||
window.location = 'index.php?page=data-pend';
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
window.location = 'index.php?page=data-pend';
|
||||
}
|
||||
});
|
||||
</script>";
|
||||
} else {
|
||||
// Sudah terhubung
|
||||
echo "<script>
|
||||
Swal.fire({title: 'Tambah Data Berhasil',text: 'Data telah terhubung dengan KK $no_kk',icon: 'success',confirmButtonText: 'OK'
|
||||
}).then((result) => {if (result.value){
|
||||
window.location = 'index.php?page=data-pend';
|
||||
}
|
||||
})</script>";
|
||||
}
|
||||
} else {
|
||||
// Tidak ada KK yang cocok
|
||||
echo "<script>
|
||||
Swal.fire({title: 'Tambah Data Berhasil',text: '',icon: 'success',confirmButtonText: 'OK'
|
||||
}).then((result) => {if (result.value){
|
||||
window.location = 'index.php?page=data-pend';
|
||||
}
|
||||
})</script>";
|
||||
}
|
||||
} else {
|
||||
echo "<script>
|
||||
Swal.fire({title: 'Tambah Data Gagal',text: '" . mysqli_error($koneksi) . "',icon: 'error',confirmButtonText: 'OK'
|
||||
}).then((result) => {if (result.value){
|
||||
window.location = 'index.php?page=add-pend';
|
||||
}
|
||||
})</script>";
|
||||
}
|
||||
mysqli_close($koneksi);
|
||||
}
|
||||
//selesai proses simpan data
|
||||
|
||||
Reference in New Issue
Block a user