JSFiddle - React, Tailwind, and code Playground
by oktaviardi pratama
HTML
<div class="max-w-6xl mx-auto grid grid-cols-1 lg:grid-cols-2 gap-6">
<!-- Form -->
<div class="bg-white p-6 rounded-lg shadow">
<h2 class="text-xl font-bold mb-4">Form Slip Gaji (Editable)</h2>
<label class="block text-sm font-medium">Nama Perusahaan</label>
<input id="company" value="PT. Zombie Capitalism" class="w-full border p-2 rounded mb-2" />
<label class="block text-sm font-medium">Alamat Perusahaan</label>
<textarea id="address" class="w-full border p-2 rounded mb-2" rows="3">Jl. Kebraon no.27 karangpilang
Surabaya
Jawa Timur</textarea>
<div class="grid grid-cols-2 gap-2">
<div>
<label class="block text-sm font-medium">Periode</label>
<input id="period" value="September 2025" class="w-full border p-2 rounded mb-2" />
</div>
<div>
<label class="block text-sm font-medium">Karyawan</label>
<input id="employee" value="Indra L Brugman" class="w-full border p-2 rounded mb-2" />
</div>
</div>
<div class="grid grid-cols-2 gap-2">
<div>
<label class="block text-sm font-medium">Jabatan</label>
<input id="position" value="Operasional" class="w-full border p-2 rounded mb-2" />
</div>
<div>
<label class="block text-sm font-medium">Status</label>
<input id="status" value="Karyawan Kontrak" class="w-full border p-2 rounded mb-2" />
</div>
</div>
<div class="mt-4">
<h3 class="font-semibold">Penerimaan (Earnings)</h3>
<div id="earnings"></div>
<button onclick="addEarning()" class="mt-2 text-sm text-blue-600">+ Tambah Penerimaan</button>
</div>
<div class="mt-4">
<h3 class="font-semibold">Pengurangan (Deductions)</h3>
<div id="deductions"></div>
<button onclick="addDeduction()" class="mt-2 text-sm text-blue-600">+ Tambah Pengurangan</button>
...
CSS
body{padding:20px;font-family:Inter, system-ui, Arial;}
JavaScript
let earnings = [
{ label: "Gaji Pokok", value: 2300000 },
{ label: "Tunjangan Jabatan", value: 625000 },
{ label: "Tunjangan Makan", value: 500000 },
];
let deductions = [
{ label: "Iuran BPJS Kesehatan", value: 23000 },
{ label: "Iuran BPJS Ketenagakerjaan", value: 46000 },
{ label: "Iuran BPJS Pensiun", value: 23000 },
];
let signaturePad;
let signatureData = "";
function init() {
renderLists();
updatePreview();
const canvas = document.getElementById("signature-pad");
signaturePad = new SignaturePad(canvas);
canvas.width = canvas.offsetWidth;
canvas.height = canvas.offsetHeight;
signaturePad.onEnd = () => {
signatureData = signaturePad.toDataURL();
updatePreview();
};
}
function fmt(n) {
return Number(n||0).toLocaleString("id-ID");
}
function renderLists() {
const earnDiv = document.getElementById("earnings");
earnDiv.innerHTML = "";
earnings.forEach((e,i) => {
earnDiv.innerHTML += `<div class='flex gap-2 items-center mt-2'>
<input value="${e.label}" onchange="updateEarning(${i}, 'label', this.value)" class='flex-1 border p-1 rounded'/>
<input value="${e.value}" onchange="updateEarning(${i}, 'value', this.value)" class='w-32 border p-1 rounded text-right'/>
<button onclick="removeEarning(${i})" class='text-red-600'>Hapus</button>
</div>`;
});
const dedDiv = document.getElementById("deductions");
dedDiv.innerHTML = "";
deductions.forEach((d,i) => {
dedDiv.innerHTML += `<div class='flex gap-2 items-center mt-2'>
<input value="${d.label}" onchange="updateDeduction(${i}, 'label', this.value)" class='flex-1 border p-1 rounded'/>
<input value="${d.value}" onchange="updateDeduction(${i}, 'value', this.value)" class='w-32 border p-1 rounded text-right'/>
<button onclick="removeDeduction(${i})" class='text-red-600'>Hapus</button>
</div>`;
});
updatePreview();
}
function updateEarning(i,field,val){
...