I am using bootstrap date picker. I want to open two month picker in one input. I want to display my input value like this:
How to create a month range picker using Bootstrap Datepicker that allows selecting two distinct months and displays the selected range in the specified format?
<div class="form-group input-border-label">
<label for="billing_range">Billing Month Range</label>
<input type="text" id="billing_range" name="billing_range" required>
</div>
<script>
document.addEventListener('DOMContentLoaded', function () {
$('#billing_range').datepicker({
format: 'M-yyyy',
autoclose: true,
startView: 1,
minViewMode: 1,
multidate: true,
multidateSeparator: ' to ',
clearBtn: true
}).on('changeDate', function(e) {
var currentDates = $(this).datepicker('getDates');
// If only one date is selected, duplicate it (Jan-2025 → Jan-2025 to Jan-2025)
if (currentDates.length === 1) {
$(this).datepicker('setDates', [currentDates[0], currentDates[0]]);
}
// If more than 2 dates, keep only the last two
else if (currentDates.length > 2) {
$(this).datepicker('setDates', [
currentDates[currentDates.length - 2],
currentDates[currentDates.length - 1]
]);
}
});
});
</script>
$(document).ready(function() {
let startMonth = null;
let endMonth = null;
const $billingRange = $('#billing_range');
const $monthPopup = $('#monthRangePopup');
function createMonthPicker(target, onSelect, options = {}) {
$(target).datepicker({
format: "M-yyyy",
startView: "months",
minViewMode: "months",
autoclose: true,
...options
}).on('changeDate', e => onSelect(e.date));
}
function updateRangeInput() {
if (!startMonth || !endMonth) return;
const start = moment(startMonth);
const end = moment(endMonth);
const rangeText = `${start.format('MMM-YYYY')} to ${end.format('MMM-YYYY')}`;
$billingRange.val(rangeText);
$monthPopup.addClass('d-none');
}
// Destroy any existing pickers
$('#startPicker, #endPicker').datepicker('destroy');
// Create Start Picker
createMonthPicker('#startPicker', function(date) {
startMonth = date;
endMonth = null;
$('#endPicker').datepicker('destroy');
createMonthPicker('#endPicker', function(date) {
endMonth = date;
updateRangeInput();
}, {
startDate: moment(startMonth).add(1, 'month').startOf('month').toDate()
});
});
// Disable endPicker initially by binding to a dummy handler
createMonthPicker('#endPicker', function() {}, {
beforeShowMonth: () => false, // diabled all the month
maxViewMode: 1 // diabled all the year
});
// Show popup
$billingRange.on('click', function() {
$monthPopup.removeClass('d-none');
});
// Hide popup on outside click
$(document).on('click', function(e) {
if (!$(e.target).closest('#billing_range, #monthRangePopup').length) {
$monthPopup.addClass('d-none');
}
});
});
<!-- Required CSS -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.9.0/css/bootstrap-datepicker.min.css" rel="stylesheet" />
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet" />
<!-- Required JS -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.9.0/js/bootstrap-datepicker.min.js"></script>
<div class="container">
<div class="form-group position-relative">
<div class="input-border-label">
<label for="billing_range">Maintenance Period</label>
<input type="text" id="billing_range" name="billing_range" readonly placeholder="Select month range" class="form-control">
</div>
<div id="monthRangePopup" class="d-none bg-white border shadow p-3 position-absolute" style="top:100%; z-index: 1050;">
<div class="d-flex" style="gap:10px;">
<div id="startPicker"></div>
<div id="endPicker"></div>
</div>
</div>
</div>
</div>
Allowing Same Start and End Month in picker
To allow users to select the same month for both start and end,
update this line:
startDate: moment(startMonth).add(1, 'month').startOf('month').toDate()
to
startDate: moment(startMonth).startOf('month').toDate()