$(document).ready(function () { console.log("Mutations index.js loaded"); // Check if DataTables is available if (typeof $.fn.DataTable === "undefined") { console.error("DataTables not available!"); return; } // Wait for DOM to be fully ready setTimeout(function () { initializeDataTable(); }, 100); }); function initializeDataTable() { console.log("Initializing DataTable..."); // Destroy existing table if any if ($.fn.DataTable.isDataTable("#mutations-table")) { $("#mutations-table").DataTable().destroy(); } // Initialize DataTable var table = $("#mutations-table").DataTable({ processing: true, serverSide: true, destroy: true, ajax: { url: $("#mutations-table").data("url"), type: "GET", data: function (d) { console.log("DataTables request data:", d); console.log("Order info:", d.order); console.log("Columns info:", d.columns); return d; }, error: function (xhr, error, code) { console.error("DataTables AJAX error:", error, code); console.error("Response:", xhr.responseText); }, }, columnDefs: [ { targets: 0, // No. column width: "5%", }, { targets: 8, // Action column width: "20%", className: "text-center", }, { targets: [6, 7], // Total Items and Status columns className: "text-center", }, ], columns: [ { data: "DT_RowIndex", name: "DT_RowIndex", orderable: false, searchable: false, }, { data: "mutation_number", name: "mutation_number", orderable: true, }, { data: "created_at", name: "created_at", orderable: true, }, { data: "from_dealer", name: "from_dealer", orderable: true, }, { data: "to_dealer", name: "to_dealer", orderable: true, }, { data: "requested_by", name: "requested_by", orderable: true, }, { data: "total_items", name: "total_items", orderable: true, }, { data: "status", name: "status", orderable: true, }, { data: "action", name: "action", orderable: false, searchable: false, }, ], order: [[1, "desc"]], // Order by mutation_number desc (which follows ID order) pageLength: 10, responsive: true, ordering: true, // Enable column ordering orderMulti: false, // Single column ordering only }); // Debug ordering events table.on("order.dt", function () { console.log("Order changed:", table.order()); }); // Add loading indicator for ordering table.on("processing.dt", function (e, settings, processing) { if (processing) { console.log("DataTable processing started (ordering/filtering)"); } else { console.log("DataTable processing finished"); } }); // Manual click handler for column headers (fallback) $("#mutations-table thead th").on("click", function () { var columnIndex = $(this).index(); console.log("Column header clicked:", columnIndex, $(this).text()); // Skip if it's the first (No.) or last (Action) column if (columnIndex === 0 || columnIndex === 8) { console.log("Non-sortable column clicked, ignoring"); return; } // Check if DataTables is handling the click if ( $(this).hasClass("sorting") || $(this).hasClass("sorting_asc") || $(this).hasClass("sorting_desc") ) { console.log("DataTables should handle this click"); } else { console.log("DataTables not handling click, manual trigger needed"); // Force DataTables to handle the ordering table.order([columnIndex, "asc"]).draw(); } }); // Handle Cancel Button Click with SweetAlert $(document).on("click", ".btn-cancel", function () { var mutationId = $(this).data("id"); if (typeof Swal !== "undefined") { Swal.fire({ title: "Batalkan Mutasi?", text: "Apakah Anda yakin ingin membatalkan mutasi ini?", icon: "warning", showCancelButton: true, confirmButtonColor: "#d33", cancelButtonColor: "#3085d6", confirmButtonText: "Ya, Batalkan", cancelButtonText: "Batal", }).then((result) => { if (result.isConfirmed) { cancelMutation(mutationId); } }); } else { if (confirm("Apakah Anda yakin ingin membatalkan mutasi ini?")) { cancelMutation(mutationId); } } }); // Handle form submissions with loading state $(document).on("submit", ".approve-form", function () { $(this) .find('button[type="submit"]') .prop("disabled", true) .html("Memproses..."); }); // Validate quantity approved in receive modal $(document).on("input", 'input[name*="quantity_approved"]', function () { var maxValue = parseFloat($(this).attr("max")); var currentValue = parseFloat($(this).val()); if (maxValue && currentValue > maxValue) { $(this).val(maxValue); $(this).addClass("is-invalid"); if (!$(this).siblings(".invalid-feedback").length) { $(this).after( '