Maxime
Maxime

Reputation: 2234

Ignore Sundays from jQuery date range picker

I'm using the following jQuery date range picker library : http://longbill.github.io/jquery-date-range-picker/

I would like to remove / hide all Sundays from all date range pickers while keeping a normal behavior on the date range pickers.

I tried to do something with beforeShowDay option :

beforeShowDay: function(t) {
  var valid = t.getDay() !== 0; //disable sunday
  var _class = '';
  // var _tooltip = valid ? '' : 'weekends are disabled';
  return [valid, _class];
}

but it only "disables" all Sundays whereas I want to remove / hide them:

The date range pickers with disabled Sundays

Here's the fiddle I'm working on : https://jsfiddle.net/maximelafarie/dnbd01do/11/

EDIT: Updated fiddle with @Swanand code: https://jsfiddle.net/maximelafarie/dnbd01do/18/

Upvotes: 0

Views: 2170

Answers (4)

Maxime
Maxime

Reputation: 2234

I finally ended up by letting the Sundays appear (but completely disabling them).

These questions inspired me :

So I created a function as follows which returns an array that contains the "sundays" (or whatever day you provide as dayNumber parameter) in the date range you selected:

function getDayInRange(dayNumber, startDate, endDate, inclusiveNextDay) {
  var start = moment(startDate),
    end = moment(endDate),
    arr = [];

  // Get "next" given day where 1 is monday and 7 is sunday
  let tmp = start.clone().day(dayNumber);
  if (!!inclusiveNextDay && tmp.isAfter(start, 'd')) {
    arr.push(tmp.format('YYYY-MM-DD'));
  }

  while (tmp.isBefore(end)) {
    tmp.add(7, 'days');
    arr.push(tmp.format('YYYY-MM-DD'));
  }

  // If last day matches the given dayNumber, add it.
  if (end.isoWeekday() === dayNumber) {
    arr.push(end.format('YYYY-MM-DD'));
  }

  return arr;
}

Then I call this function in my code like that:

$('#daterange-2')
  .dateRangePicker(configObject2)
  .bind('datepicker-change', function(event, obj) {

    var sundays = getDayInRange(7, moment(obj.date1), moment(obj.date1).add(selectedDatesCount, 'd'));
    console.log(sundays);

    $('#daterange-2')
      .data('dateRangePicker')
      .setDateRange(obj.value, moment(obj.date1)
        .add(selectedDatesCount + sundays.length, 'd')
        .format('YYYY-MM-DD'), true);
  });

This way, I retrieve the amount of sundays in the date range I selected. For example, if there's two sundays in my selection (with sundays.length), I know I have to set two additional workdays to the user selection (in the second date range picker).

Here's the working result: working result

