0

I'm working with angular bootstrap datepicker and having some weird issues. When opening the webpage everything looks alright, but when I want to change the date and I click on the calendar button to get the popup calendar it is showing the wrong month, and if I'll click on a date I'll get the date for 1 month forward.

for example, when I'm opening the page on August 8th, the date shows August 8th, and the popup shows the month: Jul, and if I'll choose the 9th I'll get August 9th.

EDIT: Thanks to Pankaj the month in the popup is fixed, but the issue still remains, when picking a date the date picker picks a date that is one month ahead.

picture for example:

enter image description here

this is the HTML code for that particular date picker:

        <div class="input-group">
            <input class="form-control"
                   placeholder="Enter start date"
                   name="dpStart"
                   [(ngModel)]="startDateModel"
                   (ngModelChange)="checkTimes()"
                   ngbDatepicker #startDateInput="ngbDatepicker"
                   required
                   (ngModelChange)  = "autoUpdateEndDate()"
                   [firstDayOfWeek] = 7> <!--##FIRST DAY OF THE WEEK: Sunday-->
          <button class="btn btn-outline-secondary calendar"
                  (click)="startDateInput.toggle()" type="button">

check Time and autoUpdateEndDate are both helper functions that check if the end date is after the start date and set the end date to be the same as the start date under certain conditions.

I would be truly grateful for any lead on the matter...

roy
  • 13
  • 7
  • Can you please share the date you're trying to assign `startDateModel`? basically month should start from `1` in this case for august it should `8` – Pankaj Parkar Aug 08 '22 at 05:29
  • sure! the startDateModel starts with a placeholder: `startDateModel: NgbDateStruct = {year: 1900 , month: 1, day: 1};` and it is overridden in the ngOnInit: `let currentDate = new Date(); this.startDateModel = { year: currentDate.getFullYear(), month: currentDate.getMonth(), day: currentDate.getDate() }; ` – roy Aug 08 '22 at 05:44
  • It should be `currentDate.getMonth() + 1`, because `getMonth()` return month from `0` for `Jan` – Pankaj Parkar Aug 08 '22 at 05:48
  • That did work for changing the month appearing in the popup! so many thanks. but now the default date I'm getting when opening the page is for 1 month forward (so the page is opened with September 8th). I think the main issue is that the displayed date is always 1 month ahead of the popup date. – roy Aug 08 '22 at 05:51
  • Can you reproduce the error in stackblitz? – Pankaj Parkar Aug 08 '22 at 06:05
  • never used it, i can give it a try once again, thanks! I'll update if I'll be able to – roy Aug 08 '22 at 06:07
  • @PankajParkar I'm not sure i'll be able to, there are many many interdependencies in this project. I'm working on it anyway – roy Aug 08 '22 at 06:30

3 Answers3

0

We do not have full visibility to your checkTimes() and autoUpdateEndDate() functions, but it seems like you are directly using the month value from ngb-datepicker within new Date(). As you already know by now, the native month indexes are 1 less than regular count, so you have to reduce that 1 after the selection.

new Date(event.year, event.month - 1, event.day);

You can also combine your ngModelChange() functions in one line

(ngModelChange)="checkTimes($event); autoUpdateEndDate()"

Demo

Nehal
  • 13,130
  • 4
  • 43
  • 59
  • Hello! Thank you very much for your effort. check time and Auto update doesn't do anything that is relevant (one checks that the end date is after the start date, and the other auto set the end date If it was never changed). It does seems to be the issue that i work with date and NgbDateStruct. I got to the point where i think the bug is that the popup it self and the "startDateModel" are using different source for their month, but they are both effected by the +1 change for the month... so the "chosen" date it one month in the future and the pop up month is correct... any ideas? – roy Aug 09 '22 at 10:51
  • Can't help much with the above description, you can use my stackblitz reproducing the issue you are having, Then I might be able to provide some feedback. To address last part of your comment, the 'Chosen' month IS a month ahead because of the +1, and my answer specifically instructs you to subtract that +1 from the selected date. Your `startDateModel ` and chosen date cannot be the same variable, as one needs to use +1 for display purpose, and the other one needs to be without +1 to calculate the correct date. – Nehal Aug 09 '22 at 14:30
  • Thank you very much for your help! I have found the issue and it was in some "middleware" that formatted the date using moment js (answered below) – roy Aug 10 '22 at 04:57
0

EDIT: In addition to the main fix that is below, a change was also needed in assigning the date into startDateModel, i worked with new Date and it wasn't working well. so i needed to add calender: NgbCalendar to the constructor, and set start date to calender.getToday() (and break it down to month day year for the NgbDataStruct)

I finally found the issue.

The issue was rooted in a "date parser formatter" I add . in which I got the date (as NgbDateStruct) and formated it using moment:

format(date: NgbDateStruct): string { return date ? moment(date).format("MMM Do yyyy"): " ";

and that made the issue, i'm not sure how moment tried to parse the NgbDateStruct, but i think it was doing great job other then that moment (and Date) is 0 based month and NgbDateStruct is 1 based month.

so the fix was changing

return date ? moment(date).subtract(1, "month").format("MMM Do yyyy"): " ";

for quite a hard fix.

or a better solution is letting moment do his parsing: return date ? moment([date.month , date.day , date.year], "MM-DD-yyyy").format("MMM Do yyyy"): " ";

Thank you all for all your help!

roy
  • 13
  • 7
0

Use [startDate] and assign the value in ts file.

<input type="text" readonly formControlName="date_of_birth [startDate]="dateOfBirth" ngbDatepicker (click)="d.toggle()" #d="ngbDatepicker" (dateSelect)="onDateSelect($event)" placement="top"
    class="form-control mb-2" placeholder="Date of Brith" />

Assign ngb object to startdate and it will show the selected value.

  dateOfBirth = {
    day: new Date().getUTCDate(),
    month: new Date().getUTCMonth() + 1,
    year: new Date().getUTCFullYear() - 16,
  };
 onDateSelect(ngbDate) {
    this.dateOfBirth = ngbDate
  }

Use startdate to show the selected value.

majid
  • 23
  • 8