Update Koperasi
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
'use strict';
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const page = document.querySelector('.koperasi-list-page');
|
||||
if (!page) return;
|
||||
|
||||
page.querySelector('#koperasi-per-page').addEventListener('change', event => event.target.form.requestSubmit());
|
||||
|
||||
page.querySelectorAll('[data-koperasi-row]').forEach(row => {
|
||||
row.addEventListener('click', event => {
|
||||
if (event.target.closest('a, button, input, select, textarea, label, form')) return;
|
||||
window.location.href = row.querySelector('.edit-record').href;
|
||||
});
|
||||
});
|
||||
|
||||
page.querySelectorAll('[data-koperasi-delete]').forEach(form => {
|
||||
form.addEventListener('submit', event => {
|
||||
event.preventDefault();
|
||||
Swal.fire({
|
||||
title: 'Hapus koperasi?',
|
||||
text: `Data koperasi "${form.dataset.nama}" akan dihapus.`,
|
||||
icon: 'warning',
|
||||
showCancelButton: true,
|
||||
confirmButtonText: 'Ya, hapus',
|
||||
cancelButtonText: 'Batal',
|
||||
customClass: { confirmButton: 'btn btn-danger me-3', cancelButton: 'btn btn-label-secondary' },
|
||||
buttonsStyling: false
|
||||
}).then(result => {
|
||||
if (result.isConfirmed) form.submit();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,49 @@
|
||||
'use strict';
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
document.querySelectorAll('[data-koperasi-wilayah], #koperasi-filter-form').forEach(container => {
|
||||
const levels = ['provinsi', 'kabupaten', 'kecamatan', 'desa']
|
||||
.map(name => ({ name, input: container.querySelector(`[data-wilayah-${name}]`) }))
|
||||
.filter(level => level.input);
|
||||
const controllers = new Map();
|
||||
const updateRequired = () => {
|
||||
if (!container.matches('[data-koperasi-wilayah]')) return;
|
||||
const hasSelection = levels.some(level => level.input.value);
|
||||
levels.forEach(level => { level.input.required = hasSelection; });
|
||||
};
|
||||
const reset = level => {
|
||||
controllers.get(level.name)?.abort();
|
||||
level.input.replaceChildren(new Option(level.input.options[0].textContent, ''));
|
||||
level.input.disabled = true;
|
||||
};
|
||||
levels.forEach((level, index) => {
|
||||
if (index === levels.length - 1) return;
|
||||
level.input.addEventListener('change', async () => {
|
||||
levels.slice(index + 1).forEach(reset);
|
||||
updateRequired();
|
||||
if (!level.input.value) return;
|
||||
const child = levels[index + 1];
|
||||
const controller = new AbortController();
|
||||
controllers.set(child.name, controller);
|
||||
const url = new URL(container.dataset[`${child.name}Url`].replace(':id', encodeURIComponent(level.input.value)), window.location.href);
|
||||
url.searchParams.set('all_wilayah', '1');
|
||||
try {
|
||||
const response = await fetch(url, {
|
||||
signal: controller.signal,
|
||||
headers: { 'Accept': 'application/json', 'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]')?.content || '' }
|
||||
});
|
||||
if (!response.ok) throw new Error('Wilayah gagal dimuat');
|
||||
const options = await response.json();
|
||||
if (controller.signal.aborted) return;
|
||||
options.forEach(option => child.input.add(new Option(option.nama, option.id)));
|
||||
child.input.disabled = false;
|
||||
updateRequired();
|
||||
} catch (error) {
|
||||
if (error.name === 'AbortError') return;
|
||||
child.input.add(new Option('Gagal memuat wilayah, pilih ulang wilayah induk', '', false, true));
|
||||
}
|
||||
});
|
||||
});
|
||||
updateRequired();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,119 @@
|
||||
'use strict';
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const page = document.querySelector('.koperasi-profile-page');
|
||||
if (!page) return;
|
||||
|
||||
page.querySelectorAll('[data-koperasi-locked-tab]').forEach(tab => {
|
||||
tab.addEventListener('click', event => event.preventDefault());
|
||||
});
|
||||
|
||||
page.querySelectorAll('[data-koperasi-survey]').forEach(operasional => {
|
||||
const fields = Array.from(operasional.querySelectorAll('[data-koperasi-survey-field]'));
|
||||
const conditions = new Map(fields.map(wrapper => [wrapper.dataset.koperasiSurveyField, JSON.parse(wrapper.dataset.koperasiConditions)]));
|
||||
const context = JSON.parse(operasional.dataset.koperasiContext);
|
||||
const requiredFields = JSON.parse(operasional.dataset.koperasiRequired);
|
||||
const selectedValues = name => Array.from(operasional.elements)
|
||||
.filter(input => input.name === name || input.name === name + '[]')
|
||||
.filter(input => !['checkbox', 'radio'].includes(input.type) || input.checked)
|
||||
.map(input => input.value);
|
||||
const matches = condition => {
|
||||
if (condition.any) return condition.any.some(matches);
|
||||
if (condition.source === 'profile') return condition.values.includes(context[condition.field]);
|
||||
return active(condition.field) && condition.values.some(value => selectedValues(condition.field).includes(value));
|
||||
};
|
||||
const active = field => (conditions.get(field) || []).every(matches);
|
||||
const updateDependencies = () => {
|
||||
fields.forEach(wrapper => {
|
||||
const field = wrapper.dataset.koperasiSurveyField;
|
||||
const visible = active(field);
|
||||
const required = visible && requiredFields.includes(field);
|
||||
wrapper.classList.toggle('d-none', !visible);
|
||||
wrapper.querySelectorAll('input, select, textarea').forEach(input => {
|
||||
input.disabled = !visible;
|
||||
input.required = required && input.type !== 'checkbox';
|
||||
input.setCustomValidity('');
|
||||
});
|
||||
const checkboxes = wrapper.querySelectorAll('input[type="checkbox"]');
|
||||
if (required && checkboxes.length && !Array.from(checkboxes).some(input => input.checked)) {
|
||||
checkboxes[0].setCustomValidity('Pilih sedikitnya satu pilihan.');
|
||||
}
|
||||
const indicator = wrapper.querySelector('[data-koperasi-required-indicator]');
|
||||
if (indicator) indicator.classList.toggle('d-none', !required);
|
||||
});
|
||||
};
|
||||
operasional.addEventListener('change', event => {
|
||||
const input = event.target;
|
||||
const group = input.closest('[data-koperasi-exclusive]');
|
||||
if (group && input.type === 'checkbox' && input.checked) {
|
||||
group.querySelectorAll('input[type="checkbox"]').forEach(option => {
|
||||
if (option !== input && (input.value === group.dataset.koperasiExclusive || option.value === group.dataset.koperasiExclusive)) {
|
||||
option.checked = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
updateDependencies();
|
||||
});
|
||||
updateDependencies();
|
||||
});
|
||||
|
||||
const activeSection = document.getElementById(window.location.hash.slice(1));
|
||||
if (activeSection && page.contains(activeSection) && activeSection.matches('[data-koperasi-section]')) {
|
||||
const showSection = () => {
|
||||
activeSection.scrollIntoView({ behavior: 'instant', block: 'start' });
|
||||
activeSection.focus({ preventScroll: true });
|
||||
};
|
||||
if (document.readyState === 'complete') {
|
||||
requestAnimationFrame(showSection);
|
||||
} else {
|
||||
window.addEventListener('load', () => requestAnimationFrame(showSection), { once: true });
|
||||
}
|
||||
}
|
||||
|
||||
const form = page.querySelector('[data-koperasi-profile]');
|
||||
if (form) {
|
||||
const jenis = form.querySelector('[name="jenis_koperasi"]');
|
||||
const wrapper = form.querySelector('#koperasi-jenis-lainnya-wrapper');
|
||||
const lainnya = form.querySelector('[name="jenis_koperasi_lainnya"]');
|
||||
const toggleJenisLainnya = () => {
|
||||
const isLainnya = jenis.value === form.dataset.jenisLainnya;
|
||||
wrapper.classList.toggle('d-none', !isLainnya);
|
||||
lainnya.disabled = !isLainnya;
|
||||
};
|
||||
jenis.addEventListener('change', toggleJenisLainnya);
|
||||
toggleJenisLainnya();
|
||||
|
||||
const fokus = form.querySelector('[name="fokus_komoditas"]');
|
||||
const detail = form.querySelector('[name="detail_fokus_komoditas"]');
|
||||
const fokusWrapper = form.querySelector('#koperasi-detail-fokus-wrapper');
|
||||
const toggleFokus = () => {
|
||||
const aktif = fokus.value === fokus.dataset.fokusYa;
|
||||
fokusWrapper.classList.toggle('d-none', !aktif);
|
||||
detail.disabled = !aktif;
|
||||
};
|
||||
fokus.addEventListener('change', toggleFokus);
|
||||
toggleFokus();
|
||||
}
|
||||
|
||||
const formatRupiah = value => {
|
||||
const negative = value.trimStart().startsWith('-');
|
||||
const digits = value.replace(/\D/g, '').replace(/^0+(?=\d)/, '');
|
||||
return (negative ? '-' : '') + digits.replace(/\B(?=(\d{3})+(?!\d))/g, '.');
|
||||
};
|
||||
|
||||
page.querySelectorAll('[data-koperasi-rupiah]').forEach(input => {
|
||||
if (/^-?[\d.]+$/.test(input.value)) input.value = formatRupiah(input.value);
|
||||
input.addEventListener('input', () => {
|
||||
const digitsBefore = input.value.slice(0, input.selectionStart).replace(/\D/g, '').length;
|
||||
input.value = formatRupiah(input.value);
|
||||
let cursor = input.value.startsWith('-') ? 1 : 0;
|
||||
let count = 0;
|
||||
while (cursor < input.value.length && count < digitsBefore) {
|
||||
if (/\d/.test(input.value[cursor])) count++;
|
||||
cursor++;
|
||||
}
|
||||
input.setSelectionRange(cursor, cursor);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
Reference in New Issue
Block a user