1
votes

Here I am using the ng bootstrap and angular 6 for the inline date picker. Here I am setting dates programmatically till now its fine but the issue is when I am setting last 7 days to date it has to be displayed from date as 02-9-2018 and to date as 17-09-2018. Here's the problem: as I am displaying the date separate calendar, the "From" date is displayed on calendar 1, and the "To" date on calendar 2.

Now what I am trying to figure out is, how can I display these only one calendar? I mean if last 7 days or last fifteen days or month are in the same month, then it doesn't have to display in another calendar. If it is not in the current month then it has to display 2 dates in different calendars.

Below is my code:

.ts code

dateSelect(event, dpp, dpt) {

  var target = event.target || event.srcElement || event.currentTarget;
  var idAttr = target.attributes.id;
  var value = idAttr.nodeValue;

  if (value == 'seven') {
    var fromDate = {
      'year': "2018",
      'month': "9",
      'day': "10"
    };

    for (let property in fromDate) {
      if (fromDate.hasOwnProperty(property)) {
        fromDate[property] = +fromDate[property];
      }
    }
    this.OneModel = fromDate;
    dpp.navigateTo(this.OneModel);

    this.TwoModel = this.calendar.getToday();
    dpt.navigateTo(this.TwoModel);
    console.log(this.OneModel);
  }

  if (value == 'fifteen') {
    var fromDate = {
      'year': "2018",
      'month': "9",
      'day': "02"
    };

    for (let property in fromDate) {
      if (fromDate.hasOwnProperty(property)) {
        fromDate[property] = +fromDate[property];
      }
    }
    this.OneModel = fromDate;
    dpp.navigateTo(this.OneModel);

    this.TwoModel = this.calendar.getToday();
    dpt.navigateTo(this.TwoModel);
    console.log(this.OneModel);
  }

  if (value == 'thirty') {
    var fromDate = {
      'year': "2018",
      'month': "9",
      'day': "18"
    };

    for (let property in fromDate) {
      if (fromDate.hasOwnProperty(property)) {
        fromDate[property] = +fromDate[property];
      }
    }
    this.OneModel = fromDate;
    dpp.navigateTo(this.OneModel);

    this.TwoModel = this.calendar.getToday();
    dpt.navigateTo(this.TwoModel);
    console.log(this.OneModel);
  }

  if (value == 'month') {
    var fromDate = {
      'year': "2018",
      'month': "9",
      'day': "01"
    };

    for (let property in fromDate) {
      if (fromDate.hasOwnProperty(property)) {
        fromDate[property] = +fromDate[property];
      }
    }
    this.OneModel = fromDate;
    dpp.navigateTo(this.OneModel);

    this.TwoModel = this.calendar.getToday();
    dpt.navigateTo(this.TwoModel);
    console.log(this.OneModel);
  }
}

.html code

<ngb-datepicker #dpp [(ngModel)]="OneModel" (navigate)="dates = $event.next"></ngb-datepicker>
<ngb-datepicker #dpt [(ngModel)]="TwoModel" (navigate)="datess = $event.next"></ngb-datepicker>

<button type="button" class="btn btn-primary btn-space" (click)="dateSelect($event,dpp,dpt)" id="seven">Last 7 Days</button>
<button type="button" class="btn btn-primary btn-space" (click)="dateSelect($event,dpp,dpt)" id="fifteen">Last 15 Days</button>
<button type="button" class="btn btn-primary btn-space" (click)="dateSelect($event,dpp,dpt)" id="thirty">Last 30 Days</button>
<button type="button" class="btn btn-primary btn-space" (click)="dateSelect($event,dpp,dpt)" id="month">This Month</button>

My working stackblitz URL

angular-sfngdu

1

1 Answers

1
votes

The first step is create a custom template day see https://ng-bootstrap.github.io/#/components/datepicker/examples#customday and add a class for you can show some days in diferent background color.

Your customDay can be like

<ng-template #customDay let-date="date" let-currentMonth="currentMonth" let-selected="selected" let-disabled="disabled" let-focused="focused">
  <!--see that you add a class "selected" is a function return true-->
  <span class="custom-day" [class.selected]="isSelectedDate(date)" [class.focused]="focused"
        [class.bg-primary]="selected" [class.fade]="date.month !== currentMonth" [class.text-muted]="disabled">
    {{ date.day }}
  </span>
</ng-template>

In your .css

.custom-day {
      text-align: center;
      padding: 0.185rem 0.25rem;
      border-radius: 0.25rem;
      display: inline-block;
      width: 2rem;
      line-height: 2rem
    }
    .custom-day:hover, .custom-day.focused {
      background-color: #e6e6e6;
    }
    .fade {
      color:Gray;
    }
    .selected {
      background-color:firebrick;
      color: white;
    }

And in your .ts

//This is the function that make a date change the class
isSelectedDate(date:any)
{
  return this.fromDate &&this.toDate? 
     (date.day==this.fromDate.day && date.year==this.fromDate.year && date.month==this.fromDate.month) || 
          (date.day==this.toDate.day && date.year==this.toDate.year && date.month==this.toDate.month):false;
}

Then you must calculate when you show one or two calendar

Update We can improve the function isSelectedDate using equal, before and after. Or, if we want to show all range, replace the function isSelectedDate by isSelectedDayRange

isSelectedDate(date:any)
{
  return this.OneModel &&this.TwoModel? 
           date.equals(this.OneModel) || date.equals(this.TwoModel)
:false;
}
//if you want to "select" a range, you can call to this function 
isSelectedDayRange(date:any)
{
    return this.OneModel && this.TwoModel?
       date.equals(this.OneModel) || date.equals(this.TwoModel) || (date.after(this.OneModel) && date.before(this.TwoModel))
    :false
}