add filter date and dealer on mutations and opnames
This commit is contained in:
@@ -18,20 +18,13 @@ class MutationsController extends Controller
|
||||
public function index(Request $request)
|
||||
{
|
||||
$menu = Menu::where('link','mutations.index')->first();
|
||||
$dealers = Dealer::all();
|
||||
|
||||
if ($request->ajax()) {
|
||||
Log::info('Mutations DataTables request', [
|
||||
'order' => $request->get('order'),
|
||||
'columns' => $request->get('columns'),
|
||||
'user_id' => auth()->id()
|
||||
]);
|
||||
|
||||
// Use a more specific query to avoid join conflicts
|
||||
$data = Mutation::query()
|
||||
->with(['fromDealer', 'toDealer', 'requestedBy.role', 'approvedBy.role', 'receivedBy.role'])
|
||||
->select([
|
||||
'mutations.*'
|
||||
]); // Remove default ordering to let DataTables handle it
|
||||
->select(['mutations.*']);
|
||||
|
||||
// Filter berdasarkan dealer jika user bukan admin
|
||||
if (auth()->user()->dealer_id) {
|
||||
@@ -40,6 +33,35 @@ class MutationsController extends Controller
|
||||
->orWhere('to_dealer_id', auth()->user()->dealer_id);
|
||||
});
|
||||
}
|
||||
|
||||
// Filter berdasarkan dealer yang dipilih
|
||||
if ($request->filled('dealer_filter')) {
|
||||
$data->where(function($query) use ($request) {
|
||||
$query->where('from_dealer_id', $request->dealer_filter)
|
||||
->orWhere('to_dealer_id', $request->dealer_filter);
|
||||
});
|
||||
}
|
||||
|
||||
// Filter berdasarkan tanggal
|
||||
if ($request->filled('date_from')) {
|
||||
try {
|
||||
$dateFrom = \Carbon\Carbon::parse($request->date_from)->format('Y-m-d');
|
||||
$data->whereDate('mutations.created_at', '>=', $dateFrom);
|
||||
} catch (\Exception $e) {
|
||||
// Fallback to original format
|
||||
$data->whereDate('mutations.created_at', '>=', $request->date_from);
|
||||
}
|
||||
}
|
||||
|
||||
if ($request->filled('date_to')) {
|
||||
try {
|
||||
$dateTo = \Carbon\Carbon::parse($request->date_to)->format('Y-m-d');
|
||||
$data->whereDate('mutations.created_at', '<=', $dateTo);
|
||||
} catch (\Exception $e) {
|
||||
// Fallback to original format
|
||||
$data->whereDate('mutations.created_at', '<=', $request->date_to);
|
||||
}
|
||||
}
|
||||
|
||||
return DataTables::of($data)
|
||||
->addIndexColumn()
|
||||
@@ -134,7 +156,7 @@ class MutationsController extends Controller
|
||||
->make(true);
|
||||
}
|
||||
|
||||
return view('warehouse_management.mutations.index', compact('menu'));
|
||||
return view('warehouse_management.mutations.index', compact('menu', 'dealers'));
|
||||
}
|
||||
|
||||
public function create()
|
||||
|
||||
@@ -22,10 +22,38 @@ class OpnamesController extends Controller
|
||||
{
|
||||
public function index(Request $request){
|
||||
$menu = Menu::where('link','opnames.index')->first();
|
||||
$dealers = Dealer::all();
|
||||
if($request->ajax()){
|
||||
$data = Opname::with('user','dealer')
|
||||
->orderBy('created_at', 'desc')
|
||||
->get();
|
||||
$data = Opname::query()
|
||||
->with('user','dealer')
|
||||
->orderBy('created_at', 'desc');
|
||||
|
||||
// Filter berdasarkan dealer yang dipilih
|
||||
if ($request->filled('dealer_filter')) {
|
||||
$data->where('dealer_id', $request->dealer_filter);
|
||||
}
|
||||
|
||||
// Filter berdasarkan tanggal
|
||||
if ($request->filled('date_from')) {
|
||||
try {
|
||||
$dateFrom = \Carbon\Carbon::parse($request->date_from)->format('Y-m-d');
|
||||
$data->whereDate('opname_date', '>=', $dateFrom);
|
||||
} catch (\Exception $e) {
|
||||
// Fallback to original format
|
||||
$data->whereDate('opname_date', '>=', $request->date_from);
|
||||
}
|
||||
}
|
||||
|
||||
if ($request->filled('date_to')) {
|
||||
try {
|
||||
$dateTo = \Carbon\Carbon::parse($request->date_to)->format('Y-m-d');
|
||||
$data->whereDate('opname_date', '<=', $dateTo);
|
||||
} catch (\Exception $e) {
|
||||
// Fallback to original format
|
||||
$data->whereDate('opname_date', '<=', $request->date_to);
|
||||
}
|
||||
}
|
||||
|
||||
return DataTables::of($data)
|
||||
->addColumn('user_name', function ($row){
|
||||
return $row->user ? $row->user->name : '-';
|
||||
@@ -59,7 +87,7 @@ class OpnamesController extends Controller
|
||||
->make(true);
|
||||
}
|
||||
|
||||
return view('warehouse_management.opnames.index');
|
||||
return view('warehouse_management.opnames.index', compact('dealers'));
|
||||
}
|
||||
|
||||
public function create(){
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -7,12 +7,147 @@ $(document).ready(function () {
|
||||
return;
|
||||
}
|
||||
|
||||
// Initialize components
|
||||
initializeSelect2();
|
||||
initializeDatepickers();
|
||||
|
||||
// Wait for DOM to be fully ready
|
||||
setTimeout(function () {
|
||||
initializeDataTable();
|
||||
}, 100);
|
||||
});
|
||||
|
||||
function initializeSelect2() {
|
||||
console.log("Initializing Select2...");
|
||||
|
||||
// Initialize Select2 for dealer filter
|
||||
if (typeof $.fn.select2 !== "undefined") {
|
||||
$("#dealer_filter").select2({
|
||||
placeholder: "Pilih Dealer",
|
||||
allowClear: false,
|
||||
width: "100%",
|
||||
dropdownAutoWidth: true,
|
||||
minimumResultsForSearch: 5, // Show search box if more than 5 options
|
||||
});
|
||||
} else {
|
||||
console.warn("Select2 not available, using regular select");
|
||||
}
|
||||
}
|
||||
|
||||
function initializeDatepickers() {
|
||||
console.log("Initializing datepickers...");
|
||||
|
||||
// Initialize start date picker
|
||||
$("#date_from").datepicker({
|
||||
dateFormat: "yy-mm-dd",
|
||||
changeMonth: true,
|
||||
changeYear: true,
|
||||
maxDate: new Date(),
|
||||
yearRange: "-5:+0",
|
||||
onSelect: function (selectedDate) {
|
||||
console.log("Start date selected:", selectedDate);
|
||||
enableEndDatePicker(selectedDate);
|
||||
$(this).datepicker("hide");
|
||||
},
|
||||
onClose: function (selectedDate) {
|
||||
if (selectedDate) {
|
||||
console.log("Start date closed with value:", selectedDate);
|
||||
enableEndDatePicker(selectedDate);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
// Initialize end date picker (initially disabled)
|
||||
initializeEndDatePicker();
|
||||
|
||||
// Initially disable end date input
|
||||
$("#date_to").prop("disabled", true);
|
||||
|
||||
// Add calendar icons
|
||||
addCalendarIcons();
|
||||
|
||||
// Setup calendar icon click handlers
|
||||
setupIconClickHandlers();
|
||||
|
||||
// Backup: Listen to change event
|
||||
setupChangeEventHandlers();
|
||||
}
|
||||
|
||||
function enableEndDatePicker(startDate) {
|
||||
console.log("Enabling end date picker with min date:", startDate);
|
||||
|
||||
// Enable the input
|
||||
$("#date_to").prop("disabled", false);
|
||||
|
||||
// Destroy existing datepicker
|
||||
$("#date_to").datepicker("destroy");
|
||||
|
||||
// Re-initialize with new minDate
|
||||
$("#date_to").datepicker({
|
||||
dateFormat: "yy-mm-dd",
|
||||
changeMonth: true,
|
||||
changeYear: true,
|
||||
maxDate: new Date(),
|
||||
yearRange: "-5:+0",
|
||||
minDate: new Date(startDate), // Convert to Date object for proper comparison
|
||||
onSelect: function (selectedDate) {
|
||||
console.log("End date selected:", selectedDate);
|
||||
$(this).datepicker("hide");
|
||||
},
|
||||
});
|
||||
|
||||
console.log("End date picker enabled with minDate:", startDate);
|
||||
}
|
||||
|
||||
function initializeEndDatePicker() {
|
||||
$("#date_to").datepicker({
|
||||
dateFormat: "yy-mm-dd",
|
||||
changeMonth: true,
|
||||
changeYear: true,
|
||||
maxDate: new Date(),
|
||||
yearRange: "-5:+0",
|
||||
onSelect: function (selectedDate) {
|
||||
console.log("End date selected:", selectedDate);
|
||||
$(this).datepicker("hide");
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function addCalendarIcons() {
|
||||
// Remove any existing icons first
|
||||
$(".input-icon").remove();
|
||||
|
||||
// Add calendar icons with just the classes, no inline styles
|
||||
const iconHtml = '<i class="fa fa-calendar input-icon"></i>';
|
||||
|
||||
$("#date_from").after(iconHtml);
|
||||
$("#date_to").after(iconHtml);
|
||||
|
||||
// Ensure parent containers have relative positioning
|
||||
$("#date_from, #date_to")
|
||||
.closest(".form-group")
|
||||
.css("position", "relative");
|
||||
}
|
||||
|
||||
function setupIconClickHandlers() {
|
||||
$(document).on("click", ".input-icon", function () {
|
||||
const input = $(this).prev("input");
|
||||
if (!input.prop("disabled")) {
|
||||
input.datepicker("show");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function setupChangeEventHandlers() {
|
||||
$("#date_from").on("change", function () {
|
||||
const selectedDate = $(this).val();
|
||||
if (selectedDate) {
|
||||
console.log("Start date change event:", selectedDate);
|
||||
enableEndDatePicker(selectedDate);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function initializeDataTable() {
|
||||
console.log("Initializing DataTable...");
|
||||
|
||||
@@ -22,7 +157,7 @@ function initializeDataTable() {
|
||||
}
|
||||
|
||||
// Initialize DataTable
|
||||
var table = $("#mutations-table").DataTable({
|
||||
const table = $("#mutations-table").DataTable({
|
||||
processing: true,
|
||||
serverSide: true,
|
||||
destroy: true,
|
||||
@@ -30,9 +165,17 @@ function initializeDataTable() {
|
||||
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);
|
||||
// Add filter parameters
|
||||
d.dealer_filter = $("#dealer_filter").val();
|
||||
d.date_from = $("#date_from").val();
|
||||
d.date_to = $("#date_to").val();
|
||||
|
||||
console.log("AJAX data being sent:", {
|
||||
dealer_filter: d.dealer_filter,
|
||||
date_from: d.date_from,
|
||||
date_to: d.date_to,
|
||||
});
|
||||
|
||||
return d;
|
||||
},
|
||||
error: function (xhr, error, code) {
|
||||
@@ -41,19 +184,9 @@ function initializeDataTable() {
|
||||
},
|
||||
},
|
||||
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",
|
||||
},
|
||||
{ targets: 0, width: "5%" }, // No. column
|
||||
{ targets: 8, width: "20%", className: "text-center" }, // Action column
|
||||
{ targets: [6, 7], className: "text-center" }, // Total Items and Status columns
|
||||
],
|
||||
columns: [
|
||||
{
|
||||
@@ -67,36 +200,12 @@ function initializeDataTable() {
|
||||
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: "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",
|
||||
@@ -104,13 +213,84 @@ function initializeDataTable() {
|
||||
searchable: false,
|
||||
},
|
||||
],
|
||||
order: [[1, "desc"]], // Order by mutation_number desc (which follows ID order)
|
||||
order: [[1, "desc"]], // Order by mutation_number desc
|
||||
pageLength: 10,
|
||||
responsive: true,
|
||||
ordering: true, // Enable column ordering
|
||||
orderMulti: false, // Single column ordering only
|
||||
ordering: true,
|
||||
orderMulti: false,
|
||||
});
|
||||
|
||||
// Setup filter button handlers
|
||||
setupFilterHandlers(table);
|
||||
|
||||
// Setup other event handlers
|
||||
setupTableEventHandlers(table);
|
||||
}
|
||||
|
||||
function setupFilterHandlers(table) {
|
||||
// Handle Filter Search Button
|
||||
$("#kt_search").on("click", function () {
|
||||
console.log("Filter button clicked");
|
||||
|
||||
const dealerFilter = $("#dealer_filter").val();
|
||||
const dateFrom = $("#date_from").val();
|
||||
const dateTo = $("#date_to").val();
|
||||
|
||||
console.log("Filtering with:", {
|
||||
dealer: dealerFilter,
|
||||
dateFrom,
|
||||
dateTo,
|
||||
});
|
||||
|
||||
table.ajax.reload();
|
||||
});
|
||||
|
||||
// Handle Filter Reset Button
|
||||
$("#kt_reset").on("click", function () {
|
||||
console.log("Reset button clicked");
|
||||
|
||||
// Clear all filters
|
||||
$("#dealer_filter").val("").trigger("change"); // Reset Select2
|
||||
$("#date_from").val("");
|
||||
$("#date_to").val("");
|
||||
|
||||
// Reset end date picker and disable it
|
||||
resetEndDatePicker();
|
||||
|
||||
// Reload table
|
||||
table.ajax.reload();
|
||||
});
|
||||
|
||||
// Handle Enter key on date inputs
|
||||
$("#date_from, #date_to").on("keypress", function (e) {
|
||||
if (e.which === 13) {
|
||||
// Enter key
|
||||
$("#kt_search").click();
|
||||
}
|
||||
});
|
||||
|
||||
// Auto-filter when dealer selection changes
|
||||
$("#dealer_filter").on("change", function () {
|
||||
console.log("Dealer filter changed:", $(this).val());
|
||||
// Uncomment the line below if you want auto-filter on dealer change
|
||||
// table.ajax.reload();
|
||||
});
|
||||
}
|
||||
|
||||
function resetEndDatePicker() {
|
||||
// Destroy existing datepicker
|
||||
$("#date_to").datepicker("destroy");
|
||||
|
||||
// Re-initialize without minDate constraint
|
||||
initializeEndDatePicker();
|
||||
|
||||
// Disable the input
|
||||
$("#date_to").prop("disabled", true);
|
||||
|
||||
console.log("End date picker reset and disabled");
|
||||
}
|
||||
|
||||
function setupTableEventHandlers(table) {
|
||||
// Debug ordering events
|
||||
table.on("order.dt", function () {
|
||||
console.log("Order changed:", table.order());
|
||||
@@ -119,7 +299,7 @@ function initializeDataTable() {
|
||||
// Add loading indicator for ordering
|
||||
table.on("processing.dt", function (e, settings, processing) {
|
||||
if (processing) {
|
||||
console.log("DataTable processing started (ordering/filtering)");
|
||||
console.log("DataTable processing started");
|
||||
} else {
|
||||
console.log("DataTable processing finished");
|
||||
}
|
||||
@@ -127,7 +307,7 @@ function initializeDataTable() {
|
||||
|
||||
// Manual click handler for column headers (fallback)
|
||||
$("#mutations-table thead th").on("click", function () {
|
||||
var columnIndex = $(this).index();
|
||||
const columnIndex = $(this).index();
|
||||
console.log("Column header clicked:", columnIndex, $(this).text());
|
||||
|
||||
// Skip if it's the first (No.) or last (Action) column
|
||||
@@ -152,28 +332,8 @@ function initializeDataTable() {
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
const mutationId = $(this).data("id");
|
||||
handleCancelMutation(mutationId, table);
|
||||
});
|
||||
|
||||
// Handle form submissions with loading state
|
||||
@@ -186,25 +346,53 @@ function initializeDataTable() {
|
||||
|
||||
// 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(
|
||||
'<div class="invalid-feedback">Quantity tidak boleh melebihi yang diminta</div>'
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$(this).removeClass("is-invalid");
|
||||
$(this).siblings(".invalid-feedback").remove();
|
||||
}
|
||||
validateQuantityInput($(this));
|
||||
});
|
||||
}
|
||||
|
||||
function cancelMutation(mutationId) {
|
||||
function handleCancelMutation(mutationId, table) {
|
||||
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, table);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
if (confirm("Apakah Anda yakin ingin membatalkan mutasi ini?")) {
|
||||
cancelMutation(mutationId, table);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function validateQuantityInput(input) {
|
||||
const maxValue = parseFloat(input.attr("max"));
|
||||
const currentValue = parseFloat(input.val());
|
||||
|
||||
if (maxValue && currentValue > maxValue) {
|
||||
input.val(maxValue);
|
||||
input.addClass("is-invalid");
|
||||
|
||||
if (!input.siblings(".invalid-feedback").length) {
|
||||
input.after(
|
||||
'<div class="invalid-feedback">Quantity tidak boleh melebihi yang diminta</div>'
|
||||
);
|
||||
}
|
||||
} else {
|
||||
input.removeClass("is-invalid");
|
||||
input.siblings(".invalid-feedback").remove();
|
||||
}
|
||||
}
|
||||
|
||||
function cancelMutation(mutationId, table) {
|
||||
$.ajax({
|
||||
url: "/warehouse/mutations/" + mutationId + "/cancel",
|
||||
type: "POST",
|
||||
@@ -223,13 +411,14 @@ function cancelMutation(mutationId) {
|
||||
} else {
|
||||
alert("Mutasi berhasil dibatalkan");
|
||||
}
|
||||
// Get table instance
|
||||
var table = $("#mutations-table").DataTable();
|
||||
|
||||
// Reload table
|
||||
table.ajax.reload();
|
||||
},
|
||||
error: function (xhr) {
|
||||
var errorMsg =
|
||||
const errorMsg =
|
||||
xhr.responseJSON?.message || "Gagal membatalkan mutasi";
|
||||
|
||||
if (typeof Swal !== "undefined") {
|
||||
Swal.fire({
|
||||
title: "Error!",
|
||||
|
||||
@@ -1,22 +1,349 @@
|
||||
$.ajaxSetup({
|
||||
headers: {
|
||||
"X-CSRF-TOKEN": $('meta[name="csrf-token"]').attr("content"),
|
||||
},
|
||||
$(document).ready(function () {
|
||||
console.log("Opnames index.js loaded");
|
||||
|
||||
// Check if required libraries are available
|
||||
if (typeof $.fn.DataTable === "undefined") {
|
||||
console.error("DataTables not available!");
|
||||
return;
|
||||
}
|
||||
|
||||
// Initialize components
|
||||
initializeSelect2();
|
||||
initializeDatepickers();
|
||||
|
||||
// Wait for DOM to be fully ready before initializing DataTable
|
||||
setTimeout(function () {
|
||||
initializeDataTable();
|
||||
}, 100);
|
||||
});
|
||||
|
||||
let tableContainer = $("#opnames-table");
|
||||
let url = tableContainer.data("url");
|
||||
let table = $("#opnames-table").DataTable({
|
||||
processing: true,
|
||||
serverSide: true,
|
||||
ajax: url,
|
||||
order: [[0, "desc"]],
|
||||
columns: [
|
||||
{ data: "created_at", name: "created_at", visible: false },
|
||||
{ data: "opname_date", name: "opname_date" },
|
||||
{ data: "dealer_name", name: "dealer.name" },
|
||||
{ data: "user_name", name: "user.name" },
|
||||
{ data: "status", name: "status" },
|
||||
{ data: "action", name: "action", orderable: false, searchable: false },
|
||||
],
|
||||
});
|
||||
/**
|
||||
* Initialize Select2 for dealer filter
|
||||
*/
|
||||
function initializeSelect2() {
|
||||
console.log("Initializing Select2...");
|
||||
|
||||
if (typeof $.fn.select2 !== "undefined") {
|
||||
$("#dealer_filter").select2({
|
||||
placeholder: "Pilih Dealer",
|
||||
allowClear: false,
|
||||
width: "100%",
|
||||
dropdownAutoWidth: true,
|
||||
minimumResultsForSearch: 5, // Show search box if more than 5 options
|
||||
});
|
||||
} else {
|
||||
console.warn("Select2 not available, using regular select");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize date pickers with validation
|
||||
*/
|
||||
function initializeDatepickers() {
|
||||
console.log("Initializing datepickers...");
|
||||
|
||||
// Initialize start date picker
|
||||
$("#date_from").datepicker({
|
||||
dateFormat: "yy-mm-dd",
|
||||
changeMonth: true,
|
||||
changeYear: true,
|
||||
maxDate: new Date(),
|
||||
yearRange: "-5:+0",
|
||||
onSelect: function (selectedDate) {
|
||||
console.log("Start date selected:", selectedDate);
|
||||
enableEndDatePicker(selectedDate);
|
||||
$(this).datepicker("hide");
|
||||
},
|
||||
onClose: function (selectedDate) {
|
||||
if (selectedDate) {
|
||||
console.log("Start date closed with value:", selectedDate);
|
||||
enableEndDatePicker(selectedDate);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
// Initialize end date picker (initially disabled)
|
||||
initializeEndDatePicker();
|
||||
|
||||
// Initially disable end date input
|
||||
$("#date_to").prop("disabled", true);
|
||||
|
||||
// Add calendar icons
|
||||
addCalendarIcons();
|
||||
|
||||
// Setup calendar icon click handlers
|
||||
setupIconClickHandlers();
|
||||
|
||||
// Setup change event handlers as backup
|
||||
setupChangeEventHandlers();
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable end date picker with minimum date constraint
|
||||
*/
|
||||
function enableEndDatePicker(startDate) {
|
||||
console.log("Enabling end date picker with min date:", startDate);
|
||||
|
||||
// Enable the input
|
||||
$("#date_to").prop("disabled", false);
|
||||
|
||||
// Destroy existing datepicker
|
||||
$("#date_to").datepicker("destroy");
|
||||
|
||||
// Re-initialize with new minDate
|
||||
$("#date_to").datepicker({
|
||||
dateFormat: "yy-mm-dd",
|
||||
changeMonth: true,
|
||||
changeYear: true,
|
||||
maxDate: new Date(),
|
||||
yearRange: "-5:+0",
|
||||
minDate: new Date(startDate), // Convert to Date object for proper comparison
|
||||
onSelect: function (selectedDate) {
|
||||
console.log("End date selected:", selectedDate);
|
||||
$(this).datepicker("hide");
|
||||
},
|
||||
});
|
||||
|
||||
console.log("End date picker enabled with minDate:", startDate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize end date picker without constraints
|
||||
*/
|
||||
function initializeEndDatePicker() {
|
||||
$("#date_to").datepicker({
|
||||
dateFormat: "yy-mm-dd",
|
||||
changeMonth: true,
|
||||
changeYear: true,
|
||||
maxDate: new Date(),
|
||||
yearRange: "-5:+0",
|
||||
onSelect: function (selectedDate) {
|
||||
console.log("End date selected:", selectedDate);
|
||||
$(this).datepicker("hide");
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Add calendar icons to date inputs
|
||||
*/
|
||||
function addCalendarIcons() {
|
||||
// Remove any existing icons first
|
||||
$(".input-icon").remove();
|
||||
|
||||
// Add calendar icons with CSS classes
|
||||
const iconHtml = '<i class="fa fa-calendar input-icon"></i>';
|
||||
|
||||
$("#date_from").after(iconHtml);
|
||||
$("#date_to").after(iconHtml);
|
||||
|
||||
// Ensure parent containers have relative positioning
|
||||
$("#date_from, #date_to")
|
||||
.closest(".form-group")
|
||||
.css("position", "relative");
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup click handlers for calendar icons
|
||||
*/
|
||||
function setupIconClickHandlers() {
|
||||
$(document).on("click", ".input-icon", function () {
|
||||
const input = $(this).prev("input");
|
||||
if (!input.prop("disabled")) {
|
||||
input.datepicker("show");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup change event handlers for date inputs
|
||||
*/
|
||||
function setupChangeEventHandlers() {
|
||||
$("#date_from").on("change", function () {
|
||||
const selectedDate = $(this).val();
|
||||
if (selectedDate) {
|
||||
console.log("Start date change event:", selectedDate);
|
||||
enableEndDatePicker(selectedDate);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize DataTable with server-side processing and filtering
|
||||
*/
|
||||
function initializeDataTable() {
|
||||
console.log("Initializing DataTable...");
|
||||
|
||||
// Destroy existing table if any
|
||||
if ($.fn.DataTable.isDataTable("#opnames-table")) {
|
||||
$("#opnames-table").DataTable().destroy();
|
||||
}
|
||||
|
||||
// Initialize DataTable
|
||||
const table = $("#opnames-table").DataTable({
|
||||
processing: true,
|
||||
serverSide: true,
|
||||
destroy: true,
|
||||
ajax: {
|
||||
url: $("#opnames-table").data("url"),
|
||||
type: "GET",
|
||||
data: function (d) {
|
||||
// Add filter parameters
|
||||
d.dealer_filter = $("#dealer_filter").val();
|
||||
d.date_from = $("#date_from").val();
|
||||
d.date_to = $("#date_to").val();
|
||||
|
||||
console.log("AJAX data being sent:", {
|
||||
dealer_filter: d.dealer_filter,
|
||||
date_from: d.date_from,
|
||||
date_to: d.date_to,
|
||||
});
|
||||
|
||||
return d;
|
||||
},
|
||||
error: function (xhr, error, code) {
|
||||
console.error("DataTables AJAX error:", error, code);
|
||||
console.error("Response:", xhr.responseText);
|
||||
},
|
||||
},
|
||||
columnDefs: [
|
||||
{ targets: 0, width: "15%" }, // Opname Date column
|
||||
{ targets: 5, width: "15%", className: "text-center" }, // Action column
|
||||
],
|
||||
columns: [
|
||||
{
|
||||
data: "created_at",
|
||||
name: "created_at",
|
||||
orderable: true,
|
||||
},
|
||||
{
|
||||
data: "opname_date",
|
||||
name: "opname_date",
|
||||
orderable: true,
|
||||
},
|
||||
{
|
||||
data: "dealer_name",
|
||||
name: "dealer.name",
|
||||
orderable: true,
|
||||
},
|
||||
{
|
||||
data: "user_name",
|
||||
name: "user.name",
|
||||
orderable: true,
|
||||
},
|
||||
{
|
||||
data: "status",
|
||||
name: "status",
|
||||
orderable: true,
|
||||
},
|
||||
{
|
||||
data: "action",
|
||||
name: "action",
|
||||
orderable: false,
|
||||
searchable: false,
|
||||
},
|
||||
],
|
||||
order: [[4, "desc"]], // Order by created_at desc
|
||||
pageLength: 10,
|
||||
responsive: true,
|
||||
ordering: true,
|
||||
orderMulti: false,
|
||||
});
|
||||
|
||||
// Setup filter button handlers
|
||||
setupFilterHandlers(table);
|
||||
|
||||
// Setup other event handlers
|
||||
setupTableEventHandlers(table);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup filter and reset button handlers
|
||||
*/
|
||||
function setupFilterHandlers(table) {
|
||||
// Handle Filter Search Button
|
||||
$("#kt_search").on("click", function () {
|
||||
console.log("Filter button clicked");
|
||||
|
||||
const dealerFilter = $("#dealer_filter").val();
|
||||
const dateFrom = $("#date_from").val();
|
||||
const dateTo = $("#date_to").val();
|
||||
|
||||
console.log("Filtering with:", {
|
||||
dealer: dealerFilter,
|
||||
dateFrom: dateFrom,
|
||||
dateTo: dateTo,
|
||||
});
|
||||
|
||||
table.ajax.reload();
|
||||
});
|
||||
|
||||
// Handle Filter Reset Button
|
||||
$("#kt_reset").on("click", function () {
|
||||
console.log("Reset button clicked");
|
||||
|
||||
// Clear all filters
|
||||
$("#dealer_filter").val("").trigger("change"); // Reset Select2
|
||||
$("#date_from").val("");
|
||||
$("#date_to").val("");
|
||||
|
||||
// Reset end date picker and disable it
|
||||
resetEndDatePicker();
|
||||
|
||||
// Reload table
|
||||
table.ajax.reload();
|
||||
});
|
||||
|
||||
// Handle Enter key on date inputs
|
||||
$("#date_from, #date_to").on("keypress", function (e) {
|
||||
if (e.which === 13) {
|
||||
// Enter key
|
||||
$("#kt_search").click();
|
||||
}
|
||||
});
|
||||
|
||||
// Optional: Auto-filter when dealer selection changes
|
||||
$("#dealer_filter").on("change", function () {
|
||||
console.log("Dealer filter changed:", $(this).val());
|
||||
// Uncomment the line below if you want auto-filter on dealer change
|
||||
// table.ajax.reload();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset end date picker to initial state
|
||||
*/
|
||||
function resetEndDatePicker() {
|
||||
// Destroy existing datepicker
|
||||
$("#date_to").datepicker("destroy");
|
||||
|
||||
// Re-initialize without minDate constraint
|
||||
initializeEndDatePicker();
|
||||
|
||||
// Disable the input
|
||||
$("#date_to").prop("disabled", true);
|
||||
|
||||
console.log("End date picker reset and disabled");
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup additional table event handlers
|
||||
*/
|
||||
function setupTableEventHandlers(table) {
|
||||
// Debug ordering events
|
||||
table.on("order.dt", function () {
|
||||
console.log("Order changed:", table.order());
|
||||
});
|
||||
|
||||
// Add loading indicator for processing
|
||||
table.on("processing.dt", function (e, settings, processing) {
|
||||
if (processing) {
|
||||
console.log("DataTable processing started");
|
||||
} else {
|
||||
console.log("DataTable processing finished");
|
||||
}
|
||||
});
|
||||
|
||||
// Handle any custom button clicks here if needed
|
||||
// Example: $(document).on('click', '.custom-btn', function() { ... });
|
||||
}
|
||||
|
||||
@@ -25,6 +25,45 @@
|
||||
</div>
|
||||
|
||||
<div class="kt-portlet__body">
|
||||
<!-- Filter Section -->
|
||||
<div class="kt-form kt-form--label-right kt-margin-b-10">
|
||||
<div class="row align-items-end">
|
||||
<div class="col-md-2">
|
||||
<div class="form-group mb-0">
|
||||
<label class="form-label">Tanggal Awal</label>
|
||||
<input type="text" class="form-control" id="date_from" name="date_from" placeholder="Tanggal awal" readonly>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<div class="form-group mb-0">
|
||||
<label class="form-label">Tanggal Akhir</label>
|
||||
<input type="text" class="form-control" id="date_to" name="date_to" placeholder="Tanggal akhir" readonly>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="form-group mb-0">
|
||||
<label class="form-label">Dealer</label>
|
||||
<select class="form-control select2" id="dealer_filter" name="dealer_filter">
|
||||
<option value="">Pilih Dealer</option>
|
||||
@foreach($dealers as $dealer)
|
||||
<option value="{{ $dealer->id }}">{{ $dealer->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="form-group mb-0">
|
||||
<button type="button" class="btn btn-brand btn-bold mr-2" id="kt_search">
|
||||
<span>Filter</span>
|
||||
</button>
|
||||
<button type="button" class="btn btn-secondary btn-bold" id="kt_reset">
|
||||
<span>Reset</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="table-responsive">
|
||||
<!--begin: Datatable -->
|
||||
<table class="table table-striped table-bordered table-hover" id="mutations-table" data-url="{{ route('mutations.index') }}">
|
||||
@@ -130,6 +169,249 @@ table.dataTable thead .sorting_desc:before {
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
/* Filter section styling */
|
||||
.form-label {
|
||||
font-weight: 600;
|
||||
color: #595d6e;
|
||||
margin-bottom: 5px;
|
||||
font-size: 12px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
.form-group.mb-0 {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
|
||||
/* Date input container styling */
|
||||
.form-group {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* Input styling for date fields */
|
||||
#date_from, #date_to {
|
||||
padding-right: 40px; /* Make space for icon */
|
||||
}
|
||||
|
||||
/* Date picker icon styling */
|
||||
.input-icon {
|
||||
position: absolute;
|
||||
right: 12px;
|
||||
bottom: 9px; /* Position from bottom to align with input field */
|
||||
cursor: pointer;
|
||||
color: #74788d;
|
||||
z-index: 5;
|
||||
font-size: 14px;
|
||||
pointer-events: auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.input-icon:hover {
|
||||
color: #5d78ff;
|
||||
}
|
||||
|
||||
/* Disabled input styling */
|
||||
input[disabled] {
|
||||
background-color: #f8f9fa !important;
|
||||
color: #6c757d !important;
|
||||
cursor: not-allowed !important;
|
||||
opacity: 0.65;
|
||||
}
|
||||
|
||||
input[disabled] + .input-icon {
|
||||
color: #ccc !important;
|
||||
cursor: not-allowed !important;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
/* Ensure Select2 container doesn't have conflicting padding */
|
||||
.select2-container .select2-selection--single .form-control {
|
||||
padding-right: 12px !important;
|
||||
}
|
||||
|
||||
/* Select2 styling */
|
||||
.select2-container {
|
||||
z-index: 9999;
|
||||
}
|
||||
|
||||
.select2-container--default .select2-selection--single {
|
||||
height: 38px;
|
||||
border: 1px solid #e2e5ec;
|
||||
border-radius: 4px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.select2-container--default .select2-selection--single .select2-selection__rendered {
|
||||
line-height: 36px;
|
||||
padding-left: 12px;
|
||||
padding-right: 30px; /* Make space for dropdown arrow */
|
||||
color: #74788d;
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.select2-container--default .select2-selection--single .select2-selection__placeholder {
|
||||
color: #74788d;
|
||||
line-height: 36px;
|
||||
}
|
||||
|
||||
/* Dropdown arrow styling */
|
||||
.select2-container--default .select2-selection--single .select2-selection__arrow {
|
||||
height: 36px;
|
||||
right: 8px;
|
||||
top: 1px;
|
||||
width: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.select2-container--default .select2-selection--single .select2-selection__arrow b {
|
||||
border-color: #74788d transparent transparent transparent;
|
||||
border-style: solid;
|
||||
border-width: 5px 4px 0 4px;
|
||||
height: 0;
|
||||
left: 50%;
|
||||
margin-left: -4px;
|
||||
margin-top: -2px;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
width: 0;
|
||||
}
|
||||
|
||||
/* Hide clear button (×) completely */
|
||||
.select2-container--default .select2-selection--single .select2-selection__clear {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* Dropdown styling */
|
||||
.select2-dropdown {
|
||||
border: 1px solid #e2e5ec;
|
||||
border-radius: 4px;
|
||||
z-index: 9999 !important;
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.15);
|
||||
}
|
||||
|
||||
/* Ensure dropdown container has proper positioning */
|
||||
.select2-container--open {
|
||||
z-index: 9999 !important;
|
||||
}
|
||||
|
||||
.select2-container--open .select2-dropdown {
|
||||
z-index: 9999 !important;
|
||||
}
|
||||
|
||||
.select2-results__option {
|
||||
padding: 8px 12px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.select2-results__option--highlighted {
|
||||
background-color: #5d78ff;
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* Focus states */
|
||||
.select2-container--default.select2-container--focus .select2-selection--single {
|
||||
border-color: #5d78ff;
|
||||
outline: 0;
|
||||
box-shadow: 0 0 0 0.2rem rgba(93, 120, 255, 0.25);
|
||||
}
|
||||
|
||||
/* Custom datepicker styles */
|
||||
.ui-datepicker {
|
||||
background: #fff;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
|
||||
font-size: 13px;
|
||||
z-index: 9999 !important;
|
||||
}
|
||||
|
||||
.ui-datepicker-header {
|
||||
background: #f8f9fa;
|
||||
border-bottom: 1px solid #dee2e6;
|
||||
padding: 10px;
|
||||
border-radius: 4px 4px 0 0;
|
||||
}
|
||||
|
||||
.ui-datepicker-title {
|
||||
font-weight: 600;
|
||||
color: #495057;
|
||||
}
|
||||
|
||||
.ui-datepicker-calendar {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.ui-datepicker-calendar td {
|
||||
padding: 5px;
|
||||
text-align: center;
|
||||
border: 1px solid #f8f9fa;
|
||||
}
|
||||
|
||||
.ui-datepicker-calendar td a {
|
||||
display: block;
|
||||
padding: 8px;
|
||||
text-decoration: none;
|
||||
color: #495057;
|
||||
border-radius: 3px;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.ui-datepicker-calendar td a:hover {
|
||||
background: #e9ecef;
|
||||
color: #212529;
|
||||
}
|
||||
|
||||
.ui-datepicker-calendar .ui-datepicker-today a {
|
||||
background: #007bff;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.ui-datepicker-calendar .ui-datepicker-current-day a {
|
||||
background: #28a745;
|
||||
color: white;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.row.align-items-end {
|
||||
align-items: stretch !important;
|
||||
}
|
||||
|
||||
.col-md-2, .col-md-4 {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.form-label {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.ui-datepicker {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 576px) {
|
||||
.col-md-4:last-child .form-group {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.col-md-4:last-child .btn {
|
||||
width: 45%;
|
||||
margin: 0 2.5%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@endsection
|
||||
|
||||
|
||||
@@ -23,26 +23,307 @@
|
||||
</div>
|
||||
|
||||
<div class="kt-portlet__body">
|
||||
<div class="table-responsive">
|
||||
<!--begin: Datatable -->
|
||||
<table class="table table-striped table-bordered table-hover" id="opnames-table" data-url="{{ route('opnames.index') }}">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Waktu Dibuat</th>
|
||||
<th>Tanggal Opname</th>
|
||||
<th>Dealer</th>
|
||||
<th>Pengguna</th>
|
||||
<th>Status</th>
|
||||
<th>Aksi</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
<!--end: Datatable -->
|
||||
</div>
|
||||
<!-- Filter Section -->
|
||||
<div class="kt-form kt-form--label-right kt-margin-b-10">
|
||||
<div class="row align-items-end">
|
||||
<div class="col-md-2">
|
||||
<div class="form-group mb-0">
|
||||
<label class="form-label">Tanggal Awal</label>
|
||||
<input type="text" class="form-control" id="date_from" name="date_from" placeholder="Tanggal awal" readonly>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<div class="form-group mb-0">
|
||||
<label class="form-label">Tanggal Akhir</label>
|
||||
<input type="text" class="form-control" id="date_to" name="date_to" placeholder="Tanggal akhir" readonly>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="form-group mb-0">
|
||||
<label class="form-label">Dealer</label>
|
||||
<select class="form-control select2" id="dealer_filter" name="dealer_filter">
|
||||
<option value="">Pilih Dealer</option>
|
||||
@foreach($dealers as $dealer)
|
||||
<option value="{{ $dealer->id }}">{{ $dealer->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="form-group mb-0">
|
||||
<button type="button" class="btn btn-brand btn-bold mr-2" id="kt_search">
|
||||
<span>Filter</span>
|
||||
</button>
|
||||
<button type="button" class="btn btn-secondary btn-bold" id="kt_reset">
|
||||
<span>Reset</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-responsive">
|
||||
<!--begin: Datatable -->
|
||||
<table class="table table-striped table-bordered table-hover" id="opnames-table" data-url="{{ route('opnames.index') }}">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Waktu Dibuat</th>
|
||||
<th>Tanggal Opname</th>
|
||||
<th>Dealer</th>
|
||||
<th>Pengguna</th>
|
||||
<th>Status</th>
|
||||
<th>Aksi</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
<!--end: Datatable -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@section('styles')
|
||||
<style>
|
||||
/* Filter section styling */
|
||||
.form-label {
|
||||
font-weight: 600;
|
||||
color: #595d6e;
|
||||
margin-bottom: 5px;
|
||||
font-size: 12px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
.form-group.mb-0 {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
|
||||
/* Date input container styling */
|
||||
.form-group {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* Input styling for date fields */
|
||||
#date_from, #date_to {
|
||||
padding-right: 40px; /* Make space for icon */
|
||||
}
|
||||
|
||||
/* Date picker icon styling */
|
||||
.input-icon {
|
||||
position: absolute;
|
||||
right: 12px;
|
||||
bottom: 9px; /* Position from bottom to align with input field */
|
||||
cursor: pointer;
|
||||
color: #74788d;
|
||||
z-index: 5;
|
||||
font-size: 14px;
|
||||
pointer-events: auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.input-icon:hover {
|
||||
color: #5d78ff;
|
||||
}
|
||||
|
||||
/* Disabled input styling */
|
||||
input[disabled] {
|
||||
background-color: #f8f9fa !important;
|
||||
color: #6c757d !important;
|
||||
cursor: not-allowed !important;
|
||||
opacity: 0.65;
|
||||
}
|
||||
|
||||
input[disabled] + .input-icon {
|
||||
color: #ccc !important;
|
||||
cursor: not-allowed !important;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
/* Select2 styling */
|
||||
.select2-container {
|
||||
z-index: 9999;
|
||||
}
|
||||
|
||||
.select2-container--default .select2-selection--single {
|
||||
height: 38px;
|
||||
border: 1px solid #e2e5ec;
|
||||
border-radius: 4px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.select2-container--default .select2-selection--single .select2-selection__rendered {
|
||||
line-height: 36px;
|
||||
padding-left: 12px;
|
||||
padding-right: 30px; /* Make space for dropdown arrow */
|
||||
color: #74788d;
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
max-width: calc(100% - 30px); /* Ensure text doesn't overlap with arrow */
|
||||
}
|
||||
|
||||
.select2-container--default .select2-selection--single .select2-selection__placeholder {
|
||||
color: #74788d;
|
||||
line-height: 36px;
|
||||
}
|
||||
|
||||
/* Dropdown arrow styling */
|
||||
.select2-container--default .select2-selection--single .select2-selection__arrow {
|
||||
height: 36px;
|
||||
right: 8px;
|
||||
top: 1px;
|
||||
width: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.select2-container--default .select2-selection--single .select2-selection__arrow b {
|
||||
border-color: #74788d transparent transparent transparent;
|
||||
border-style: solid;
|
||||
border-width: 5px 4px 0 4px;
|
||||
height: 0;
|
||||
left: 50%;
|
||||
margin-left: -4px;
|
||||
margin-top: -2px;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
width: 0;
|
||||
}
|
||||
|
||||
/* Hide clear button (×) completely */
|
||||
.select2-container--default .select2-selection--single .select2-selection__clear {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* Dropdown styling */
|
||||
.select2-dropdown {
|
||||
border: 1px solid #e2e5ec;
|
||||
border-radius: 4px;
|
||||
z-index: 9999 !important;
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.15);
|
||||
}
|
||||
|
||||
/* Ensure dropdown container has proper positioning */
|
||||
.select2-container--open {
|
||||
z-index: 9999 !important;
|
||||
}
|
||||
|
||||
.select2-container--open .select2-dropdown {
|
||||
z-index: 9999 !important;
|
||||
}
|
||||
|
||||
.select2-results__option {
|
||||
padding: 8px 12px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.select2-results__option--highlighted {
|
||||
background-color: #5d78ff;
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* Focus states */
|
||||
.select2-container--default.select2-container--focus .select2-selection--single {
|
||||
border-color: #5d78ff;
|
||||
outline: 0;
|
||||
box-shadow: 0 0 0 0.2rem rgba(93, 120, 255, 0.25);
|
||||
}
|
||||
|
||||
/* Custom datepicker styles */
|
||||
.ui-datepicker {
|
||||
background: #fff;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
|
||||
font-size: 13px;
|
||||
z-index: 9999 !important;
|
||||
}
|
||||
|
||||
.ui-datepicker-header {
|
||||
background: #f8f9fa;
|
||||
border-bottom: 1px solid #dee2e6;
|
||||
padding: 10px;
|
||||
border-radius: 4px 4px 0 0;
|
||||
}
|
||||
|
||||
.ui-datepicker-title {
|
||||
font-weight: 600;
|
||||
color: #495057;
|
||||
}
|
||||
|
||||
.ui-datepicker-calendar {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.ui-datepicker-calendar td {
|
||||
padding: 5px;
|
||||
text-align: center;
|
||||
border: 1px solid #f8f9fa;
|
||||
}
|
||||
|
||||
.ui-datepicker-calendar td a {
|
||||
display: block;
|
||||
padding: 8px;
|
||||
text-decoration: none;
|
||||
color: #495057;
|
||||
border-radius: 3px;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.ui-datepicker-calendar td a:hover {
|
||||
background: #e9ecef;
|
||||
color: #212529;
|
||||
}
|
||||
|
||||
.ui-datepicker-calendar .ui-datepicker-today a {
|
||||
background: #007bff;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.ui-datepicker-calendar .ui-datepicker-current-day a {
|
||||
background: #28a745;
|
||||
color: white;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.row.align-items-end {
|
||||
align-items: stretch !important;
|
||||
}
|
||||
|
||||
.col-md-2, .col-md-4 {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.form-label {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.ui-datepicker {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 576px) {
|
||||
.col-md-4:last-child .form-group {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.col-md-4:last-child .btn {
|
||||
width: 45%;
|
||||
margin: 0 2.5%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@endsection
|
||||
|
||||
@section('javascripts')
|
||||
<script src="{{ mix('js/warehouse_management/opnames/index.js') }}"></script>
|
||||
@endsection
|
||||
Reference in New Issue
Block a user