JSFiddle - React, Tailwind, and code Playground
by NickU
HTML
<div class="button-container">
<button type="button" value="All" title="01/01/1999 - 02/25/2023" class="bntWhen selected">All </button>
<button type="button" value="Today" title="02/25/2023 - 02/25/2023" class="bntWhen">Today </button>
<button type="button" value="PreviousDay" title="02/24/2023 - 02/24/2023" class="bntWhen">Previous Day </button>
<button type="button" value="WeekToDate" title="02/20/2023 - 02/25/2023" class="bntWhen">Week To Date </button>
<button type="button" value="PreviousWeek" title="02/13/2023 - 02/17/2023" class="bntWhen">Previous Week </button>
<button type="button" value="MonthToDate" title="02/01/2023 - 02/25/2023" class="bntWhen">Month To Date </button>
<button type="button" value="YearToDate" title="01/01/2023 - 02/25/2023" class="bntWhen">Year To Date </button>
<button type="button" value="LastCalendYear" title="01/01/2022 - 12/31/2022" class="bntWhen">Last Year </button>
<button type="button" value="CustomRange" title="Click to enter Custom Date Range ..." class="bntWhen">Custom Date... </button>
<div class="custom-range">
<input type="date" name="startDate" id="startDate">
<input type="date" name="endDate" id="endDate">
</div>
<form name="f1" id="f1">
<input type="hidden" name="DateAddedPeriod" id="DateAddedPeriod" value="All">
<input type="hidden" id="DateAddedPeriodTitle" name="DateAddedPeriodTitle" value="">
</form>
</div>
CSS
#date-filter-table {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(3, 1fr);
position: relative;
margin-top: 10px;
}
#date-filter-table .bntWhen {
position: relative;
z-index: 1;
}
#date-filter-table .bntWhen.selected:before {
content: '';
display: block;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(90deg, #FFFFFF00 0%, #FFFFFFAA 100%);
z-index: -1;
}
.custom-range {
visibility: hidden;
position: absolute;
left: 0;
top: 0;
z-index: 2;
width: 100%;
background-color: #fff;
box-shadow: 0 1px 5px rgba(0, 0, 0, 0.3);
padding: 10px;
box-sizing: border-box;
}
.custom-range.show {
display: block;
animation: slide-down 0.3s;
}
.custom-range input[type="date"] {
border: 1px solid #c0c0c0b3;
margin: 5px;
border-radius: 3px;
padding: 5px;
font-size: 12px;
}
.custom-range .actions {
display: flex;
justify-content: flex-end;
margin-top: 10px;
}
.custom-range .actions button {
margin-left: 10px;
}
@keyframes slide-down {
0% {
opacity: 0;
top: -100%;
}
100% {
opacity: 1;
top: 0;
}
}
JavaScript
// Get the custom range div and its width
const customRangeDiv = document.querySelector(".custom-range");
const customRangeWidth = 900;
// Position the buttons
const buttons = document.querySelectorAll(".bntWhen");
const numButtons = buttons.length;
const buttonWidth = buttons[0].offsetWidth;
const buttonOverlap = buttonWidth / 2;
const buttonMargin = (customRangeWidth - numButtons * buttonWidth + (numButtons - 1) * buttonOverlap) / 2;
for (let i = 0; i < numButtons; i++) {
const button = buttons[i];
const buttonLeft = i * (buttonWidth - buttonOverlap) + buttonMargin;
button.style.position = "absolute";
button.style.left = `${buttonLeft}px`;
}
// Animate the button positions
function animateButtonPositions(targetMargin) {
const startMargin = parseFloat(buttons[0].style.marginLeft);
const numSteps = 100;
const stepSize = (targetMargin - startMargin) / numSteps;
let step = 1;
const interval = setInterval(() => {
if (step >= numSteps) {
clearInterval(interval);
}
const newMargin = startMargin + step * stepSize;
for (let i = 0; i < numButtons; i++) {
const button = buttons[i];
const buttonLeft = i * (buttonWidth - buttonOverlap) + newMargin;
button.style.left = `${buttonLeft}px`;
}
step++;
console.log("step="+ step);
}, 50);
}
// Add a click event listener to the CustomRange button
const customRangeButton = document.querySelector(".bntWhen[value=CustomRange]");
customRangeButton.addEventListener("click", () => {
//customRangeDiv.style.visibility = "visible";
animateButtonPositions(-customRangeWidth / 2);
});