Files
database-pertani-web/public/assets/js/bumdes.js
T
2026-11-05 19:20:05 +07:00

376 lines
19 KiB
JavaScript

/* Profil, kelembagaan, dan operasional BUMDes. */
'use strict';
$(document).ready(function () {
const $page = $('.bumdes-page');
if (!$page.length) return;
const profileForm = document.querySelector('[data-bumdes-profile]');
const ajaxHeaders = {
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content,
'Accept': 'application/json'
};
if (profileForm) {
const prefix = '#' + profileForm.dataset.prefix;
const lainnyaValue = profileForm.dataset.jabatanLainnya;
$(`${prefix}-jenis-kelamin, ${prefix}-pendidikan-terakhir, ${prefix}-jabatan`).select2();
$(`${prefix}-tanggal-lahir`).flatpickr({
dateFormat: 'd-m-Y'
});
function toggleJabatanLainnya() {
const isLainnya = $(`${prefix}-jabatan`).val() === lainnyaValue;
$(`${prefix}-jabatan-lainnya-wrapper`).toggleClass('d-none', !isLainnya);
$(`${prefix}-jabatan-lainnya`).prop('disabled', !isLainnya).prop('required', isLainnya);
if (!isLainnya) {
$(`${prefix}-jabatan-lainnya`).val('');
}
}
$(`${prefix}-jabatan`).on('change', toggleJabatanLainnya);
toggleJabatanLainnya();
$(`${prefix}-provinsi`).select2().change(function(e) {
e.preventDefault();
const provinsiId = $(this).val();
$(`${prefix}-kabupaten`).prop('disabled', !provinsiId).val('').trigger('change');
$(`${prefix}-kecamatan`).prop('disabled', true).val('').trigger('change');
$(`${prefix}-desa`).prop('disabled', true).val('').trigger('change');
if (provinsiId) {
$.ajax({
url: profileForm.dataset.kabupatenUrl.replace(':id', provinsiId) + '?all_wilayah=1',
method: 'GET',
headers: ajaxHeaders,
success: function(data) {
$(`${prefix}-kabupaten`).empty().append('<option value="">Pilih Kabupaten/Kota</option>');
data.forEach(function(kabupaten) {
$(`${prefix}-kabupaten`).append(new Option(kabupaten.nama, kabupaten.id));
});
}
});
}
});
$(`${prefix}-kabupaten`).select2().change(function(e) {
e.preventDefault();
const kabupatenId = $(this).val();
$(`${prefix}-kecamatan`).prop('disabled', !kabupatenId).val('').trigger('change');
$(`${prefix}-desa`).prop('disabled', true).val('').trigger('change');
if (kabupatenId) {
$.ajax({
url: profileForm.dataset.kecamatanUrl.replace(':id', kabupatenId) + '?all_wilayah=1',
method: 'GET',
headers: ajaxHeaders,
success: function(data) {
$(`${prefix}-kecamatan`).empty().append('<option value="">Pilih Kecamatan</option>');
data.forEach(function(kecamatan) {
$(`${prefix}-kecamatan`).append(new Option(kecamatan.nama, kecamatan.id));
});
}
});
}
});
$(`${prefix}-kecamatan`).select2().change(function(e) {
e.preventDefault();
const kecamatanId = $(this).val();
$(`${prefix}-desa`).prop('disabled', !kecamatanId).val('').trigger('change');
if (kecamatanId) {
$.ajax({
url: profileForm.dataset.desaUrl.replace(':id', kecamatanId) + '?all_wilayah=1',
method: 'GET',
headers: ajaxHeaders,
success: function(data) {
$(`${prefix}-desa`).empty().append('<option value="">Pilih Desa/Kelurahan</option>');
data.forEach(function(desa) {
$(`${prefix}-desa`).append(new Option(desa.nama, desa.id));
});
}
});
}
});
$(`${prefix}-desa`).select2();
}
if (profileForm) {
function syncProfileDetails() {
const inactive = $('input[name="status_keaktifan"]:checked').val() === 'tidak_aktif_vakum';
$('#alasan-tidak-aktif').prop('disabled', !inactive);
const hasStaff = $('input[name="memiliki_staf"]:checked').val() === '1';
$('#staf-detail-wrapper').find('input').prop('disabled', !hasStaff);
}
$('input[name="status_keaktifan"], input[name="memiliki_staf"]').on('change', syncProfileDetails);
syncProfileDetails();
}
if (document.getElementById('kelembagaanAktorForm')) {
$('#status-badan-hukum, #status-unit-komoditas, #status-ad-art').select2({ width: '100%' });
function setRequired(selector, enabled) {
$(selector).prop('disabled', !enabled).prop('required', enabled).each(function () {
$(`[data-required-for="${this.id}"]`).toggleClass('d-none', !enabled);
});
}
function syncDetails() {
const jasaLainnya = $('#unit-usaha-jasa_lainnya').is(':checked');
$('#unit-usaha-jasa-lainnya-wrapper').toggleClass('d-none', !jasaLainnya).find('input').prop('disabled', !jasaLainnya);
setRequired('#nomor-dasar-hukum, #tahun-dasar-hukum', $('#status-badan-hukum').val() === 'sudah_berbadan_hukum');
setRequired('#nama-unit-komoditas', $('#status-unit-komoditas').val() === 'ya');
setRequired('#tahun-ad-art', $('#status-ad-art').val() === 'ada_lengkap');
}
$('input[name="unit_usaha[]"], #status-badan-hukum, #status-unit-komoditas, #status-ad-art').on('change', syncDetails);
syncDetails();
}
if (document.getElementById('operasionalBumdesForm')) {
function setFieldsEnabled($wrapper, enabled) {
$wrapper.find('input, textarea, select').prop('disabled', !enabled);
if (!enabled) {
$wrapper.find('input:not([type="radio"]):not([type="checkbox"]), textarea').val('');
$wrapper.find('input[type="radio"], input[type="checkbox"]').prop('checked', false);
}
}
function syncPenambahanModal() {
const enabled = $('input[name="pernah_penambahan_modal"]:checked').val() === '1';
const $wrapper = $('#penambahan-modal-wrapper');
setFieldsEnabled($wrapper, enabled);
}
function syncInventarisRow(row) {
const $row = $(row);
const exists = $row.find('.bumdes-inventaris-status-radio[value="1"]').is(':checked');
$row.find('.bumdes-inventaris-detail').prop('disabled', !exists);
$row.find('.bumdes-inventaris-required').prop('required', exists);
if (!exists) {
$row.find('.bumdes-inventaris-detail').val('').removeClass('is-invalid').removeAttr('aria-invalid aria-describedby');
}
}
$('input[name="pernah_penambahan_modal"]').on('change', syncPenambahanModal);
$('.bumdes-inventaris-status-radio').on('change', function () {
syncInventarisRow($(this).closest('tr'));
});
syncPenambahanModal();
$('[data-bumdes-aset], [data-bumdes-infrastruktur]').each(function () { syncInventarisRow(this); });
}
const $moneyForms = $('#operasionalBumdesForm, #rantaiNilaiBumdesForm');
if ($moneyForms.length) {
function onlyDigits(value) {
return String(value || '').replace(/\D/g, '');
}
function formatRupiah(value) {
return onlyDigits(value).replace(/\B(?=(\d{3})+(?!\d))/g, '.');
}
$moneyForms.on('input', '.rupiah-input', function () {
const cursorAtEnd = this.selectionStart === this.value.length;
this.value = formatRupiah(this.value);
if (cursorAtEnd) {
this.setSelectionRange(this.value.length, this.value.length);
}
});
$moneyForms.find('.rupiah-input').each(function () {
this.value = formatRupiah(this.value);
});
$moneyForms.on('submit', function () {
$(this).find('.rupiah-input').each(function () {
this.value = onlyDigits(this.value);
});
});
}
const $choiceForms = $('#operasionalBumdesForm, #rantaiNilaiBumdesForm');
if ($choiceForms.length) {
function syncChoiceField($input, enabled) {
$input.prop('disabled', !enabled).prop('required', enabled);
$choiceForms.find(`[data-required-for="${$input.attr('id')}"]`).toggleClass('d-none', !enabled);
if (!enabled) $input.val('').removeClass('is-invalid');
}
function syncChoiceDetails() {
syncChoiceField($('#jumlah-alokasi-desa'), $choiceForms.find('input[name="ada_alokasi_desa"]:checked').val() === '1');
$choiceForms.find('[data-bumdes-choices]').each(function () {
const $group = $(this);
const $other = $group.find('[data-ekosistem-other-value]');
const enabled = $group.find('input[type="checkbox"]').toArray().some(input => input.checked && input.value === $other.data('ekosistem-other-value'));
syncChoiceField($other, enabled);
});
}
$choiceForms.on('change', 'input[name="ada_alokasi_desa"]', syncChoiceDetails);
$choiceForms.on('change', '[data-bumdes-choices] input[type="checkbox"]', function () {
const $group = $(this).closest('[data-bumdes-choices]');
const exclusive = $group.data('exclusive-value');
if (this.checked) {
$group.find('input[type="checkbox"]').not(this).each((_, input) => {
if (this.value === exclusive || input.value === exclusive) input.checked = false;
});
}
syncChoiceDetails();
});
syncChoiceDetails();
const $rantaiForm = $('#rantaiNilaiBumdesForm');
if ($rantaiForm.length) {
function syncRantaiState() {
const trading = $rantaiForm.find('[name="melakukan_jual_beli"]:checked').val() === '1';
const $tradeSections = $rantaiForm.find('[data-rantai-section]').prop('disabled', !trading).toggleClass('d-none', !trading);
$tradeSections.closest('.card').not('#section-rantai-pembelian').toggleClass('d-none', !trading);
const notSold = $rantaiForm.find('[name="saluran_penjualan[]"]:checked').toArray().some(input => input.value === $rantaiForm.data('belum-menjual-value'));
const $sales = $('#rantai-penjualan-details').prop('disabled', !trading || notSold);
if (notSold) {
$sales.find('input[type="checkbox"]').prop('checked', false);
$sales.find('input:not([type="checkbox"])').val('');
}
$rantaiForm.find('[data-rantai-other-field]').each(function () {
const $group = $(this);
const value = $rantaiForm.find(`[name="${$group.data('rantai-other-field')}"]:checked`).val();
syncChoiceField($group.find('input[type="text"]'), trading && value === $group.data('rantai-other-value'));
});
const purchased = $rantaiForm.find('[name="bentuk_produk_dibeli[]"]:checked').toArray().map(input => input.value);
$rantaiForm.find('[data-rantai-price-product]').each(function () {
const enabled = trading && purchased.includes($(this).data('rantai-price-product'));
const $inputs = $(this).find('input').prop('disabled', !enabled);
if (!enabled) $inputs.val('').removeClass('is-invalid');
});
}
function syncPostharvestState() {
const processing = $rantaiForm.find('[name="melakukan_pengolahan_pascapanen"]:checked').val() === '1';
const $processingSections = $rantaiForm.find('[data-postharvest-section]').prop('disabled', !processing).toggleClass('d-none', !processing);
$processingSections.closest('.card').not('#section-rantai-sortasi').toggleClass('d-none', !processing);
$rantaiForm.find('[data-postharvest-detail]').each(function () {
const $group = $(this);
const value = $rantaiForm.find(`[name="${$group.data('condition-field')}"]:checked`).val();
const enabled = processing && $group.data('condition-values').includes(value);
const $inputs = $group.find('input, textarea');
const $checkboxes = $inputs.filter('[type="checkbox"]');
$inputs.prop('disabled', !enabled);
$inputs.not('[type="checkbox"]').prop('required', enabled);
$checkboxes.prop('required', false);
if (enabled && !$checkboxes.is(':checked')) $checkboxes.first().prop('required', true);
$group.find('[data-postharvest-required]').toggleClass('d-none', !enabled);
if (!enabled) {
$checkboxes.prop('checked', false);
$inputs.not('[type="checkbox"]').val('');
$inputs.removeClass('is-invalid');
}
});
}
$rantaiForm.on('change', 'input', function () {
if (this.name === 'melakukan_jual_beli' && this.value === '0') {
const $fields = $rantaiForm.find('[data-rantai-section] input');
$fields.filter('[type="radio"], [type="checkbox"]').prop('checked', false);
$fields.not('[type="radio"], [type="checkbox"]').val('');
}
if (this.name === 'melakukan_pengolahan_pascapanen' && this.value === '0') {
const $fields = $rantaiForm.find('[data-postharvest-section] input, [data-postharvest-section] textarea');
$fields.filter('[type="radio"], [type="checkbox"]').prop('checked', false);
$fields.not('[type="radio"], [type="checkbox"]').val('');
}
syncChoiceDetails();
syncRantaiState();
syncPostharvestState();
});
syncRantaiState();
syncPostharvestState();
}
}
const $operationalForm = $('#operasionalBumdesForm');
if ($operationalForm.length) {
function syncOperationalConditions() {
$operationalForm.find('[data-operasional-condition]').each(function () {
const $group = $(this);
const field = $group.data('condition-field');
const selected = $operationalForm.find(`[name="${field}"]:checked`).val();
const enabled = $group.data('condition-values').includes(selected);
const $inputs = $group.find('input, textarea, select');
const $checkboxes = $inputs.filter('[type="checkbox"]');
$inputs.prop('disabled', !enabled);
$inputs.not('[type="checkbox"]').prop('required', enabled);
$checkboxes.prop('required', false);
if (enabled && !$checkboxes.is(':checked')) $checkboxes.first().prop('required', true);
$group.find('[data-operasional-required]').toggleClass('d-none', !enabled);
if (!enabled) {
$inputs.not('[type="checkbox"]').val('');
$checkboxes.prop('checked', false);
$inputs.removeClass('is-invalid');
}
});
}
$operationalForm.on('change', 'input, select', syncOperationalConditions);
syncOperationalConditions();
}
const filterForm = document.getElementById('bumdes-filter-form');
if (filterForm) {
const $desa = $('#filter-desa');
let desaRequest;
$('#filter-kecamatan').on('change', function () {
if (desaRequest) desaRequest.abort();
$desa.empty().append(new Option('Semua Desa', '')).prop('disabled', true);
if (!this.value) return;
desaRequest = $.ajax({
url: filterForm.dataset.desaUrl.replace(':id', this.value),
data: {all_wilayah: 1}, headers: ajaxHeaders, dataType: 'json'
}).done(function (data) {
data.forEach(desa => $desa.append(new Option(desa.nama, desa.id)));
$desa.prop('disabled', false);
}).fail(function (xhr, status) {
if (status !== 'abort') $desa.empty().append(new Option('Gagal memuat desa', ''));
});
});
}
$page.on('click', '.bumdes-row', function (event) {
if (!$(event.target).closest('a, button, input, select, textarea, label').length) {
window.location.href = this.querySelector('.edit-record').href;
}
});
$page.on('submit', '.bumdes-delete-form', function (event) {
event.preventDefault();
const form = this;
Swal.fire({
title: 'Apakah Anda yakin?', text: `Profil "${form.dataset.nama}" akan dihapus.`,
icon: 'warning', showCancelButton: true, confirmButtonText: 'Ya, Hapus!', cancelButtonText: 'Batal',
customClass: {confirmButton: 'btn btn-primary me-3', cancelButton: 'btn btn-label-secondary'},
buttonsStyling: false
}).then(result => { if (result.isConfirmed) form.submit(); });
});
const scrollAfterSave = function () {
const notice = document.getElementById('bumdes-notifications');
if (notice && notice.dataset.hasErrors !== '1') {
const target = document.getElementById(window.location.hash.slice(1));
const profileSection = target?.id === 'section-kepengurusan';
const trading = document.querySelector('#rantaiNilaiBumdesForm [name="melakukan_jual_beli"]:checked')?.value === '1';
const processing = document.querySelector('#rantaiNilaiBumdesForm [name="melakukan_pengolahan_pascapanen"]:checked')?.value === '1';
const postharvestTarget = target?.hasAttribute('data-postharvest-card');
const eligibleForTarget = postharvestTarget ? (processing || (trading && target.id === 'section-rantai-sortasi')) : trading;
const valueChainSection = eligibleForTarget && target?.matches('#rantaiNilaiBumdesForm > .card');
if ((profileSection || valueChainSection) && target.closest('.bumdes-page') && target.getClientRects().length) {
target.scrollIntoView({block: 'start'});
return;
}
}
notice?.scrollIntoView({block: 'start'});
};
if (document.readyState === 'complete') {
scrollAfterSave();
} else {
window.addEventListener('load', scrollAfterSave, {once: true});
}
});