Reputation: 1233
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:
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 class="time-cal col-lg-6 col-12">
<label>Pick times</label><br>
<button type="button" class="btn btn-xs time-btn btn-danger" data-start="07:00" data-end="08:00" disabled="">07:00 - 08:00</button>
<button type="button" class="btn btn-xs time-btn btn-danger" data-start="08:00" data-end="09:00" disabled="">08:00 - 09:00</button>
<button type="button" class="btn btn-xs time-btn btn-light" data-start="09:00" data-end="10:00">09:00 - 10:00</button>
<button type="button" class="btn btn-xs time-btn btn-light" data-start="10:00" data-end="11:00">10:00 - 11:00</button>
<button type="button" class="btn btn-xs time-btn btn-danger" data-start="11:00" data-end="12:00" disabled="">11:00 - 12:00</button>
<button type="button" class="btn btn-xs time-btn btn-light" data-start="12:00" data-end="13:00">12:00 - 13:00</button>
<button type="button" class="btn btn-xs time-btn btn-light" data-start="13:00" data-end="14:00">13:00 - 14:00</button>
<button type="button" class="btn btn-xs time-btn btn-light" data-start="14:00" data-end="15:00">14:00 - 15:00</button>
<button type="button" class="btn btn-xs time-btn btn-light" data-start="15:00" data-end="16:00">15:00 - 16:00</button>
<button type="button" class="btn btn-xs time-btn btn-danger" data-start="16:00" data-end="17:00" disabled="">16:00 - 17:00</button>
<button type="button" class="btn btn-xs time-btn btn-danger" data-start="17:00" data-end="18:00" disabled="">17:00 - 18:00</button>
<button type="button" class="btn btn-xs time-btn btn-light" data-start="18:00" data-end="19:00">18:00 - 19:00</button>
<button type="button" class="btn btn-xs time-btn btn-light" data-start="19:00" data-end="20:00">19:00 - 20:00</button>
<button type="button" class="btn btn-xs time-btn btn-light" data-start="20:00" data-end="21:00">20:00 - 21:00</button>
<button type="button" class="btn btn-xs time-btn btn-light" data-start="21:00" data-end="22:00">21:00 - 22:00</button>
<div class="form-group">
</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>
Upvotes: 1
Views: 200
Reputation: 12544
-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 && btn.selected).forEach(btn=>btn.setSelected(false));
return;
}
//deselect other timeblocks
enabledButtons.toArray().filter(b=>b.timeBlock !== this.timeBlock).forEach(b=>b.setSelected(false));
//check if there are other selected
const selected = this.timeBlock.filter(b=>b.selected);
if(selected.length === 0)
this.setSelected(true); //no other buttons selected, simply select
else{
//select range withint the timeblock
let from = selected[0].index, to = this.index;
if(from > to)
[from,to] = [to,from];
for(let i = from;i<=to;i++)
timeButtons[i].setSelected(true);
}
});
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<div class="time-cal col-lg-6 col-12">
<label>Pick times</label><br>
<button type="button" class="btn btn-xs time-btn btn-danger" data-start="07:00" data-end="08:00" disabled="">07:00 - 08:00</button>
<button type="button" class="btn btn-xs time-btn btn-danger" data-start="08:00" data-end="09:00" disabled="">08:00 - 09:00</button>
<button type="button" class="btn btn-xs time-btn btn-light" data-start="09:00" data-end="10:00">09:00 - 10:00</button>
<button type="button" class="btn btn-xs time-btn btn-light" data-start="10:00" data-end="11:00">10:00 - 11:00</button>
<button type="button" class="btn btn-xs time-btn btn-danger" data-start="11:00" data-end="12:00" disabled="">11:00 - 12:00</button>
<button type="button" class="btn btn-xs time-btn btn-light" data-start="12:00" data-end="13:00">12:00 - 13:00</button>
<button type="button" class="btn btn-xs time-btn btn-light" data-start="13:00" data-end="14:00">13:00 - 14:00</button>
<button type="button" class="btn btn-xs time-btn btn-light" data-start="14:00" data-end="15:00">14:00 - 15:00</button>
<button type="button" class="btn btn-xs time-btn btn-light" data-start="15:00" data-end="16:00">15:00 - 16:00</button>
<button type="button" class="btn btn-xs time-btn btn-danger" data-start="16:00" data-end="17:00" disabled="">16:00 - 17:00</button>
<button type="button" class="btn btn-xs time-btn btn-danger" data-start="17:00" data-end="18:00" disabled="">17:00 - 18:00</button>
<button type="button" class="btn btn-xs time-btn btn-light" data-start="18:00" data-end="19:00">18:00 - 19:00</button>
<button type="button" class="btn btn-xs time-btn btn-light" data-start="19:00" data-end="20:00">19:00 - 20:00</button>
<button type="button" class="btn btn-xs time-btn btn-light" data-start="20:00" data-end="21:00">20:00 - 21:00</button>
<button type="button" class="btn btn-xs time-btn btn-light" data-start="21:00" data-end="22:00">21:00 - 22:00</button>
<div class="form-group">
</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>
Upvotes: 1