With the above screenshot, you can see the user selected 4 workdays (5 with sunday but we don't count it). Then he click on the second calendar and the 4 workdays automatically apply.

Here's the result if the period apply over a sunday (we add one supplementary day and Xfor X sundays in the period): other working result

Finally, here's the working fiddle: https://jsfiddle.net/maximelafarie/dnbd01do/21/

I want to thank any person that helped me. The question was hard to explain and to understand.

Upvotes: 1

Swanand Taware
Swanand Taware

Reputation: 753

You need do changes in two functions in your daterangepicker.js file:

  1. createMonthHTML()

        function createMonthHTML(d) { var days = [];
        d.setDate(1);
        var lastMonth = new Date(d.getTime() - 86400000);
        var now = new Date();
        var dayOfWeek = d.getDay();
        if ((dayOfWeek === 0) && (opt.startOfWeek === 'monday')) {
            // add one week
            dayOfWeek = 7;
        }
        var today, valid;
    
        if (dayOfWeek > 0) {
            for (var i = dayOfWeek; i > 0; i--) {
                var day = new Date(d.getTime() - 86400000 * i);
                valid = isValidTime(day.getTime());
                if (opt.startDate && compare_day(day, opt.startDate) < 0) valid = false;
                if (opt.endDate && compare_day(day, opt.endDate) > 0) valid = false;
                days.push({
                    date: day,
                    type: 'lastMonth',
                    day: day.getDate(),
                    time: day.getTime(),
                    valid: valid
                });
            }
        }
        var toMonth = d.getMonth();
        for (var i = 0; i < 40; i++) {
            today = moment(d).add(i, 'days').toDate();
            valid = isValidTime(today.getTime());
            if (opt.startDate && compare_day(today, opt.startDate) < 0) valid = false;
            if (opt.endDate && compare_day(today, opt.endDate) > 0) valid = false;
            days.push({
                date: today,
                type: today.getMonth() == toMonth ? 'toMonth' : 'nextMonth',
                day: today.getDate(),
                time: today.getTime(),
                valid: valid
            });
        }
        var html = [];
        for (var week = 0; week < 6; week++) {
            if (days[week * 7].type == 'nextMonth') break;
            html.push('<tr>');
    
            for (var day = 0; day < 7; day++) {
                var _day = (opt.startOfWeek == 'monday') ? day + 1 : day;
                today = days[week * 7 + _day];
                var highlightToday = moment(today.time).format('L') == moment(now).format('L');
                today.extraClass = '';
                today.tooltip = '';
                if (today.valid && opt.beforeShowDay && typeof opt.beforeShowDay == 'function') {
                    var _r = opt.beforeShowDay(moment(today.time).toDate());
                    today.valid = _r[0];
                    today.extraClass = _r[1] || '';
                    today.tooltip = _r[2] || '';
                    if (today.tooltip !== '') today.extraClass += ' has-tooltip ';
                }
    
                var todayDivAttr = {
                    time: today.time,
                    'data-tooltip': today.tooltip,
                    'class': 'day ' + today.type + ' ' + today.extraClass + ' ' + (today.valid ? 'valid' : 'invalid') + ' ' + (highlightToday ? 'real-today' : '')
                };
    
                if (day === 0 && opt.showWeekNumbers) {
                    html.push('<td><div class="week-number" data-start-time="' + today.time + '">' + opt.getWeekNumber(today.date) + '</div></td>');
                }
                if(day == 0){
                    html.push('<td class="hideSunday"' + attributesCallbacks({}, opt.dayTdAttrs, today) + '><div ' + attributesCallbacks(todayDivAttr, opt.dayDivAttrs, today) + '>' + showDayHTML(today.time, today.day) + '</div></td>');
                }else{
                    html.push('<td ' + attributesCallbacks({}, opt.dayTdAttrs, today) + '><div ' + attributesCallbacks(todayDivAttr, opt.dayDivAttrs, today) + '>' + showDayHTML(today.time, today.day) + '</div></td>');
                }
    
            }
            html.push('</tr>');
        }
        return html.join('');
    }
    

In this function i have added class hideSunday while pushing the element.

The 2nd function is getWeekHead():

function getWeekHead() {
        var prepend = opt.showWeekNumbers ? '<th>' + translate('week-number') + '</th>' : '';
        if (opt.startOfWeek == 'monday') {
            return prepend + '<th>' + translate('week-1') + '</th>' +
                '<th>' + translate('week-2') + '</th>' +
                '<th>' + translate('week-3') + '</th>' +
                '<th>' + translate('week-4') + '</th>' +
                '<th>' + translate('week-5') + '</th>' +
                '<th>' + translate('week-6') + '</th>' +
                '<th class="hideSunday">' + translate('week-7') + '</th>';
        } else {
            return prepend + '<th class="hideSunday">' + translate('week-7') + '</th>' +
                '<th>' + translate('week-1') + '</th>' +
                '<th>' + translate('week-2') + '</th>' +
                '<th>' + translate('week-3') + '</th>' +
                '<th>' + translate('week-4') + '</th>' +
                '<th>' + translate('week-5') + '</th>' +
                '<th>' + translate('week-6') + '</th>';
        }
    }

In this file, I have added class to week-7 header.

CSS:

.hideSunday{display:none;}

Please note, I have not checked all the scenario but it will do trick for you.

Upvotes: 1

Niladri
Niladri

Reputation: 5962

You can also do it by setting a custom css class and use it in beforeShowDay like below

.hideSunDay{
   display:none;
  }

   beforeShowDay: function(t) {
      var valid = t.getDay() !== 0; //disable sunday
      var _class = t.getDay() !== 0 ? '' : 'hideSunDay';   
      // var _tooltip = valid ? '' : 'weekends are disabled';
      return [valid, _class];
    }

But it only hides the sundays beginning from current day.

Here is a working fiddle

https://jsfiddle.net/dnbd01do/16/

Upvotes: 0

user9019817
user9019817

Reputation:

You could do it with just a little CSS but it does leave a gap:

.week-name th:nth-child(7),
.month1 tbody tr td:nth-child(7) {
    display: none;
}

Hope this helps a little.

Upvotes: 1

Related Questions