I build a custom timepicker with jQuery and bootstrap. It's almost finished, but 1 "nice to have detail" is missing and I'm stucked getting to the result.
It should follow this rules:
- Select the time on click
- Only related times are possible to select.
- Only 1 time range at once is possible (e.g. 09:00-11:00 works but can't pick another time range)
- Disabled times are not possible to pick and if they are between a possible time range, only the range before or after disabled are allowed.
- It should be possible to click the start time and the end time and if there are no obstacles in between, the times between should be selected as well.
1-4 are working but I'm stucked on point 5.
So what I want to achieve is that if I click on 13:00-14:00
and 15:00-16:00
, 14:00-15:00
should be selected automatically if allowed by above rules.
$('.time-cal .time-btn').on('click',function(){
if($('.time-cal .time-btn.btn-success').length == 0)
{
$(this).not(".btn-danger").toggleClass('btn-success');
$(this).not(".btn-danger").toggleClass('btn-light');
}else{
if($(this).hasClass('btn-light'))
{
if($(this).next().hasClass('btn-success') || $(this).prev().hasClass('btn-success'))
{
$(this).not(".btn-danger").toggleClass('btn-success');
$(this).not(".btn-danger").toggleClass('btn-light');
}
}else{
let next = $(this).next();
let prev = $(this).prev();
if(!next.hasClass('btn-success') || ! prev.hasClass('btn-success'))
{
$(this).not(".btn-danger").toggleClass('btn-success');
$(this).not(".btn-danger").toggleClass('btn-light');
}
}
}
});
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA 058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<div >
<label>Pick times</label><br>
<button type="button" data-start="07:00" data-end="08:00" disabled="">07:00 - 08:00</button>
<button type="button" data-start="08:00" data-end="09:00" disabled="">08:00 - 09:00</button>
<button type="button" data-start="09:00" data-end="10:00">09:00 - 10:00</button>
<button type="button" data-start="10:00" data-end="11:00">10:00 - 11:00</button>
<button type="button" data-start="11:00" data-end="12:00" disabled="">11:00 - 12:00</button>
<button type="button" data-start="12:00" data-end="13:00">12:00 - 13:00</button>
<button type="button" data-start="13:00" data-end="14:00">13:00 - 14:00</button>
<button type="button" data-start="14:00" data-end="15:00">14:00 - 15:00</button>
<button type="button" data-start="15:00" data-end="16:00">15:00 - 16:00</button>
<button type="button" data-start="16:00" data-end="17:00" disabled="">16:00 - 17:00</button>
<button type="button" data-start="17:00" data-end="18:00" disabled="">17:00 - 18:00</button>
<button type="button" data-start="18:00" data-end="19:00">18:00 - 19:00</button>
<button type="button" data-start="19:00" data-end="20:00">19:00 - 20:00</button>
<button type="button" data-start="20:00" data-end="21:00">20:00 - 21:00</button>
<button type="button" data-start="21:00" data-end="22:00">21:00 - 22:00</button>
<div >
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js" integrity="sha384-ApNbgh9B Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5 76PVCmYl" crossorigin="anonymous"></script>
CodePudding user response:
-edit altered behaviour based on the comments. At startup each time'button' is divided into a specific timeblock so buttons in the same timeblock can be quickly handled together (there might be some additional/other behavioral requirements when reselecting)
const
disabledClass = 'btn-danger',
selectedClass = 'btn-success',
notselectedClass = 'btn-light',
timeButtons = $('.time-cal .time-btn'),
enabledButtons = timeButtons.not('.' disabledClass ),
timeBlocks = [];
timeButtons.each((index,btn)=>{btn.enabled=!$(btn).hasClass(disabledClass);
if(btn.enabled){
if(index===0 || !timeButtons[index-1].enabled){
timeBlocks.push([]); //new timeblock
}
btn.timeBlock = timeBlocks[timeBlocks.length-1];
btn.timeBlock.push(btn);
}
prevEnabled = btn.enabled;
btn.index = index;btn.selected=false;
btn.setSelected = sel => {if(btn.selected===sel)return; btn.selected=sel;
$(btn).toggleClass(notselectedClass,!sel).toggleClass(selectedClass,sel);}
});
enabledButtons.click(function(){
if(this.selected){
//deselect and make sure times in this block after this button are deselected too
this.timeBlock.filter(btn=>btn.index >= this.index).forEach(btn=>btn.setSelected(false));
return;
}
let selected = false;
enabledButtons.each((index,btn)=>{
if(btn.timeBlock !== this.timeBlock)
btn.setSelected(false); //other timeblocks, make sure to disable
else{
selected ||= btn.selected || btn.index===this.index;
btn.setSelected(selected && btn.index <= this.index);
}
});
});
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA 058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<div >
<label>Pick times</label><br>
<button type="button" data-start="07:00" data-end="08:00" disabled="">07:00 - 08:00</button>
<button type="button" data-start="08:00" data-end="09:00" disabled="">08:00 - 09:00</button>
<button type="button" data-start="09:00" data-end="10:00">09:00 - 10:00</button>
<button type="button" data-start="10:00" data-end="11:00">10:00 - 11:00</button>
<button type="button" data-start="11:00" data-end="12:00" disabled="">11:00 - 12:00</button>
<button type="button" data-start="12:00" data-end="13:00">12:00 - 13:00</button>
<button type="button" data-start="13:00" data-end="14:00">13:00 - 14:00</button>
<button type="button" data-start="14:00" data-end="15:00">14:00 - 15:00</button>
<button type="button" data-start="15:00" data-end="16:00">15:00 - 16:00</button>
<button type="button" data-start="16:00" data-end="17:00" disabled="">16:00 - 17:00</button>
<button type="button" data-start="17:00" data-end="18:00" disabled="">17:00 - 18:00</button>
<button type="button" data-start="18:00" data-end="19:00">18:00 - 19:00</button>
<button type="button" data-start="19:00" data-end="20:00">19:00 - 20:00</button>
<button type="button" data-start="20:00" data-end="21:00">20:00 - 21:00</button>
<button type="button" data-start="21:00" data-end="22:00">21:00 - 22:00</button>
<div >
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js" integrity="sha384-ApNbgh9B Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5 76PVCmYl" crossorigin="anonymous"></script>