Fix(CSS): Remove overflow hidden from Date Filter to show dropdown
This commit is contained in:
parent
786df69fa7
commit
2d3c1bc4df
@ -26,10 +26,11 @@ h1, h2, h3, h4, h5, h6 {
|
|||||||
flex-direction: row !important;
|
flex-direction: row !important;
|
||||||
align-items: center !important;
|
align-items: center !important;
|
||||||
justify-content: space-between !important;
|
justify-content: space-between !important;
|
||||||
|
flex-wrap: nowrap !important; /* Ensure they stay on one line */
|
||||||
gap: 2px !important;
|
gap: 2px !important;
|
||||||
width: 100% !important;
|
width: 100% !important;
|
||||||
box-sizing: border-box !important;
|
box-sizing: border-box !important;
|
||||||
overflow: hidden !important; /* Prevent wrapping overflow */
|
/* overflow: hidden; Removed to allow dropdown list to show */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Hide any stray shortcuts that might have survived JS cleanup */
|
/* Hide any stray shortcuts that might have survived JS cleanup */
|
||||||
|
|||||||
@ -20,6 +20,63 @@ h1, h2, h3, h4, h5, h6 {
|
|||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* --- Masar Date Filter Row (Dynamic Wrapper) --- */
|
||||||
|
.masar-date-filter-row {
|
||||||
|
display: flex !important;
|
||||||
|
flex-direction: row !important;
|
||||||
|
align-items: center !important;
|
||||||
|
justify-content: space-between !important;
|
||||||
|
flex-wrap: nowrap !important; /* Ensure they stay on one line */
|
||||||
|
gap: 2px !important;
|
||||||
|
width: 100% !important;
|
||||||
|
box-sizing: border-box !important;
|
||||||
|
/* overflow: hidden; Removed to allow dropdown list to show */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hide any stray shortcuts that might have survived JS cleanup */
|
||||||
|
.masar-date-filter-row .datetimeshortcuts {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.masar-date-filter-row select {
|
||||||
|
width: 32% !important;
|
||||||
|
min-width: 0 !important;
|
||||||
|
font-size: 11px !important;
|
||||||
|
padding: 0 2px !important;
|
||||||
|
height: 28px !important;
|
||||||
|
line-height: 1 !important;
|
||||||
|
box-sizing: border-box !important;
|
||||||
|
margin: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.masar-date-filter-row input {
|
||||||
|
width: 33% !important;
|
||||||
|
min-width: 0 !important;
|
||||||
|
font-size: 11px !important;
|
||||||
|
padding: 0 2px !important;
|
||||||
|
height: 28px !important;
|
||||||
|
margin: 0 !important;
|
||||||
|
box-sizing: border-box !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Specific fix for date inputs to ensure they look clean */
|
||||||
|
.masar-date-filter-row input[type="date"] {
|
||||||
|
-webkit-appearance: none; /* Remove some browser defaults */
|
||||||
|
appearance: none;
|
||||||
|
line-height: 28px;
|
||||||
|
}
|
||||||
|
.masar-date-filter-row input[type="date"]::-webkit-inner-spin-button,
|
||||||
|
.masar-date-filter-row input[type="date"]::-webkit-calendar-picker-indicator {
|
||||||
|
/* Make the calendar icon smaller and fit */
|
||||||
|
width: 12px;
|
||||||
|
height: 12px;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* --- Other Admin Tweaks --- */
|
||||||
.hero-section {
|
.hero-section {
|
||||||
background: linear-gradient(135deg, var(--primary-dark) 0%, #2D2D30 100%);
|
background: linear-gradient(135deg, var(--primary-dark) 0%, #2D2D30 100%);
|
||||||
padding: 100px 0;
|
padding: 100px 0;
|
||||||
@ -28,18 +85,6 @@ h1, h2, h3, h4, h5, h6 {
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hero-section::before {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
top: -50px;
|
|
||||||
right: -50px;
|
|
||||||
width: 200px;
|
|
||||||
height: 200px;
|
|
||||||
background: var(--accent-orange);
|
|
||||||
filter: blur(80px);
|
|
||||||
opacity: 0.2;
|
|
||||||
}
|
|
||||||
|
|
||||||
.glass-card {
|
.glass-card {
|
||||||
background: rgba(255, 255, 255, 0.05);
|
background: rgba(255, 255, 255, 0.05);
|
||||||
backdrop-filter: blur(15px);
|
backdrop-filter: blur(15px);
|
||||||
@ -65,46 +110,6 @@ h1, h2, h3, h4, h5, h6 {
|
|||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tracking-input {
|
|
||||||
background: rgba(255, 255, 255, 0.1);
|
|
||||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
|
||||||
color: white;
|
|
||||||
border-radius: 12px 0 0 12px;
|
|
||||||
padding: 15px 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tracking-input:focus {
|
|
||||||
background: rgba(255, 255, 255, 0.15);
|
|
||||||
border-color: var(--accent-orange);
|
|
||||||
box-shadow: none;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.feature-icon {
|
|
||||||
width: 60px;
|
|
||||||
height: 60px;
|
|
||||||
background: var(--accent-orange);
|
|
||||||
border-radius: 15px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
color: white;
|
|
||||||
font-size: 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.parcel-status-badge {
|
|
||||||
padding: 8px 16px;
|
|
||||||
border-radius: 50px;
|
|
||||||
font-size: 14px;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
.status-pending { background: #FFE8CC; color: #D9480F; }
|
|
||||||
.status-picked_up { background: #E3FAFC; color: #0B7285; }
|
|
||||||
.status-in_transit { background: #E7F5FF; color: #1864AB; }
|
|
||||||
.status-delivered { background: #EBFBEE; color: #2B8A3E; }
|
|
||||||
|
|
||||||
/* Chat Widget */
|
/* Chat Widget */
|
||||||
#masar-chat-widget {
|
#masar-chat-widget {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
@ -132,10 +137,6 @@ h1, h2, h3, h4, h5, h6 {
|
|||||||
transition: transform 0.2s;
|
transition: transform 0.2s;
|
||||||
}
|
}
|
||||||
|
|
||||||
#masar-chat-toggle:hover {
|
|
||||||
transform: scale(1.05);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* RTL Support for Chat */
|
/* RTL Support for Chat */
|
||||||
[dir="rtl"] #masar-chat-widget {
|
[dir="rtl"] #masar-chat-widget {
|
||||||
right: auto;
|
right: auto;
|
||||||
@ -146,146 +147,14 @@ h1, h2, h3, h4, h5, h6 {
|
|||||||
left: 20px;
|
left: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.typing-dots span {
|
|
||||||
display: inline-block;
|
|
||||||
width: 8px;
|
|
||||||
height: 8px;
|
|
||||||
background-color: #adb5bd;
|
|
||||||
border-radius: 50%;
|
|
||||||
margin: 0 2px;
|
|
||||||
animation: typing 1s infinite;
|
|
||||||
}
|
|
||||||
.typing-dots span:nth-child(2) { animation-delay: 0.2s; }
|
|
||||||
.typing-dots span:nth-child(3) { animation-delay: 0.4s; }
|
|
||||||
|
|
||||||
@keyframes typing {
|
|
||||||
0%, 100% { transform: translateY(0); }
|
|
||||||
50% { transform: translateY(-5px); }
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --- Admin Panel Customizations --- */
|
|
||||||
|
|
||||||
/* Fix: Prevent accidental file dialog open when clicking labels for logos/favicons */
|
|
||||||
body.model-platformprofile label[for="id_logo"],
|
|
||||||
body.model-platformprofile label[for="id_favicon"],
|
|
||||||
body.model-platformprofile label[for="id_admin_panel_logo"] {
|
|
||||||
pointer-events: none;
|
|
||||||
cursor: default;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Improve Admin Form Spacing */
|
|
||||||
.form-row {
|
|
||||||
padding: 15px 10px;
|
|
||||||
border-bottom: 1px solid #f0f0f0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --- Fix Admin Search Box & Filter Layout --- */
|
|
||||||
|
|
||||||
/* Target the search form container in Jazzmin/AdminLTE */
|
|
||||||
#changelist-search .input-group {
|
|
||||||
display: flex !important;
|
|
||||||
flex-wrap: nowrap !important;
|
|
||||||
max-width: 300px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Make the input field take available space */
|
|
||||||
#changelist-search input[type="text"] {
|
|
||||||
flex-grow: 1 !important;
|
|
||||||
width: auto !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Ensure the button stays inline */
|
|
||||||
#changelist-search button[type="submit"],
|
|
||||||
#changelist-search .btn {
|
|
||||||
white-space: nowrap !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Force filters to sit nicely in a row */
|
|
||||||
.filter-wrapper .form-group,
|
|
||||||
.filter-wrapper select,
|
|
||||||
.filter-wrapper .select2-container {
|
|
||||||
margin-bottom: 0 !important;
|
|
||||||
display: inline-block !important;
|
|
||||||
width: auto !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --- Date Range Filter Styling (Compact & Horizontal) --- */
|
|
||||||
|
|
||||||
/* The dropdown we injected */
|
|
||||||
.admin-date-dropdown {
|
|
||||||
width: auto !important;
|
|
||||||
min-width: 120px;
|
|
||||||
display: inline-block !important;
|
|
||||||
margin-bottom: 5px; /* Spacing if it wraps */
|
|
||||||
margin-left: 5px; /* Spacing for RTL (since we use float/flex) */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The container of inputs (From/To) */
|
|
||||||
.admindatefilter .controls.date-filter-controls {
|
|
||||||
display: inline-flex !important;
|
|
||||||
align-items: center !important;
|
|
||||||
flex-wrap: nowrap !important;
|
|
||||||
gap: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The actual date inputs */
|
|
||||||
.admindatefilter .date-input {
|
|
||||||
width: 90px !important; /* Force small width */
|
|
||||||
padding: 0.25rem 0.5rem;
|
|
||||||
font-size: 0.875rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Ensure the whole filter block flows nicely if possible */
|
|
||||||
.admindatefilter {
|
|
||||||
display: block; /* Default block in sidebar */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If filters are in a horizontal top bar (Jazzmin tweaks), ensure they flow */
|
|
||||||
.filter-wrapper .admindatefilter {
|
|
||||||
display: inline-block !important;
|
|
||||||
vertical-align: top;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --- Search Box RTL/LTR Border Radius Handling --- */
|
|
||||||
|
|
||||||
/* LTR (Default) */
|
|
||||||
.masar-search-input {
|
|
||||||
border-top-right-radius: 0;
|
|
||||||
border-bottom-right-radius: 0;
|
|
||||||
}
|
|
||||||
.masar-search-btn {
|
|
||||||
border-top-left-radius: 0;
|
|
||||||
border-bottom-left-radius: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* RTL Override for Search Box */
|
|
||||||
[dir="rtl"] .masar-search-input {
|
|
||||||
border-top-right-radius: 0.25rem !important;
|
|
||||||
border-bottom-right-radius: 0.25rem !important;
|
|
||||||
border-top-left-radius: 0 !important;
|
|
||||||
border-bottom-left-radius: 0 !important;
|
|
||||||
}
|
|
||||||
[dir="rtl"] .masar-search-btn {
|
|
||||||
border-top-left-radius: 0.25rem !important;
|
|
||||||
border-bottom-left-radius: 0.25rem !important;
|
|
||||||
border-top-right-radius: 0 !important;
|
|
||||||
border-bottom-right-radius: 0 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --- Admin Panel RTL Sidebar Override (Agresive) --- */
|
/* --- Admin Panel RTL Sidebar Override (Agresive) --- */
|
||||||
|
|
||||||
/* We use [dir="rtl"] selector which should be on html tag */
|
|
||||||
|
|
||||||
@media (min-width: 992px) {
|
@media (min-width: 992px) {
|
||||||
/* Main Sidebar */
|
|
||||||
[dir="rtl"] .main-sidebar {
|
[dir="rtl"] .main-sidebar {
|
||||||
left: auto !important;
|
left: auto !important;
|
||||||
right: 0 !important;
|
right: 0 !important;
|
||||||
border-right: none !important;
|
border-right: none !important;
|
||||||
border-left: 1px solid rgba(0,0,0,0.1) !important;
|
border-left: 1px solid rgba(0,0,0,0.1) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Content Wrapper & Headers */
|
|
||||||
[dir="rtl"] .content-wrapper,
|
[dir="rtl"] .content-wrapper,
|
||||||
[dir="rtl"] .main-header,
|
[dir="rtl"] .main-header,
|
||||||
[dir="rtl"] .main-footer {
|
[dir="rtl"] .main-footer {
|
||||||
@ -293,22 +162,17 @@ body.model-platformprofile label[for="id_admin_panel_logo"] {
|
|||||||
margin-right: 250px !important;
|
margin-right: 250px !important;
|
||||||
transition: margin-right .3s ease-in-out !important;
|
transition: margin-right .3s ease-in-out !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Collapsed Sidebar State */
|
|
||||||
[dir="rtl"].sidebar-collapse .main-sidebar {
|
[dir="rtl"].sidebar-collapse .main-sidebar {
|
||||||
margin-left: 0 !important;
|
margin-left: 0 !important;
|
||||||
margin-right: 0 !important; /* AdminLTE collapses by width, not margin usually, but ensure position matches */
|
margin-right: 0 !important;
|
||||||
width: 4.6rem !important;
|
width: 4.6rem !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
[dir="rtl"].sidebar-collapse .content-wrapper,
|
[dir="rtl"].sidebar-collapse .content-wrapper,
|
||||||
[dir="rtl"].sidebar-collapse .main-header,
|
[dir="rtl"].sidebar-collapse .main-header,
|
||||||
[dir="rtl"].sidebar-collapse .main-footer {
|
[dir="rtl"].sidebar-collapse .main-footer {
|
||||||
margin-left: 0 !important;
|
margin-left: 0 !important;
|
||||||
margin-right: 4.6rem !important;
|
margin-right: 4.6rem !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fix Brand Logo Area */
|
|
||||||
[dir="rtl"] .brand-link {
|
[dir="rtl"] .brand-link {
|
||||||
float: right !important;
|
float: right !important;
|
||||||
width: 100% !important;
|
width: 100% !important;
|
||||||
@ -319,63 +183,41 @@ body.model-platformprofile label[for="id_admin_panel_logo"] {
|
|||||||
margin-right: 0.8rem !important;
|
margin-right: 0.8rem !important;
|
||||||
margin-left: 0.5rem !important;
|
margin-left: 0.5rem !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Navbar alignment */
|
|
||||||
[dir="rtl"] .navbar-nav {
|
[dir="rtl"] .navbar-nav {
|
||||||
flex-direction: row; /* bootstrap default, but ensure items flow right to left visually */
|
flex-direction: row;
|
||||||
}
|
}
|
||||||
[dir="rtl"] .navbar-nav .nav-item {
|
[dir="rtl"] .navbar-nav .nav-item {
|
||||||
float: right;
|
float: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Right side navbar items (user menu etc) should be on left now?
|
|
||||||
In RTL, "ml-auto" (margin-left: auto) pushes items to the LEFT.
|
|
||||||
Jazzmin uses ml-auto for the user menu.
|
|
||||||
In RTL, we want them on the LEFT.
|
|
||||||
Bootstrap 4 RTL support usually flips ml-auto to mr-auto,
|
|
||||||
but if we are running LTR bootstrap in RTL mode, ml-auto pushes to Right.
|
|
||||||
Wait, ml-auto = margin-left: auto. In LTR, this pushes to Right.
|
|
||||||
In RTL, we want these items on the LEFT. So we need margin-right: auto.
|
|
||||||
*/
|
|
||||||
|
|
||||||
[dir="rtl"] .ml-auto {
|
[dir="rtl"] .ml-auto {
|
||||||
margin-left: 0 !important;
|
margin-left: 0 !important;
|
||||||
margin-right: auto !important;
|
margin-right: auto !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
[dir="rtl"] .mr-auto {
|
[dir="rtl"] .mr-auto {
|
||||||
margin-right: 0 !important;
|
margin-right: 0 !important;
|
||||||
margin-left: auto !important;
|
margin-left: auto !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sidebar Navigation Items RTL */
|
|
||||||
[dir="rtl"] .nav-sidebar .nav-item > .nav-link {
|
[dir="rtl"] .nav-sidebar .nav-item > .nav-link {
|
||||||
display: flex !important;
|
display: flex !important;
|
||||||
flex-direction: row !important; /* Standard flow: RTL = Start(Right) to End(Left) */
|
flex-direction: row !important;
|
||||||
align-items: center !important;
|
align-items: center !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
[dir="rtl"] .nav-sidebar .nav-icon {
|
[dir="rtl"] .nav-sidebar .nav-icon {
|
||||||
margin-left: 0.5rem !important;
|
margin-left: 0.5rem !important;
|
||||||
margin-right: 0 !important;
|
margin-right: 0 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
[dir="rtl"] .nav-sidebar .nav-link p {
|
[dir="rtl"] .nav-sidebar .nav-link p {
|
||||||
display: inline-block !important;
|
display: inline-block !important;
|
||||||
margin-right: 0 !important;
|
margin-right: 0 !important;
|
||||||
text-align: right !important;
|
text-align: right !important;
|
||||||
width: 100% !important;
|
width: 100% !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fix sidebar angle icon (arrow) */
|
|
||||||
[dir="rtl"] .nav-sidebar .nav-icon.fa-angle-left {
|
[dir="rtl"] .nav-sidebar .nav-icon.fa-angle-left {
|
||||||
transform: rotate(180deg);
|
transform: rotate(180deg);
|
||||||
margin-left: 0 !important;
|
margin-left: 0 !important;
|
||||||
margin-right: auto !important; /* Push to the far left */
|
margin-right: auto !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* General Utils */
|
|
||||||
[dir="rtl"] .float-right {
|
[dir="rtl"] .float-right {
|
||||||
float: left !important;
|
float: left !important;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,119 +1,130 @@
|
|||||||
(function($) {
|
(function($) {
|
||||||
$(document).ready(function() {
|
// Masar Date Range Filter Layout Fix v4
|
||||||
// Helper to format date as YYYY-MM-DD
|
// Forces a horizontal layout for the Date Range Filter in Django Admin Sidebar
|
||||||
function formatDate(d) {
|
// v4: Switches to type="date", removes Django's calendar shortcuts to prevent layout breakage.
|
||||||
var year = d.getFullYear();
|
|
||||||
var month = ('0' + (d.getMonth() + 1)).slice(-2);
|
function initDateRangeDropdown() {
|
||||||
var day = ('0' + d.getDate()).slice(-2);
|
|
||||||
return year + '-' + month + '-' + day;
|
// Find all "Greater Than or Equal" inputs (the start date of the range)
|
||||||
|
var $gteInputs = $('input[name$="__gte"]');
|
||||||
|
|
||||||
|
if ($gteInputs.length === 0) {
|
||||||
|
return; // Not found yet
|
||||||
}
|
}
|
||||||
|
|
||||||
function initDateRangeDropdown() {
|
$gteInputs.each(function() {
|
||||||
var $gteInputs = $('input[name$="__gte"]');
|
var $gte = $(this);
|
||||||
|
if ($gte.data('masar-processed')) return;
|
||||||
|
$gte.data('masar-processed', true);
|
||||||
|
|
||||||
$gteInputs.each(function() {
|
var name = $gte.attr('name');
|
||||||
var $gte = $(this);
|
var prefix = name.substring(0, name.lastIndexOf('__gte'));
|
||||||
var name = $gte.attr('name');
|
var $lte = $('input[name="' + prefix + '__lte"]');
|
||||||
var prefix = name.substring(0, name.lastIndexOf('__gte'));
|
|
||||||
var $lte = $('input[name="' + prefix + '__lte"]');
|
|
||||||
|
|
||||||
if ($lte.length === 0) return;
|
if ($lte.length === 0) return;
|
||||||
|
|
||||||
var $container = $gte.closest('.admindatefilter');
|
// Locate the container
|
||||||
if ($container.length === 0) {
|
var $parent = $gte.parent();
|
||||||
$container = $gte.closest('div[data-filter-name], li, .form-row, .card-body, .filter-wrapper');
|
|
||||||
}
|
|
||||||
if ($container.length === 0) $container = $gte.parent();
|
|
||||||
|
|
||||||
if ($container.data('dropdown-init')) return;
|
// Create custom flex wrapper
|
||||||
$container.data('dropdown-init', true);
|
var $wrapper = $('<div class="masar-date-filter-row"></div>');
|
||||||
|
|
||||||
|
// Create the Quick Select Dropdown
|
||||||
|
var $select = $('<select class="form-control custom-select admin-date-dropdown">' +
|
||||||
|
'<option value="any">Any</option>' +
|
||||||
|
'<option value="today">Today</option>' +
|
||||||
|
'<option value="7days">7 Days</option>' +
|
||||||
|
'<option value="month">Month</option>' +
|
||||||
|
'<option value="custom">Custom</option>' +
|
||||||
|
'</select>');
|
||||||
|
|
||||||
|
// CONVERT INPUTS TO HTML5 DATE
|
||||||
|
// This gives us a native picker and removes the need for Django's clunky JS shortcuts
|
||||||
|
$gte.attr('type', 'date').removeClass('vDateField');
|
||||||
|
$lte.attr('type', 'date').removeClass('vDateField');
|
||||||
|
|
||||||
var $controls = $gte.closest('.controls');
|
// --- RESTRUCTURING DOM ---
|
||||||
if ($controls.length === 0) {
|
// 1. Insert wrapper before the start input
|
||||||
$controls = $gte.parent();
|
$gte.before($wrapper);
|
||||||
}
|
|
||||||
$controls.addClass('date-filter-controls'); // Hook for CSS
|
// 2. Move elements into wrapper
|
||||||
|
$wrapper.append($select);
|
||||||
// --- Dropdown ---
|
$wrapper.append($gte);
|
||||||
var $select = $('<select class="form-control custom-select admin-date-dropdown">' +
|
$wrapper.append($lte);
|
||||||
'<option value="any">Any Date</option>' +
|
|
||||||
'<option value="today">Today</option>' +
|
|
||||||
'<option value="7days">Last 7 Days</option>' +
|
|
||||||
'<option value="month">This Month</option>' +
|
|
||||||
'<option value="year">This Year</option>' +
|
|
||||||
'<option value="custom">Custom Range...</option>' +
|
|
||||||
'</select>');
|
|
||||||
|
|
||||||
// --- Inputs Styling ---
|
// 3. AGGRESSIVE CLEANUP
|
||||||
$gte.addClass('form-control form-control-sm date-input');
|
// Remove text nodes, BRs, AND Django's calendar shortcuts (.datetimeshortcuts)
|
||||||
$lte.addClass('form-control form-control-sm date-input');
|
// We search the *original parent* for these leftovers.
|
||||||
|
$parent.contents().filter(function() {
|
||||||
|
return (
|
||||||
|
(this.nodeType === 3 && $.trim($(this).text()) !== '') || // Text
|
||||||
|
this.tagName === 'BR' || // Line breaks
|
||||||
|
$(this).hasClass('datetimeshortcuts') // Django Calendar Icons
|
||||||
|
);
|
||||||
|
}).remove();
|
||||||
|
|
||||||
// Insert Dropdown
|
// Also hide any shortcuts that might be dynamically appended later (via CSS rule or observer)
|
||||||
if ($controls.length) {
|
// But removing the 'vDateField' class above usually prevents Django from initializing them.
|
||||||
$controls.before($select);
|
|
||||||
|
// Logic for Dropdown Changes
|
||||||
|
function formatDate(d) {
|
||||||
|
var year = d.getFullYear();
|
||||||
|
var month = ('0' + (d.getMonth() + 1)).slice(-2);
|
||||||
|
var day = ('0' + d.getDate()).slice(-2);
|
||||||
|
return year + '-' + month + '-' + day;
|
||||||
|
}
|
||||||
|
|
||||||
|
var gteVal = $gte.val();
|
||||||
|
var lteVal = $lte.val();
|
||||||
|
if (gteVal || lteVal) {
|
||||||
|
$select.val('custom');
|
||||||
|
} else {
|
||||||
|
$select.val('any');
|
||||||
|
}
|
||||||
|
|
||||||
|
$select.on('change', function() {
|
||||||
|
var val = $(this).val();
|
||||||
|
var today = new Date();
|
||||||
|
|
||||||
|
if (val === 'custom') {
|
||||||
|
// Do nothing, let user edit
|
||||||
} else {
|
} else {
|
||||||
$gte.before($select);
|
if (val === 'any') {
|
||||||
}
|
$gte.val('');
|
||||||
|
$lte.val('');
|
||||||
// Initial State
|
|
||||||
var gteVal = $gte.val();
|
|
||||||
var lteVal = $lte.val();
|
|
||||||
|
|
||||||
if (gteVal || lteVal) {
|
|
||||||
$select.val('custom');
|
|
||||||
$controls.css('display', 'inline-flex'); // Ensure flex
|
|
||||||
} else {
|
|
||||||
$select.val('any');
|
|
||||||
$controls.hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Event Listener
|
|
||||||
$select.on('change', function() {
|
|
||||||
var val = $(this).val();
|
|
||||||
var today = new Date();
|
|
||||||
|
|
||||||
if (val === 'custom') {
|
|
||||||
$controls.css('display', 'inline-flex').hide().fadeIn();
|
|
||||||
} else {
|
} else {
|
||||||
if (val === 'any') {
|
var startStr = '';
|
||||||
$gte.val('');
|
var endStr = formatDate(today);
|
||||||
$lte.val('');
|
|
||||||
} else {
|
|
||||||
var startStr = '';
|
|
||||||
var endStr = formatDate(today);
|
|
||||||
|
|
||||||
if (val === 'today') {
|
if (val === 'today') {
|
||||||
startStr = formatDate(today);
|
startStr = formatDate(today);
|
||||||
} else if (val === '7days') {
|
} else if (val === '7days') {
|
||||||
var past = new Date();
|
var past = new Date();
|
||||||
past.setDate(today.getDate() - 7);
|
past.setDate(today.getDate() - 7);
|
||||||
startStr = formatDate(past);
|
startStr = formatDate(past);
|
||||||
} else if (val === 'month') {
|
} else if (val === 'month') {
|
||||||
var firstDay = new Date(today.getFullYear(), today.getMonth(), 1);
|
var firstDay = new Date(today.getFullYear(), today.getMonth(), 1);
|
||||||
startStr = formatDate(firstDay);
|
startStr = formatDate(firstDay);
|
||||||
} else if (val === 'year') {
|
|
||||||
var firstDay = new Date(today.getFullYear(), 0, 1);
|
|
||||||
startStr = formatDate(firstDay);
|
|
||||||
}
|
|
||||||
|
|
||||||
$gte.val(startStr);
|
|
||||||
$lte.val(endStr);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Auto-submit
|
|
||||||
var $form = $gte.closest('form');
|
|
||||||
if ($form.length) {
|
|
||||||
$form.submit();
|
|
||||||
} else {
|
|
||||||
var $btn = $container.find('input[type="submit"], button[type="submit"]');
|
|
||||||
if ($btn.length) $btn.click();
|
|
||||||
}
|
}
|
||||||
|
$gte.val(startStr);
|
||||||
|
$lte.val(endStr);
|
||||||
}
|
}
|
||||||
});
|
// Trigger Form Submit
|
||||||
|
var $form = $gte.closest('form');
|
||||||
|
if ($form.length) {
|
||||||
|
$form.submit();
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$(document).ready(function() {
|
||||||
initDateRangeDropdown();
|
initDateRangeDropdown();
|
||||||
|
// Retry logic for stubborn renderers
|
||||||
|
setTimeout(initDateRangeDropdown, 200);
|
||||||
setTimeout(initDateRangeDropdown, 500);
|
setTimeout(initDateRangeDropdown, 500);
|
||||||
|
setTimeout(initDateRangeDropdown, 1000);
|
||||||
});
|
});
|
||||||
|
|
||||||
})(django.jQuery);
|
})(django.jQuery);
|
||||||
Loading…
x
Reference in New Issue
Block a user