8

I am using this multidate picker. Is it possible to use date range mode where no weekends would be selected?

I have already done multidatepicker where weekends are blocked and where user can select just 5 days but this is not my goal. I would like this functionality: when user clicks on specific date, five days in range would be highlighted without weekend days...

My code bellow:

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

now I am quite near of my own solution:

I count all days which have to be enabled and all new day which have to be selected if there is weekend in range of days.

I add my new method in multidatepicker.js daysRangeWithoutWeekends where I count all new and disabled days. Then I use two foreach loops where I disable and enable new dates:

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

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

value is Date object. First foreach loop works perfectly and remove all highlighted weekends but second loop doesn't work. It returns me error:

Empty array of dates received.

Do you know why?

For all you do not understand what my goal is: multidatepicker range without weekend

I have to pick 5 day in range without weekends if i click on 21.6.2012 dates 21.6., 22.6, 25.6, 26.6., 27.6. have to be selected.

With upper code I manage to remove highlighted class on weekends but don't know why second loop (look my code upper) does not highlighted 26.6.2012 and 27.6.2012.

Visruth
  • 3,430
  • 35
  • 48
Gasper
  • 959
  • 3
  • 11
  • 29
  • where do you input that five days ??>.. do u have start date and end date kind of thing?? – Kabilan S Jun 12 '12 at 03:11
  • do u mean automatic calulation of the end date with the start date and 5 days given excluding the week ends?? – Kabilan S Jun 12 '12 at 03:12
  • Can you put some more code, showing how do you populate all_new_dates please – Ateszki Jun 12 '12 at 15:03
  • @gašper It would be better to update your question with your code, rather than adding an answer. In your code, where are you declaring / assigning `all_removed_dates` and `all_new_dates`? – Jeffery To Jun 14 '12 at 17:06

5 Answers5

0

First of all this is not generic solution. I didn't have time for generic solution. My solution is if you have to pick 5 days in range without weekends.

in jquery-ui.multidatepicker.js in onSelect method(cca. 81 row) add:

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);
      });                             
}

in jquery-ui.multidatepicker.js in toogleDate method(cca. 431 row) before case 'daysRange' add:

case 'daysRangeWithoutWeekends':

in jquery-ui.multidatepicker.js in setMode(cca. 473row) before case 'daysRange' add:

case 'daysRangeWithoutWeekends':

calander is init with:

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

If anyone make generic algorithm please share it =)

Gasper
  • 959
  • 3
  • 11
  • 29
0

Why don't you try this

methods.addDates.call(obj,all_new_dates);

instead of this

$.each(all_new_dates, function(index, value) { 
     methods.addDates.call(obj,value);
});
Ateszki
  • 2,243
  • 1
  • 16
  • 13
0

Perhaps just looping through and modifying the array contents would work?

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;
}
pete
  • 24,141
  • 4
  • 37
  • 51
0

change the daysRange case with the following code

case 'daysRange':

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++;
}
Adi
  • 1
0

disable only sunday : add in option beforeShowDay: noWeekendsOrHolidays

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

if you have error in console: Error: Empty array of dates received. in jquery-ui.multidatespicker.js looking for "addDates : function( dates, type )" and add 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.');
            }
        },
Vlad
  • 365
  • 3
  • 6