jquery ui инструмент за избор на множество дати диапазон от данни без почивни дни

Използвам този инструмент за избор на множество данни. Възможно ли е да се използва режим на диапазон от дати, където няма да бъдат избрани почивни дни?

Вече направих избор на множество дати, където уикендите са блокирани и където потребителят може да избере само 5 дни, но това не е целта ми. Бих искал тази функционалност: когато потребителят щракне върху конкретна дата, пет дни в диапазон ще бъдат откроени без дните през почивните дни...

Моят код по-долу:

jQuery('#deliverydate').multiDatesPicker({
   minDate:0,
   beforeShowDay: noWeekendsOrHolidays,
   mode: 'daysRangeWithoutWeekends', 
   autoselectRange: [0,5],
   numberOfMonths: 2            
});

сега съм доста близо до собственото си решение:

Отчитам всички дни, които трябва да бъдат активирани, и всички нови дни, които трябва да бъдат избрани, ако има уикенд в диапазон от дни.

Добавям новия си метод в multidatepicker.js daysRangeWithoutWeekends, където отчитам всички нови и деактивирани дни. След това използвам два цикъла foreach, където деактивирам и активирам нови дати:

$.each(all_removed_dates, function(index, value) { 
    methods.removeDates.call(obj, value);
});

$.each(all_new_dates, function(index, value) { 
     methods.addDates.call(obj,value);
});

стойността е обект Дата. Първият цикъл foreach работи перфектно и премахва всички подчертани уикенди, но вторият цикъл не работи. Връща ми грешка:

Empty array of dates received.

Знаеш ли защо?

За всички, които не разбирате каква е целта ми: multidatepicker диапазон без уикенд

Трябва да избера 5 дни в обхват без почивните дни, ако щракна върху дати 21.6.2012 г. 21.6., 22.6, 25.6, 26.6., 27.6. трябва да бъдат избрани.

С горния код успявам да премахна маркирания клас през уикендите, но не знам защо вторият цикъл (вижте моя код отгоре) не маркира 26.6.2012 и 27.6.2012.


person Gasper    schedule 08.06.2012    source източник
comment
къде въвеждате тези пет дни??›.. имате ли нещо като начална и крайна дата??   -  person Kabilan S    schedule 12.06.2012
comment
имате предвид автоматично изчисляване на крайната дата с дадена начална дата и 5 дни без края на седмицата??   -  person Kabilan S    schedule 12.06.2012
comment
Можете ли да поставите още код, показващ как се попълват всички_нови_дати, моля   -  person Ateszki    schedule 12.06.2012
comment
@gašper Би било по-добре да актуализирате въпроса си с вашия код, вместо да добавяте отговор. Във вашия код къде декларирате/присвоявате all_removed_dates и all_new_dates?   -  person Jeffery To    schedule 14.06.2012


Отговори (5)


Първо, това не е общо решение. Нямах време за общо решение. Моето решение е, ако трябва да изберете 5 дни в обхват без почивните дни.

в jquery-ui.multidatepicker.js в метод onSelect (ок. 81 ред) добавете:

if(this.multiDatesPicker.mode == 'daysRangeWithoutWeekends'  && this.multiDatesPicker.dates.picked.length > 0){
      var i = 0,
      last

      if(this.multiDatesPicker.dates.picked[0].getDay() == 2){  //thusday
           i = 1
           //remove sunday
           all_removed_dates.push(this.multiDatesPicker.dates.picked[4])
      } 
      if(this.multiDatesPicker.dates.picked[0].getDay() == 3){//wednesday
           i = 2 
           //remove sunday and saturday 
           all_removed_dates.push(this.multiDatesPicker.dates.picked[3],                      this.multiDatesPicker.dates.picked[4])
      }
      if(this.multiDatesPicker.dates.picked[0].getDay() == 4){ //thursday
           i=2
           all_removed_dates.push(this.multiDatesPicker.dates.picked[2], this.multiDatesPicker.dates.picked[3])                                   
      }  
      if(this.multiDatesPicker.dates.picked[0].getDay() == 5){ //friday
           i=2
           all_removed_dates.push(this.multiDatesPicker.dates.picked[1], this.multiDatesPicker.dates.picked[2])                                   
      } 

      last = this.multiDatesPicker.dates.picked.pop()
      this.multiDatesPicker.dates.picked.push(last)

      if(this.multiDatesPicker.dates.picked[0].getDay() == 2){ //thusday
            //if we have thusday we add 2 day after last day so last day in range was saturday and we add 2 day and we get date for monday
            var new_date = new Date(last.getFullYear(), last.getMonth(), last.getDate() + 2)
            all_new_dates.push(new_date)
      }else{
          //if there were sunday and saturday in range we add 2 days to last date in range
          for(var j = 1; j <= i; j++){
                var new_date = new Date(last.getFullYear(), last.getMonth(), last.getDate() + j)
                all_new_dates.push(new_date)
          }
      }

      var obj = this
      //remove sunday and saturday 
      $.each(all_removed_dates, function(index, value) { 
          methods.removeDates.call(obj, value);
      });
      //add new days                                  
      $.each(all_new_dates, function(index, value) { 
          methods.add_new_date.call(obj,value);
      });                             
}

