Kendo UI Calendar Multiselection

2019-05-16 15:50发布

问题:

Hi is there a way to make the kendodatepicker allow multiselect? so select more than one date and have them all stay highlighted?

回答1:

Update 08.2016


You can use my plugin to select multiple dates.

Demo

Old answer


Still there is no official way to select multiple dates in DatePicker. However, with some help of jQuery you can achieve this functionality.

HTML:

<table>
  <tr>
    <td style="vertical-align: initial; padding-right: 100px;">
      <input id="picker" />
    </td>
    <td>
      <div id="calendar"></div>
    </td>
  </tr>
</table>

CSS:

.k-state-selected {
  background-color: transparent;
  border-color: transparent;
  background-image: none;
}

td.k-state-focused.k-state-selected {
  box-shadow: none;
}

.k-state-selected > .k-link {
  color: black;
}

.selected {
  background-color: #F35800;
  border-color: #F85A00;
  background-image: none, linear-gradient(to bottom, rgba(255, 255, 255, 0.2) 0px, rgba(255, 255, 255, 0) 100%);
}

.selected > .k-link {
  color: #FFF;
}

JS:

$(function() {
  var day = 86400000;
  var today = new Date();
  //time is set to midnight for correct comparison with values from calendar
  today.setHours(0, 0, 0, 0);

  //data source
  var selectedDates = [
    today.getTime() - day,
    today.getTime(),
    today.getTime() + day
  ];

  //DatePicker with multiselection
  initPicker($('#picker').kendoDatePicker(), selectedDates);

  //Calendar with multiselection
  //initCalendar($("#calendar").kendoCalendar(), selectedDates.slice());
});

function initPicker(picker, selectedDates) {
  var isInit = false;
  var kendoPicker = picker.data('kendoDatePicker');

  kendoPicker.bind('open', function() {
    if (!isInit) {
      //assuming that corresponding calendar widget has id 'picker_dateview'
      var calendar = $('#' + picker.attr('id') + '_dateview > .k-calendar');

      initCalendar(calendar, selectedDates, function() {
        updatePicker(picker, selectedDates);
      });

      isInit = true;
    }
  });

  picker.on('input change blur', function() {
    updatePicker(picker, selectedDates);
  });

  updatePicker(picker, selectedDates);
}

function initCalendar(calendar, selectedDates, onUpdate) {
  var kendoCalendar = calendar.data('kendoCalendar');

  kendoCalendar.bind('navigate', function() {
    setTimeout(function() {
      updateCalendar(calendar, selectedDates);
    }, 0);
  });

  updateCalendar(calendar, selectedDates);

  calendar.on('click', function(event) {
    var cell = $(event.target).closest('td');
    var isClickedOnDayCell = cell.length !== 0 && isDayCell(cell);

    if (isClickedOnDayCell) {
      var date = dateFromCell(cell).getTime();
      var isDateAlreadySelected = selectedDates.some(function(selected) {
        return selected === date;
      });

      if (isDateAlreadySelected) {
        selectedDates.splice(selectedDates.indexOf(date), 1);

      } else {
        selectedDates.push(date);
      }

      updateCell(cell, selectedDates);

      if (onUpdate !== undefined) {
        onUpdate();
      }
    }
  });
}

function updatePicker(picker, selectedDates) {
  var datesString = selectedDates.sort().reduce(function(acc, selected, index) {
    var date = new Date(selected);
    var formattedDate = (date.getMonth() + 1) + '/' + date.getDate() + '/' + date.getFullYear();

    return acc + formattedDate + (index === (selectedDates.length - 1) ? '' : ', ');
  }, '');

  picker.val(datesString);
}

function updateCalendar(calendar, selectedDates) {
  calendar.find('td > a').parent().each(function(i, item) {
    var cell = $(item);

    if (isDayCell(cell)) {
      updateCell(cell, selectedDates);
    }
  });
}

function updateCell(cell, selectedDates) {
  var isCellSelected = selectedDates.some(function(selected) {
    return selected === dateFromCell(cell).getTime();
  });

  if (isCellSelected) {
    cell.addClass('selected');

  } else {
    cell.removeClass('selected');
  }
}

function isDayCell(cell) {
  return /^\d{1,2}$/.test(cell.find('a').text());
}

function dateFromCell(cell) {
  return new Date(convertDataValue(cell.find('a').attr('data-value')));
}

//convert from 'YYYY/MM/DD', where MM = 0..11
function convertDataValue(date) {
  var regex = /\/(\d+)\//;
  var month = +date.match(regex)[1] + 1;

  return date.replace(regex, '/' + month + '/');
}

Live example:

https://jsfiddle.net/iyegoroff/a8ma6a1j/



回答2:

i am not Much sure , but as i know multiple selection behavior is currently not supported, because the date picker calendar can only have one date as a selected value . but if you really need this option you can customize it

http://demos.telerik.com/kendo-ui/datepicker/template

and add a common image to the range(like a underlining) and give date with a loop. In calendar you can change its background color .

this is a example code you can try for it :

http://onabai.wordpress.com/2012/09/19/kendo-ui-setting-background-for-specific-dates/

And If you like this option be available soon vote for it :

http://kendoui-feedback.telerik.com/forums/127393-telerik-kendo-ui-feedback/suggestions/4122749-add-range-select-to-datepicker

(i am new to sit so i cant put many links)

Hope this help !! Good luck