简体   繁体   中英

Custom timepicker with jQuery and bootstrap

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. Select the time on click
  2. Only related times are possible to select.
  3. Only 1 time range at once is possible (eg 09:00-11:00 works but can't pick another time range)
  4. 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.
  5. 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/bootstrap@4.0.0/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/popper.js@1.12.9/dist/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.0.0/dist/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>

-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/bootstrap@4.0.0/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/popper.js@1.12.9/dist/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.0.0/dist/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM