recreate project
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
<?= $this->extend('layout/management_layout') ?>
|
||||
<?= $this->section('content') ?>
|
||||
<div class="container my-4">
|
||||
<h3>Edit Inventory Movement</h3>
|
||||
|
||||
<form action="<?= site_url('inventory/movements/update/'.$movement['id']) ?>" method="post">
|
||||
<?= csrf_field() ?>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Item</label>
|
||||
<input type="text" class="form-control" value="<?= esc($movement['item_name'] ?? $movement['item_id']) ?>" disabled>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Quantity Change</label>
|
||||
<input type="number" name="qty_change" class="form-control" value="<?= esc($movement['qty_change']) ?>" required>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Movement Type</label>
|
||||
<select name="movement_type" class="form-select" required>
|
||||
<?php foreach (['initial','in','out','adjust','distribution'] as $type): ?>
|
||||
<option value="<?= $type ?>" <?= $movement['movement_type']===$type ? 'selected' : '' ?>>
|
||||
<?= ucfirst($type) ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Reason</label>
|
||||
<input type="text" name="reason" class="form-control" maxlength="120" value="<?= esc($movement['reason']) ?>">
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Note</label>
|
||||
<textarea name="note" class="form-control"><?= esc($movement['note']) ?></textarea>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-3">
|
||||
<label class="form-label">Semester</label>
|
||||
<select name="semester" class="form-select">
|
||||
<option value="">-- None --</option>
|
||||
<option value="Spring" <?= $movement['semester']==='Spring'?'selected':'' ?>>Spring</option>
|
||||
<option value="Fall" <?= $movement['semester']==='Fall'?'selected':'' ?>>Fall</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label class="form-label">School Year</label>
|
||||
<input type="text" name="school_year" class="form-control" value="<?= esc($movement['school_year']) ?>">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-primary">Save Changes</button>
|
||||
<a href="<?= site_url('inventory/movements') ?>" class="btn btn-secondary">Cancel</a>
|
||||
</form>
|
||||
</div>
|
||||
<?= $this->endSection() ?>
|
||||
@@ -0,0 +1,213 @@
|
||||
<?= $this->extend('layout/management_layout') ?>
|
||||
<?= $this->section('content') ?>
|
||||
|
||||
<div class="container my-4">
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<h3 class="mb-0"><?= esc($title ?? ($isCreate ? 'Create Inventory Movement' : 'Edit Inventory Movement')) ?></h3>
|
||||
<a href="<?= site_url('inventory/movements') ?>" class="btn btn-outline-secondary">Back to List</a>
|
||||
</div>
|
||||
|
||||
<?php if (session()->getFlashdata('status')): ?>
|
||||
<div class="alert alert-<?= session('status') === 'success' ? 'success' : 'danger' ?>">
|
||||
<?= esc(session('message')) ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (isset($validation) && $validation->getErrors()): ?>
|
||||
<div class="alert alert-danger">
|
||||
<ul class="mb-0">
|
||||
<?php foreach ($validation->getErrors() as $e): ?>
|
||||
<li><?= esc($e) ?></li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<form action="<?= esc($action) ?>" method="post" class="card shadow-sm">
|
||||
<?= csrf_field() ?>
|
||||
<div class="card-body">
|
||||
<!-- =============== Item =============== -->
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Item <span class="text-danger">*</span></label>
|
||||
|
||||
<?php if (!empty($isCreate)): ?>
|
||||
<select name="item_id" class="form-select" required>
|
||||
<option value="">-- Select Item --</option>
|
||||
<?php
|
||||
$oldItem = old('item_id', $movement['item_id'] ?? '');
|
||||
foreach ($items as $it):
|
||||
$selected = (string)$oldItem === (string)$it['id'] ? 'selected' : '';
|
||||
?>
|
||||
<option value="<?= esc($it['id']) ?>" <?= $selected ?>>
|
||||
<?= esc($it['name']) ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<?php else: ?>
|
||||
<!-- Lock item on edit (history integrity). Keep hidden field to submit original value -->
|
||||
<input type="hidden" name="item_id" value="<?= esc($movement['item_id']) ?>">
|
||||
<input type="text" class="form-control" value="<?= esc($movement['item_name'] ?? $movement['item_id']) ?>" disabled>
|
||||
<div class="form-text">Item cannot be changed after creation.</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<!-- =============== Qty Change & Type =============== -->
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-3">
|
||||
<label class="form-label">Quantity Change <span class="text-danger">*</span></label>
|
||||
<input
|
||||
type="number"
|
||||
name="qty_change"
|
||||
required
|
||||
class="form-control"
|
||||
value="<?= esc(old('qty_change', $movement['qty_change'] ?? 0)) ?>"
|
||||
>
|
||||
<div class="form-text">
|
||||
Use negative values for outbound movements if type is <code>out</code> (or set type accordingly).
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6 mb-3">
|
||||
<label class="form-label">Movement Type <span class="text-danger">*</span></label>
|
||||
<select name="movement_type" class="form-select" required>
|
||||
<?php
|
||||
$oldType = old('movement_type', $movement['movement_type'] ?? 'adjust');
|
||||
foreach ($movementTypes as $t):
|
||||
$sel = $oldType === $t ? 'selected' : '';
|
||||
?>
|
||||
<option value="<?= esc($t) ?>" <?= $sel ?>><?= ucfirst($t) ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- =============== Reason & Note =============== -->
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Reason</label>
|
||||
<input
|
||||
type="text"
|
||||
name="reason"
|
||||
maxlength="120"
|
||||
class="form-control"
|
||||
value="<?= esc(old('reason', $movement['reason'] ?? '')) ?>"
|
||||
placeholder="Short reason (max 120 chars)"
|
||||
>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Note</label>
|
||||
<textarea
|
||||
name="note"
|
||||
class="form-control"
|
||||
rows="3"
|
||||
placeholder="Any additional details about this movement..."
|
||||
><?= esc(old('note', $movement['note'] ?? '')) ?></textarea>
|
||||
</div>
|
||||
|
||||
<!-- =============== Semester & School Year =============== -->
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-3">
|
||||
<label class="form-label">Semester</label>
|
||||
<select name="semester" class="form-select">
|
||||
<option value="">-- None --</option>
|
||||
<?php
|
||||
$oldSem = old('semester', $movement['semester'] ?? '');
|
||||
foreach ($semesters as $sem):
|
||||
$sel = $oldSem === $sem ? 'selected' : '';
|
||||
?>
|
||||
<option value="<?= esc($sem) ?>" <?= $sel ?>><?= esc($sem) ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6 mb-3">
|
||||
<label class="form-label">School Year</label>
|
||||
<input
|
||||
type="text"
|
||||
name="school_year"
|
||||
class="form-control"
|
||||
value="<?= esc(old('school_year', $movement['school_year'] ?? '')) ?>"
|
||||
placeholder="e.g., 2025-2026"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- =============== Optional Relations =============== -->
|
||||
<div class="row">
|
||||
<!-- Teachers / TAs from TeacherModel::getTeachersAndTAs() -->
|
||||
<div class="col-md-4 mb-3">
|
||||
<label class="form-label">Teacher (optional)</label>
|
||||
<select name="teacher_id" class="form-select">
|
||||
<option value="">-- None --</option>
|
||||
<?php
|
||||
$oldTeacher = (string) old('teacher_id', (string) ($movement['teacher_id'] ?? ''));
|
||||
foreach ($teachers as $t):
|
||||
$sel = $oldTeacher === (string)$t['id'] ? 'selected' : '';
|
||||
?>
|
||||
<option value="<?= esc($t['id']) ?>" <?= $sel ?>>
|
||||
<?= esc($t['fullname']) ?> (<?= esc(ucfirst($t['role'])) ?>)
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!-- Students (expects id + fullname; adjust if your array key is different) -->
|
||||
<div class="col-md-4 mb-3">
|
||||
<label class="form-label">Student (optional)</label>
|
||||
<select name="student_id" class="form-select">
|
||||
<option value="">-- None --</option>
|
||||
<?php
|
||||
$oldStudent = (string) old('student_id', (string) ($movement['student_id'] ?? ''));
|
||||
foreach ($students as $s):
|
||||
$sel = $oldStudent !== '' && $oldStudent === (string)$s['id'] ? 'selected' : '';
|
||||
?>
|
||||
<option value="<?= esc($s['id']) ?>" <?= $sel ?>><?= esc($s['fullname']) ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4 mb-3">
|
||||
<label class="form-label">Class Section (optional)</label>
|
||||
<select name="class_section_id" class="form-select">
|
||||
<option value="">-- None --</option>
|
||||
<?php
|
||||
$oldSection = (string) old('class_section_id', (string) ($movement['class_section_id'] ?? ''));
|
||||
foreach ($classSections as $cs):
|
||||
$value = (string)$cs['class_section_id']; // using CODE per your schema
|
||||
$sel = $oldSection !== '' && $oldSection === $value ? 'selected' : '';
|
||||
?>
|
||||
<option value="<?= esc($value) ?>" <?= $sel ?>><?= esc($cs['class_section_name']) ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<div class="form-text">Uses the <strong>class_section_id</strong> code (not PK).</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if (!$isCreate): ?>
|
||||
<hr>
|
||||
<div class="row g-3">
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">Performed By</label>
|
||||
<input type="text" class="form-control"
|
||||
value="<?= esc($movement['performed_by_name'] ?? $movement['performed_by'] ?? '—') ?>" disabled>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">Created At</label>
|
||||
<input type="text" class="form-control" value="<?= esc(!empty($movement['created_at']) ? local_datetime($movement['created_at'], 'm-d-Y H:i') : '—') ?>" disabled>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">Last Updated</label>
|
||||
<input type="text" class="form-control" value="<?= esc(!empty($movement['updated_at']) ? local_datetime($movement['updated_at'], 'm-d-Y H:i') : '—') ?>" disabled>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<div class="card-footer d-flex gap-2">
|
||||
<button type="submit" class="btn btn-primary"><?= $isCreate ? 'Create Movement' : 'Save Changes' ?></button>
|
||||
<a href="<?= site_url('inventory/movements') ?>" class="btn btn-secondary">Cancel</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<?= $this->endSection() ?>
|
||||
@@ -0,0 +1,275 @@
|
||||
<?= $this->extend('layout/management_layout') ?>
|
||||
<?= $this->section('content') ?>
|
||||
<div class="container-fluid">
|
||||
<div class="d-flex justify-content-between align-items-center my-3">
|
||||
<h2 class="mb-0">Inventory Movements</h2>
|
||||
<div class="d-flex gap-2">
|
||||
<!-- Top bulk delete submits the master form by id -->
|
||||
<button id="bulkDeleteBtnTop" type="submit" form="bulkDeleteForm" class="btn btn-danger" disabled>
|
||||
<i class="bi bi-trash"></i> Delete Selected
|
||||
</button>
|
||||
<a href="<?= site_url('inventory/movements/create') ?>" class="btn btn-success">
|
||||
<i class="bi bi-plus-circle"></i> New Movement
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-2"><?= $this->include('partials/academic_filter') ?></div>
|
||||
|
||||
<?php if (session()->getFlashdata('status')): ?>
|
||||
<div class="alert alert-<?= session('status') === 'success' ? 'success' : 'danger' ?>">
|
||||
<?= esc(session('message')) ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="table-responsive">
|
||||
<!-- Single master form holds the selected ids[] for bulk delete -->
|
||||
<form id="bulkDeleteForm" action="<?= site_url('inventory/movements/bulk-delete') ?>" method="post">
|
||||
<?= csrf_field() ?>
|
||||
|
||||
<table id="movementsTable" class="table table-striped table-hover align-middle" data-no-mgmt-sticky="1">
|
||||
<thead class="table-dark">
|
||||
<tr>
|
||||
<th style="width:36px">
|
||||
<input type="checkbox" id="checkAll" title="Select all on this page">
|
||||
</th>
|
||||
<th>ID</th>
|
||||
<th>Item</th>
|
||||
<th>Qty Change</th>
|
||||
<th>Movement Type</th>
|
||||
<th>Reason</th>
|
||||
<th>Semester</th>
|
||||
<th>School Year</th>
|
||||
<th>Teacher</th>
|
||||
<th>Student</th>
|
||||
<th>Class Section</th>
|
||||
<th>Performed By</th>
|
||||
<th>Created At</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if (!empty($movements)): ?>
|
||||
<?php foreach ($movements as $m): ?>
|
||||
<tr>
|
||||
<td>
|
||||
<input type="checkbox" class="row-check" name="ids[]" value="<?= esc($m['id']) ?>">
|
||||
</td>
|
||||
<td><?= esc($m['id']) ?></td>
|
||||
<td><?= esc($m['item_name'] ?? $m['item_id']) ?></td>
|
||||
<td><?= esc($m['qty_change']) ?></td>
|
||||
<td><span class="badge bg-info"><?= esc($m['movement_type']) ?></span></td>
|
||||
<td><?= esc($m['reason']) ?></td>
|
||||
<td><?= esc($m['semester']) ?></td>
|
||||
<td><?= esc($m['school_year']) ?></td>
|
||||
<td><?= esc($m['teacher_name'] ?? $m['teacher_id']) ?></td>
|
||||
<td><?= esc($m['student_name'] ?? $m['student_id']) ?></td>
|
||||
<td><?= esc($m['class_section_name'] ?? $m['class_section_id']) ?></td>
|
||||
<td><?= esc($m['performed_by_name'] ?? $m['performed_by']) ?></td>
|
||||
<td><?= esc(!empty($m['created_at']) ? local_datetime($m['created_at'], 'm-d-Y H:i') : '') ?></td>
|
||||
<td class="text-nowrap">
|
||||
<a href="<?= site_url('inventory/movements/edit/'.$m['id']) ?>" class="btn btn-sm btn-primary">
|
||||
<i class="bi bi-pencil"></i> Edit
|
||||
</a>
|
||||
|
||||
<!-- Single delete button (no nested form). JS will create & submit a POST form with CSRF -->
|
||||
<button type="button"
|
||||
class="btn btn-sm btn-danger btn-delete-one"
|
||||
data-action="<?= site_url('inventory/movements/delete/'.$m['id']) ?>">
|
||||
<i class="bi bi-trash"></i> Delete
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="mt-2">
|
||||
<button id="bulkDeleteBtnBottom" type="submit" class="btn btn-danger" disabled>
|
||||
<i class="bi bi-trash"></i> Delete Selected
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
$(function(){
|
||||
const table = $('#movementsTable').DataTable({
|
||||
pageLength: 100,
|
||||
order: [[1, 'desc']], // 0=checkbox, 1=ID
|
||||
columnDefs: [
|
||||
{ orderable: false, targets: [0, 13] } // checkbox + actions
|
||||
]
|
||||
});
|
||||
|
||||
const $checkAll = $('#checkAll');
|
||||
const $bulkTop = $('#bulkDeleteBtnTop');
|
||||
const $bulkBot = $('#bulkDeleteBtnBottom');
|
||||
|
||||
function selectionCount() { return $('#movementsTable tbody .row-check:checked').length; }
|
||||
function syncBulkButtons() {
|
||||
const n = selectionCount();
|
||||
$bulkTop.prop('disabled', n === 0);
|
||||
$bulkBot.prop('disabled', n === 0);
|
||||
}
|
||||
|
||||
// Individual row checks
|
||||
$(document).on('change', '.row-check', syncBulkButtons);
|
||||
|
||||
// Header "select all" (only visible rows on current page)
|
||||
$checkAll.on('change', function() {
|
||||
const checked = this.checked;
|
||||
$('#movementsTable tbody input.row-check').prop('checked', checked);
|
||||
syncBulkButtons();
|
||||
});
|
||||
|
||||
// Keep header checkbox in sync after redraws
|
||||
table.on('draw', function(){
|
||||
const $visible = $('#movementsTable tbody input.row-check');
|
||||
const allChecked = $visible.length && $visible.filter(':checked').length === $visible.length;
|
||||
$checkAll.prop('checked', allChecked && $visible.length > 0);
|
||||
syncBulkButtons();
|
||||
});
|
||||
|
||||
// Confirm for bulk delete (both top and bottom submit the same #bulkDeleteForm)
|
||||
$('#bulkDeleteForm').on('submit', function(e){
|
||||
const n = selectionCount();
|
||||
if (n === 0) { e.preventDefault(); return false; }
|
||||
if (!confirm(`Delete ${n} selected movement(s)?`)) { e.preventDefault(); return false; }
|
||||
});
|
||||
|
||||
// ---- Single delete (avoid nested forms) ----
|
||||
const csrfName = '<?= esc(csrf_token()) ?>';
|
||||
const CSRF_COOKIE_NAME = <?= json_encode(config('Security')->csrfCookieName ?? (config('Security')->cookieName ?? 'csrf_cookie_name')) ?>;
|
||||
function getCookie(name){
|
||||
return document.cookie.split(';').map(v=>v.trim()).find(v=>v.startsWith(name+'='))?.split('=')[1] || '';
|
||||
}
|
||||
|
||||
$(document).on('click', '.btn-delete-one', async function(e){
|
||||
e.preventDefault();
|
||||
const url = $(this).data('action');
|
||||
if (!url) return;
|
||||
|
||||
if (!confirm('Delete this movement?')) return;
|
||||
|
||||
const token = decodeURIComponent(getCookie(CSRF_COOKIE_NAME) || '<?= esc(csrf_hash()) ?>');
|
||||
// Try fast path: POST via fetch, then reload regardless of redirect
|
||||
try {
|
||||
const body = new URLSearchParams();
|
||||
body.append(csrfName, token);
|
||||
const resp = await fetch(url, {
|
||||
method: 'POST',
|
||||
body,
|
||||
credentials: 'same-origin',
|
||||
headers: { 'Accept': 'text/html,application/json', 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', 'X-Requested-With': 'XMLHttpRequest' }
|
||||
});
|
||||
// If the server responded (200/302/etc), just reload to reflect changes
|
||||
if (resp.ok || resp.status === 302 || resp.status === 303 || resp.status === 301) {
|
||||
window.location.reload();
|
||||
return;
|
||||
}
|
||||
} catch (_) {
|
||||
// fall through to form submit
|
||||
}
|
||||
|
||||
// Fallback: create a one-off form and submit (POST with latest CSRF)
|
||||
const form = document.createElement('form');
|
||||
form.method = 'post';
|
||||
form.action = url;
|
||||
const input = document.createElement('input');
|
||||
input.type = 'hidden';
|
||||
input.name = csrfName;
|
||||
input.value = token;
|
||||
form.appendChild(input);
|
||||
document.body.appendChild(form);
|
||||
form.submit();
|
||||
});
|
||||
|
||||
// Keep bulk delete form's CSRF fresh just before submit
|
||||
$('#bulkDeleteForm').on('submit', function(){
|
||||
try {
|
||||
const fresh = decodeURIComponent(getCookie(CSRF_COOKIE_NAME) || '');
|
||||
if (fresh) {
|
||||
const $hidden = $(this).find('input[name="' + csrfName + '"]');
|
||||
if ($hidden.length) $hidden.val(fresh);
|
||||
}
|
||||
} catch(_) {}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<script>
|
||||
// jQuery-free fallback: enables bulk delete buttons and single delete
|
||||
(function(){
|
||||
if (window.jQuery) return; // jQuery path already binds everything
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function(){
|
||||
function qsa(sel, root){ return Array.prototype.slice.call((root||document).querySelectorAll(sel)); }
|
||||
function selCount(){ return qsa('#movementsTable tbody .row-check:checked').length; }
|
||||
function sync(){
|
||||
var n = selCount();
|
||||
var top = document.getElementById('bulkDeleteBtnTop');
|
||||
var bot = document.getElementById('bulkDeleteBtnBottom');
|
||||
if (top) top.disabled = (n === 0);
|
||||
if (bot) bot.disabled = (n === 0);
|
||||
}
|
||||
|
||||
// Individual row checks
|
||||
document.addEventListener('change', function(e){
|
||||
if (e.target && e.target.classList && e.target.classList.contains('row-check')) sync();
|
||||
});
|
||||
// Header select all
|
||||
var checkAll = document.getElementById('checkAll');
|
||||
if (checkAll) {
|
||||
checkAll.addEventListener('change', function(){
|
||||
var on = !!this.checked;
|
||||
qsa('#movementsTable tbody input.row-check').forEach(function(el){ el.checked = on; });
|
||||
sync();
|
||||
});
|
||||
}
|
||||
|
||||
// Confirm bulk delete
|
||||
var bulkForm = document.getElementById('bulkDeleteForm');
|
||||
if (bulkForm) {
|
||||
bulkForm.addEventListener('submit', function(e){
|
||||
var n = selCount();
|
||||
if (n === 0) { e.preventDefault(); return; }
|
||||
if (!confirm('Delete ' + n + ' selected movement(s)?')) { e.preventDefault(); }
|
||||
});
|
||||
}
|
||||
|
||||
// Single delete via fetch fallback
|
||||
(function(){
|
||||
var TOKEN_NAME = '<?= esc(csrf_token()) ?>';
|
||||
var COOKIE_NAME = <?= json_encode(config('Security')->csrfCookieName ?? (config('Security')->cookieName ?? 'csrf_cookie_name')) ?>;
|
||||
function getCookie(n){
|
||||
try { return document.cookie.split(';').map(function(v){return v.trim();}).find(function(v){return v.indexOf(n+'=')===0;})?.split('=')[1] || ''; } catch(_) { return ''; }
|
||||
}
|
||||
document.addEventListener('click', function(e){
|
||||
var btn = e.target && e.target.closest ? e.target.closest('.btn-delete-one') : null;
|
||||
if (!btn) return;
|
||||
e.preventDefault();
|
||||
var url = btn.getAttribute('data-action');
|
||||
if (!url) return;
|
||||
if (!confirm('Delete this movement?')) return;
|
||||
var token = decodeURIComponent(getCookie(COOKIE_NAME) || '<?= esc(csrf_hash()) ?>');
|
||||
var body = new URLSearchParams();
|
||||
body.append(TOKEN_NAME, token);
|
||||
fetch(url, { method:'POST', body, credentials:'same-origin', headers:{ 'Accept':'text/html,application/json', 'Content-Type':'application/x-www-form-urlencoded; charset=UTF-8', 'X-Requested-With':'XMLHttpRequest' } })
|
||||
.then(function(){ location.reload(); })
|
||||
.catch(function(){
|
||||
var form = document.createElement('form');
|
||||
form.method = 'post'; form.action = url;
|
||||
var inp = document.createElement('input');
|
||||
inp.type = 'hidden'; inp.name = TOKEN_NAME; inp.value = token;
|
||||
form.appendChild(inp); document.body.appendChild(form); form.submit();
|
||||
});
|
||||
});
|
||||
})();
|
||||
|
||||
// Initial state
|
||||
sync();
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
<?= $this->endSection() ?>
|
||||
Reference in New Issue
Block a user