в jquery-ui.multidatepicker.js в метода toogleDate (ок. 431 ред) преди случай 'daysRange' добавете:

case 'daysRangeWithoutWeekends':

в jquery-ui.multidatepicker.js в setMode(ок. 473ред) преди случай 'daysRange' добавете:

case 'daysRangeWithoutWeekends':

calander е init с:

jQuery('#deliverydate').multiDatesPicker({
   minDate:0,
   beforeShowDay: noWeekendsOrHolidays,
   mode: 'daysRangeWithoutWeekends', 
   autoselectRange: [0,5],
   numberOfMonths: 2            
});

Ако някой направи общ алгоритъм, моля да го сподели =)

person Gasper    schedule 13.06.2012

Защо не опитате това

methods.addDates.call(obj,all_new_dates);

вместо това

$.each(all_new_dates, function(index, value) { 
     methods.addDates.call(obj,value);
});
person Ateszki    schedule 13.06.2012

Може би просто преминаване през цикъл и модифициране на съдържанието на масива ще работи?

if (this.multiDatesPicker.mode === 'daysRangeWithoutWeekends' && this.multiDatesPicker.dates.picked.length > 0) {
    var i = 0,
        saturdayFound = false,
        sundayFound = false;
    for (i = 0; i < this.multiDatesPicker.dates.picked.length; i += 1) {
        if (this.multiDatesPicker.dates.picked[i].getDay() === 6) {
            this.multiDatesPicker.dates.picked[i] = this.multiDatesPicker.dates.picked[i].addDays(2); //make it Monday
            saturdayFound = true;
        }
        if (this.multiDatesPicker.dates.picked[i].getDay() === 0) {
            this.multiDatesPicker.dates.picked[i] = this.multiDatesPicker.dates.picked[i].addDays(1); //make it Monday
            sundayFound = true;
        }
        if (saturdayFound || sundayFound) {
            //weekend exists before this element in the array
            if ((this.multiDatesPicker.dates.picked[i].getDay() > 0) || (this.multiDatesPicker.dates.picked[i].getDay() < 6)) {
                //weekday found following weekend
                if (saturdayFound) {
                    this.multiDatesPicker.dates.picked[i] = this.multiDatesPicker.dates.picked[i].addDays(1); //add a day to offset for Saturday
                }
                if (sundayFound) {
                    this.multiDatesPicker.dates.picked[i] = this.multiDatesPicker.dates.picked[i].addDays(1); //add a day to offset for Sunday
                }
            }
        }
    }
    all_new_dates = this.multiDatesPicker.dates.picked;
}
person pete    schedule 18.06.2012

променете регистъра на дните със следния код

case 'dayRange':

this.multiDatesPicker.dates[type] = []; // deletes all picked/disabled 
var end = this.multiDatesPicker.autoselectRange[1];
var begin = this.multiDatesPicker.autoselectRange[0];
if(end < begin) { // switch
    end = this.multiDatesPicker.autoselectRange[0];
    begin = this.multiDatesPicker.autoselectRange[1];
}

var i1=begin;
var i2=begin;
while(i1<end){
    var tep= new Date(methods.sumDays(date, i2));
    if(tep.getDay()!=0 && tep.getDay()!=6){
        methods.addDates.call(this, methods.sumDays(date, i2), type);
        i1++;
    }
    i2++;
}
person Adi    schedule 19.08.2015

деактивирайте само неделя: добавете опция преди ShowDay: noWeekendsOrHolidays

function noWeekendsOrHolidays(date) {
    DateRemove = date.getFullYear()+'-'+date.getMonth()+'-'+date.getDate();
    if (date.getDay() == 0) { // remove dimanche
        return [false, ''];
    } else {
        return [true, ''];
    }
}

ако имате грешка в конзолата: Грешка: Празен масив от получени дати. в jquery-ui.multidatespicker.js търси "addDates: function( dates, type)" и добавя return true;

addDates : function( dates, type ) {
            if(dates.length > 0) {
                if(!type) type = 'picked';
                switch(typeof dates) {
                    case 'object':
                    case 'array':
                        if(dates.length) {
                            for(var i = 0; i < dates.length; i++)
                                addDate.call(this, dates[i], type, true);
                            sortDates.call(this, type);
                            break;
                        } // else does the same as 'string'
                    case 'string':
                    case 'number':
                        addDate.call(this, dates, type);
                        break;
                    default: 
                        $.error('Date format "'+ typeof dates +'" not allowed on jQuery.multiDatesPicker');
                }
                //$(this).datepicker('refresh');
            } else {
                return true; // ADD THIS ONE
                $.error('Empty array of dates received.');
            }
        },
person Vlad    schedule 23.11.2016