MediaWiki:Common.js: Perbedaan antara revisi
Tidak ada ringkasan suntingan Tanda: Suntingan perangkat seluler Suntingan peramban seluler |
Tidak ada ringkasan suntingan Tanda: Suntingan perangkat seluler Suntingan peramban seluler |
||
| Baris 1: | Baris 1: | ||
/** | /** | ||
* ==================================================================== | * ==================================================================== | ||
* MIPPEDIA DATA - ADVANCED STRUCTURED DATA SYSTEM (PRO VERSION) | * MIPPEDIA DATA - ADVANCED STRUCTURED DATA SYSTEM (PRO-MAX VERSION) | ||
* | * Fitur: Advanced Citation, Bypass Cache Fix, UI Grid, Async Loading | ||
* ==================================================================== | * ==================================================================== | ||
*/ | */ | ||
| Baris 25: | Baris 25: | ||
var api = new mw.Api(); | var api = new mw.Api(); | ||
// Ikon SVG Profesional | // Ikon SVG Profesional | ||
var svgEdit = '<svg class="md-icon" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"></path><path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"></path></svg>'; | var svgEdit = '<svg class="md-icon" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"></path><path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"></path></svg>'; | ||
var svgLock = '<svg class="md-icon" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="11" width="18" height="11" rx="2" ry="2"></rect><path d="M7 11V7a5 5 0 0 1 10 0v4"></path></svg>'; | var svgLock = '<svg class="md-icon" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="11" width="18" height="11" rx="2" ry="2"></rect><path d="M7 11V7a5 5 0 0 1 10 0v4"></path></svg>'; | ||
var svgUnlock = '<svg class="md-icon" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="11" width="18" height="11" rx="2" ry="2"></rect><path d="M7 11V7a5 5 0 0 1 9.9-1"></path></svg>'; | var svgUnlock = '<svg class="md-icon" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="11" width="18" height="11" rx="2" ry="2"></rect><path d="M7 11V7a5 5 0 0 1 9.9-1"></path></svg>'; | ||
var svgRef = '<svg class="md-icon" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg>'; | var svgRef = '<svg class="md-icon" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg>'; | ||
var svgLink = '<svg class="md-icon" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg>'; | |||
// 3. INJEKSI CSS TAMPILAN | // 3. INJEKSI CSS TAMPILAN | ||
| Baris 36: | Baris 37: | ||
background: #ffffff; | background: #ffffff; | ||
border-radius: 12px; | border-radius: 12px; | ||
box-shadow: 0 | box-shadow: 0 8px 24px rgba(0,0,0,0.06); | ||
padding: | padding: 24px; | ||
margin: | margin: 24px 0; | ||
font-family: | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; | ||
border: 1px solid # | border: 1px solid #eef0f2; | ||
transition: all 0.3s ease; | |||
} | } | ||
.md-header { | .md-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; padding-bottom: 15px; border-bottom: 1px solid #f0f0f0; } | ||
.md-title { font-size: 1.3em; font-weight: 700; color: #1a1a1a; margin: 0; display: flex; align-items: center; gap: 8px;} | |||
.md-actions { display: flex; gap: 10px; align-items: center; } | |||
.md-title { | |||
.md-actions { display: flex; gap: | |||
.md-icon { vertical-align: middle; } | .md-icon { vertical-align: middle; } | ||
.md-btn-icon { | .md-btn-icon { | ||
background: #f8f9fa; | background: #f8f9fa; border: 1px solid #e2e2e2; cursor: pointer; color: #5a42b8; | ||
padding: 7px 12px; border-radius: 8px; transition: all 0.2s ease; | |||
display: inline-flex; align-items: center; gap: 6px; font-size: 0.85em; font-weight: 600; | |||
padding: | |||
display: inline-flex; | |||
} | } | ||
.md-btn-icon:hover { background: #eef2f5; border-color: #d0d0d0; } | .md-btn-icon:hover:not(:disabled) { background: #eef2f5; border-color: #d0d0d0; transform: translateY(-1px); } | ||
.md-btn-lock { color: # | .md-btn-lock { color: #d32f2f; background: #fff5f5; border-color: #fbd6d6; } | ||
.md-btn-unlock { color: # | .md-btn-lock:hover:not(:disabled) { background: #fee2e2; } | ||
.md-btn-unlock { color: #2e7d32; background: #f1fbf2; border-color: #c8e6c9; } | |||
.md-btn-unlock:hover:not(:disabled) { background: #e8f5e9; } | |||
.md-row-display { | .md-row-display { | ||
display: flex; | display: flex; justify-content: space-between; align-items: flex-start; | ||
padding: 14px 10px; border-bottom: 1px solid #f5f5f5; transition: background 0.2s; border-radius: 6px; | |||
padding: | |||
} | } | ||
.md-row-display:hover { background: #fafafa; } | |||
.md-row-display:last-child { border-bottom: none; } | .md-row-display:last-child { border-bottom: none; } | ||
.md-data-ref { | .md-data-group { display: flex; flex-direction: column; gap: 6px; flex: 1; } | ||
font-size: 0. | .md-data-label { font-size: 0.8em; color: #757575; font-weight: 700; text-transform: uppercase; letter-spacing: 0.8px; } | ||
.md-data-value { font-size: 1.05em; color: #202124; line-height: 1.4; } | |||
.md-ref-badge { | |||
text-decoration: none !important; | font-size: 0.75em; background: #f1f3f4; padding: 4px 10px; border-radius: 20px; | ||
text-decoration: none !important; color: #1a73e8; margin-left: 10px; | |||
display: inline-flex; align-items: center; gap: 4px; border: 1px solid #e8eaed; transition: all 0.2s; | |||
display: inline-flex; | |||
} | } | ||
.md- | .md-ref-badge:hover { background: #e8f0fe; color: #174ea6; border-color: #d2e3fc; } | ||
/* Form Edit */ | /* Form Edit (Grid Layout) */ | ||
.md-form-box { | .md-form-box { background: #fafbfc; border-radius: 10px; padding: 20px; margin-top: 15px; border: 1px solid #eaedf0; } | ||
.md-form-title { font-size: 1em; font-weight: 600; color: #333; margin: 0 0 15px 0; border-bottom: 2px solid #e2e2e2; padding-bottom: 5px; display: inline-block;} | |||
.md-form-group { margin-bottom: 15px; } | |||
.md-form-group label { display: block; font-size: 0.85em; font-weight: 600; margin-bottom: 6px; color: #4a4a4a; } | |||
.md-input, .md-select { | |||
border: 1px solid # | width: 100%; padding: 10px 14px; border: 1px solid #cfd4d9; border-radius: 8px; | ||
box- | box-sizing: border-box; font-family: inherit; font-size: 0.95em; transition: all 0.2s; background: #fff; | ||
} | } | ||
.md- | .md-input:focus, .md-select:focus { border-color: #5a42b8; outline: none; box-shadow: 0 0 0 3px rgba(90, 66, 184, 0.1); } | ||
.md- | |||
/* Grid Referensi 2 Kolom */ | |||
.md-ref-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 15px; background: #fff; padding: 15px; border-radius: 8px; border: 1px dashed #ccc; } | |||
.md-grid-full { grid-column: span 2; } | |||
.md-checkbox-group { display: flex; align-items: center; gap: 8px; font-size: 0.9em; color: #444; margin-top: 10px; cursor: pointer; } | |||
.md- | |||
.md-checkbox-group { display: flex; align-items: center; gap: 8px; font-size: 0.9em; color: #444; margin-top: | |||
/* Tombol | /* Tombol & Spinner */ | ||
.md-form-actions { display: flex; gap: | .md-form-actions { display: flex; gap: 12px; align-items: center; margin-top: 20px; padding-top: 15px; border-top: 1px solid #eaeaea; } | ||
.md-btn { | .md-btn { | ||
padding: | padding: 10px 20px; border: none; border-radius: 8px; font-weight: 600; cursor: pointer; | ||
color: white; font-size: 0.9em; transition: all 0.2s; display: inline-flex; align-items: center; gap: 8px; | |||
color: white; | |||
} | } | ||
.md-btn:hover { | .md-btn:hover:not(:disabled) { transform: translateY(-2px); box-shadow: 0 4px 10px rgba(0,0,0,0.15); } | ||
.md-btn:disabled { opacity: 0.6; cursor: not-allowed | .md-btn:disabled { opacity: 0.6; cursor: not-allowed; } | ||
.md-btn-save { background: #6b52d1; } | .md-btn-save { background: linear-gradient(135deg, #6b52d1, #5a42b8); } | ||
.md-btn-cancel { background: #6c757d; } | .md-btn-cancel { background: #6c757d; } | ||
.md-btn-delete { background: # | .md-btn-delete { background: linear-gradient(135deg, #e53935, #c62828); margin-left: auto; } | ||
.md-spinner { | .md-spinner { | ||
display: none; | display: none; width: 14px; height: 14px; border: 2px solid rgba(255, 255, 255, 0.4); | ||
border-radius: 50%; border-top-color: #ffffff; animation: md-spin 0.8s linear infinite; | |||
border-radius: 50%; | |||
} | } | ||
.md-btn-icon .md-spinner { border-color: rgba(0,0,0,0.2); border-top-color: currentColor; } | |||
.is-loading .md-spinner { display: inline-block; } | .is-loading .md-spinner { display: inline-block; } | ||
@keyframes md-spin { to { transform: rotate(360deg); } } | @keyframes md-spin { to { transform: rotate(360deg); } } | ||
.md-native-render { display: none; } | .md-native-render { display: none; } | ||
.md-small-text { font-size: 0.8em; color: #888; font-weight: normal; } | |||
`; | `; | ||
$('<style>').text(css).appendTo('head'); | $('<style>').text(css).appendTo('head'); | ||
// 4. PARSER DATA | // 4. PARSER DATA | ||
function loadData() { | function loadData() { | ||
return api.get({ | return api.get({ | ||
action: 'query', | action: 'query', prop: 'revisions', titles: pageName, rvprop: 'content', rvslots: 'main', formatversion: 2 | ||
}).then(function(data) { | }).then(function(data) { | ||
var content = data.query.pages[0].revisions[0].slots.main.content; | var content = data.query.pages[0].revisions[0].slots.main.content; | ||
| Baris 186: | Baris 135: | ||
return content; | return content; | ||
}); | }); | ||
} | |||
// --- HELPER UNTUK MEMBENTUK TEKS REFERENSI --- | |||
function buildWikitextRef(refObj) { | |||
if (!refObj) return ""; | |||
if (typeof refObj === 'string') return refObj ? "[ " + refObj + " Rujukan]" : ""; | |||
if (!refObj.url) return ""; // URL Wajib | |||
var title = refObj.title || "Tautan Rujukan"; | |||
var text = "[" + refObj.url + " " + title + "]"; | |||
var details = []; | |||
if (refObj.author) details.push("Penulis: " + refObj.author); | |||
if (refObj.site) details.push("Situs: " + refObj.site); | |||
if (refObj.publisher) details.push("Penerbit: " + refObj.publisher); | |||
if (refObj.date) details.push("Diakses pada: " + refObj.date); | |||
if (refObj.type) details.push("Format: " + refObj.type); | |||
if (details.length > 0) { | |||
text += " — <small>" + details.join(" • ") + "</small>"; | |||
} | |||
return text; | |||
} | } | ||
// 5. PENYIMPANAN KE WIKITEXT API | // 5. PENYIMPANAN KE WIKITEXT API | ||
function saveData(actionType, $btnEl, originalContent) { | function saveData(actionType, $btnEl, originalContent) { | ||
if ($btnEl) $btnEl.addClass('is-loading').prop('disabled', true); | |||
if ($btnEl) | |||
var jsonStr = JSON.stringify({ locked: isLocked, items: dataItems }); | var jsonStr = JSON.stringify({ locked: isLocked, items: dataItems }); | ||
var wt = "<!-- MIPPEDIA_DATA_START | " + jsonStr + " -->\n"; | var wt = "<!-- MIPPEDIA_DATA_START | " + jsonStr + " -->\n"; | ||
wt += "<div class=\"md-native-render\">\n{| class=\"wikitable\"\n! Data !! Nilai !! Referensi\n"; | wt += "<div class=\"md-native-render\">\n{| class=\"wikitable\"\n! Data !! Nilai !! Referensi\n"; | ||
dataItems.forEach(function(item) { | dataItems.forEach(function(item) { | ||
var valTxt = item.link ? "[[" + item.val + "]]" : item.val; | var valTxt = item.link ? "[[" + item.val + "]]" : item.val; | ||
var refTxt = item.ref | var refTxt = buildWikitextRef(item.ref); | ||
wt += "|-\n| " + item.prop + " || " + valTxt + " || " + refTxt + "\n"; | wt += "|-\n| " + item.prop + " || " + valTxt + " || " + refTxt + "\n"; | ||
}); | }); | ||
| Baris 213: | Baris 183: | ||
} | } | ||
// SIMPAN DATA | |||
api.postWithToken('csrf', { | api.postWithToken('csrf', { | ||
action: 'edit', | action: 'edit', title: pageName, text: newContent, summary: 'Mippedia Data: ' + actionType, minor: true | ||
}).done(function() { | }).done(function() { | ||
location. | // FIX CACHE: Eksekusi Purge dulu biar cache anonim dibersihkan, baru reload. | ||
api.post({ action: 'purge', titles: pageName }).always(function() { | |||
window.location.href = mw.util.getUrl(pageName) + '?action=purge'; // Bypass Reload | |||
}); | |||
}).fail(function(err) { | }).fail(function(err) { | ||
if ($btnEl) $btnEl.removeClass('is-loading').prop('disabled', false); | |||
if ($btnEl) | alert("Gagal menyimpan! (Error: " + err + "). Pastikan Anda memiliki izin mengedit halaman ini."); | ||
alert("Gagal | |||
}); | }); | ||
} | } | ||
| Baris 233: | Baris 200: | ||
function buildUI(rawContent) { | function buildUI(rawContent) { | ||
var $app = $('<div id="mippedia-data-app"></div>'); | var $app = $('<div id="mippedia-data-app"></div>'); | ||
var $header = $('<div class="md-header"><h3 class="md-title">' + svgEdit + ' Mippedia Data <span class="md-small-text">Pro</span></h3></div>'); | |||
var $header = $('<div class="md-header"><h3 class="md-title">Mippedia Data</h3></div>'); | |||
var $actions = $('<div class="md-actions"></div>'); | var $actions = $('<div class="md-actions"></div>'); | ||
| Baris 242: | Baris 208: | ||
var lockClass = isLocked ? 'md-btn-unlock' : 'md-btn-lock'; | var lockClass = isLocked ? 'md-btn-unlock' : 'md-btn-lock'; | ||
var $lockBtn = $('<button class="md-btn-icon ' + lockClass + '" title="Akses Pengurus">' + lockIcon + lockText + '</button>'); | // Spinner sudah disematkan di dalam tombol kunci | ||
var $lockBtn = $('<button class="md-btn-icon ' + lockClass + '" title="Akses Pengurus">' + lockIcon + lockText + ' <span class="md-spinner"></span></button>'); | |||
$lockBtn.on('click', function() { | $lockBtn.on('click', function() { | ||
isLocked = !isLocked; | isLocked = !isLocked; | ||
| Baris 249: | Baris 216: | ||
$actions.append($lockBtn); | $actions.append($lockBtn); | ||
} else if (isLocked) { | } else if (isLocked) { | ||
$actions.append('<span title="Dikunci oleh Pengurus" style="color:# | $actions.append('<span title="Dikunci oleh Pengurus" style="color:#d32f2f; font-size:0.9em; font-weight:bold; background:#fff5f5; padding:6px 12px; border-radius:6px; border:1px solid #fbd6d6;">' + svgLock + ' Terkunci</span>'); | ||
} | } | ||
| Baris 263: | Baris 230: | ||
var $list = $('<div class="md-list"></div>'); | var $list = $('<div class="md-list"></div>'); | ||
if (dataItems.length === 0) { | if (dataItems.length === 0) { | ||
$list.append('<div style="color:#888; | $list.append('<div style="color:#888; text-align:center; padding: 30px 0; background:#f9f9f9; border-radius:8px; border:1px dashed #ddd;">Belum ada data struktur. Klik Tambah untuk memulai.</div>'); | ||
} else { | } else { | ||
dataItems.forEach(function(item, index) { | dataItems.forEach(function(item, index) { | ||
var $row = $('<div class="md-row-display"></div>'); | var $row = $('<div class="md-row-display"></div>'); | ||
var $info = $('<div class="md-data-group"></div>'); | var $info = $('<div class="md-data-group"></div>'); | ||
$info.append('<span class="md-data-label">' + item.prop + '</span>'); | $info.append('<span class="md-data-label">' + item.prop + '</span>'); | ||
var $valArea = $('<div></div>'); | var $valArea = $('<div style="display:flex; align-items:center; flex-wrap:wrap; gap:8px;"></div>'); | ||
var displayVal = item.link ? '<a href="' + mw.util.getUrl(item.val) + '" style="color:# | var displayVal = item.link ? '<a href="' + mw.util.getUrl(item.val) + '" style="color:#1a73e8; text-decoration:none; font-weight:600;">' + item.val + '</a>' : item.val; | ||
$valArea.append('<span class="md-data-value">' + displayVal + '</span>'); | $valArea.append('<span class="md-data-value">' + displayVal + '</span>'); | ||
// Render UI Referensi | |||
if (item.ref) { | if (item.ref) { | ||
$valArea.append('<a href="' + | var isObj = typeof item.ref === 'object'; | ||
var refUrl = isObj ? item.ref.url : item.ref; | |||
var refTitle = (isObj && item.ref.title) ? item.ref.title : "Sumber Rujukan"; | |||
var tooltip = []; | |||
if (isObj) { | |||
if(item.ref.author) tooltip.push("Penulis: " + item.ref.author); | |||
if(item.ref.publisher) tooltip.push("Penerbit: " + item.ref.publisher); | |||
if(item.ref.date) tooltip.push("Diakses: " + item.ref.date); | |||
} | |||
var titleAttr = tooltip.length > 0 ? ' title="' + tooltip.join(" | ") + '"' : ''; | |||
if(refUrl) { | |||
$valArea.append('<a href="' + refUrl + '" target="_blank" class="md-ref-badge" ' + titleAttr + '>' + svgRef + refTitle + '</a>'); | |||
} | |||
} | } | ||
$info.append($valArea); | $info.append($valArea); | ||
$row.append($info); | $row.append($info); | ||
if (!isLocked || isSysop) { | if (!isLocked || isSysop) { | ||
var $editIcon = $('<button class="md-btn-icon" style="padding: | var $editIcon = $('<button class="md-btn-icon" style="padding:5px 10px; font-size:0.8em; align-self:center;">' + svgEdit + ' Edit</button>'); | ||
$editIcon.on('click', function() { showForm(index, rawContent); }); | $editIcon.on('click', function() { showForm(index, rawContent); }); | ||
$row.append($editIcon); | $row.append($editIcon); | ||
| Baris 306: | Baris 287: | ||
} | } | ||
// 8. LOGIKA FORM EDIT | // 8. LOGIKA FORM EDIT (DENGAN ADVANCED REF GRID) | ||
function showForm(index, rawContent) { | function showForm(index, rawContent) { | ||
var $container = $('#md-form-container'); | var $container = $('#md-form-container'); | ||
| Baris 312: | Baris 293: | ||
var isNew = index === -1; | var isNew = index === -1; | ||
var currentData = isNew ? { prop: '', val: '', link: false, ref: | var currentData = isNew ? { prop: '', val: '', link: false, ref: {} } : dataItems[index]; | ||
// Konversi format ref lama (string) ke objek biar nggak error | |||
var currentRef = currentData.ref || {}; | |||
if (typeof currentRef === 'string') currentRef = { url: currentRef }; | |||
var $form = $('<div class="md-form-box"></div>'); | var $form = $('<div class="md-form-box"></div>'); | ||
$form.append('<div class="md-form-group"><label>Data</label><input type="text" id="md-inp-prop" class="md-input" value="' + currentData.prop + ' | $form.append('<h4 class="md-form-title">' + (isNew ? 'Tambah Data Baru' : 'Edit Data') + '</h4>'); | ||
$form.append('<div class="md-form-group"><label>Nilai</label><input type="text" id="md-inp-val" class="md-input" value="' + currentData.val + ' | |||
// Input Utama | |||
$form.append('<div class="md-form-group"><label>Label Data (Contoh: Pekerjaan, Sutradara)</label><input type="text" id="md-inp-prop" class="md-input" value="' + (currentData.prop || '') + '"></div>'); | |||
$form.append('<div class="md-form-group"><label>Nilai Data</label><input type="text" id="md-inp-val" class="md-input" value="' + (currentData.val || '') + '"></div>'); | |||
var chk = currentData.link ? 'checked' : ''; | var chk = currentData.link ? 'checked' : ''; | ||
$form.append('< | $form.append('<label class="md-checkbox-group"><input type="checkbox" id="md-inp-link" ' + chk + '> Jadikan Tautan Internal (Wikilink)</label>'); | ||
// Grid Detail Referensi (Opsional) | |||
var $refArea = $('<div class="md-form-group" style="margin-top:25px;"></div>'); | |||
$refArea.append('<label>Sumber Referensi <span class="md-small-text">(Semua kolom di bawah opsional)</span></label>'); | |||
var $refGrid = $('<div class="md-ref-grid"></div>'); | |||
// Full Width (URL) | |||
$refGrid.append('<div class="md-grid-full"><input type="url" id="md-ref-url" class="md-input" placeholder="URL Tautan (https://...)" value="' + (currentRef.url || '') + '"></div>'); | |||
// 2 Kolom | |||
$refGrid.append('<div><input type="text" id="md-ref-title" class="md-input" placeholder="Judul Halaman Web" value="' + (currentRef.title || '') + '"></div>'); | |||
$refGrid.append('<div><input type="text" id="md-ref-site" class="md-input" placeholder="Nama Situs (cth: Kompas, BBC)" value="' + (currentRef.site || '') + '"></div>'); | |||
$refGrid.append('<div><input type="text" id="md-ref-publisher" class="md-input" placeholder="Penerbit" value="' + (currentRef.publisher || '') + '"></div>'); | |||
$refGrid.append('<div><input type="text" id="md-ref-author" class="md-input" placeholder="Nama Penulis" value="' + (currentRef.author || '') + '"></div>'); | |||
$refGrid.append('<div><input type="date" id="md-ref-date" class="md-input" value="' + (currentRef.date || '') + '" title="Tanggal Diakses"></div>'); | |||
var selWeb = currentRef.type === 'Berita/Web' ? 'selected' : ''; | |||
var selPdf = currentRef.type === 'Dokumen PDF' ? 'selected' : ''; | |||
var selVid = currentRef.type === 'Video' ? 'selected' : ''; | |||
$refGrid.append('<div><select id="md-ref-type" class="md-select"><option value="">-- Format --</option><option value="Berita/Web" '+selWeb+'>Berita / Web</option><option value="Dokumen PDF" '+selPdf+'>Dokumen PDF</option><option value="Video" '+selVid+'>Video</option></select></div>'); | |||
$ | $refArea.append($refGrid); | ||
$form.append($refArea); | |||
// Tombol Aksi | |||
var $actions = $('<div class="md-form-actions"></div>'); | var $actions = $('<div class="md-form-actions"></div>'); | ||
var $btnSave = $('<button class="md-btn md-btn-save">Simpan Data <span class="md-spinner"></span></button>'); | |||
var $btnSave = $('<button class="md-btn md-btn-save"> | |||
var $btnCancel = $('<button class="md-btn md-btn-cancel">Batal</button>'); | var $btnCancel = $('<button class="md-btn md-btn-cancel">Batal</button>'); | ||
| Baris 334: | Baris 343: | ||
if (!isNew) { | if (!isNew) { | ||
var $btnDelete = $('<button class="md-btn md-btn-delete">Hapus | var $btnDelete = $('<button class="md-btn md-btn-delete">Hapus <span class="md-spinner"></span></button>'); | ||
$btnDelete.on('click', function() { | $btnDelete.on('click', function() { | ||
if(confirm('Yakin mau hapus baris data ini secara permanen?')) { | if(confirm('Yakin mau hapus baris data ini secara permanen?')) { | ||
| Baris 346: | Baris 355: | ||
$form.append($actions); | $form.append($actions); | ||
$container.append($form); | $container.append($form); | ||
// Scroll ke form dengan mulus | |||
$('html, body').animate({ scrollTop: $form.offset().top - 100 }, 300); | |||
$btnCancel.on('click', function() { $container.empty(); }); | $btnCancel.on('click', function() { $container.empty(); }); | ||
| Baris 353: | Baris 365: | ||
var newVal = $('#md-inp-val').val().trim(); | var newVal = $('#md-inp-val').val().trim(); | ||
var newLink = $('#md-inp-link').is(':checked'); | var newLink = $('#md-inp-link').is(':checked'); | ||
if (!newProp || !newVal) { | if (!newProp || !newVal) { | ||
alert("Label Data dan Nilai harus diisi, bro!"); | alert("Label Data dan Nilai harus diisi, bro!"); return; | ||
} | } | ||
var newItem = { prop: newProp, val: newVal, link: newLink, ref: | // Ambil Data Referensi | ||
var refObj = { | |||
url: $('#md-ref-url').val().trim(), | |||
title: $('#md-ref-title').val().trim(), | |||
site: $('#md-ref-site').val().trim(), | |||
publisher: $('#md-ref-publisher').val().trim(), | |||
author: $('#md-ref-author').val().trim(), | |||
date: $('#md-ref-date').val(), | |||
type: $('#md-ref-type').val() | |||
}; | |||
// Bersihkan properti referensi yang kosong agar JSON tidak bengkak | |||
Object.keys(refObj).forEach(key => { if (!refObj[key]) delete refObj[key]; }); | |||
// Kalau URL kosong, jadikan ref null | |||
if (!refObj.url) refObj = null; | |||
var newItem = { prop: newProp, val: newVal, link: newLink, ref: refObj }; | |||
if (isNew) | if (isNew) dataItems.push(newItem); | ||
else dataItems[index] = newItem; | |||
saveData(isNew ? 'Menambahkan data baru' : 'Mengubah data', $(this), rawContent); | saveData(isNew ? 'Menambahkan data baru' : 'Mengubah data', $(this), rawContent); | ||
| Baris 372: | Baris 396: | ||
} | } | ||
// 9. | // 9. JALANKAN PROGRAM | ||
loadData().then(function(rawContent) { | loadData().then(function(rawContent) { buildUI(rawContent); }); | ||
}); | }); | ||