Skip to content
This repository was archived by the owner on Mar 2, 2018. It is now read-only.

Commit 87ca9e2

Browse files
committed
issue #152 added show-week-numbers feature
1 parent 6908984 commit 87ca9e2

File tree

5 files changed

+145
-69
lines changed

5 files changed

+145
-69
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ please send me email to `allenhwkim AT gmail.com` with your github id.
180180
* **min-hour** number, mininum selectable hour
181181
* **max-hour** number, maximum selectable hour
182182
* **disabled-dates** Array of Date, dates not selectable
183+
* **show-week-numbers** trueor false, default false. Show week numbers
183184

184185
## Outputs of directive
185186

app/directive-test.component.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ var templateStr = `
2020
[min-date]="date2MinDate"
2121
[max-date]="date2MaxDate"
2222
[show-close-layer]="true"
23+
[show-week-numbers]="true"
2324
date-only="true"/>
2425
date2: {{date2}}
2526
<button id="set-date" (click)="date2 = date2New">Set 2017-12-31</button>

src/ng2-datetime-picker.component.ts

Lines changed: 99 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -38,46 +38,56 @@ declare var moment: any;
3838
<b class="prev_next next month" (click)="updateMonthData(+1)">&rsaquo;</b>
3939
</div>
4040
41-
<!-- Date -->
42-
<div class="days" *ngIf="!timeOnly">
43-
44-
<!-- Su Mo Tu We Th Fr Sa -->
45-
<div class="day-of-week"
46-
*ngFor="let dayOfWeek of monthData.localizedDaysOfWeek; let ndx=index"
47-
[class.weekend]="isWeekend(ndx + monthData.firstDayOfWeek)"
48-
title="{{dayOfWeek.fullName}}">
49-
{{dayOfWeek.shortName}}
50-
</div>
51-
52-
<!-- Fill up blank days for this month -->
53-
<div *ngIf="monthData.leadingDays.length < 7">
54-
<div class="day"
55-
(click)="updateMonthData(-1)"
56-
*ngFor="let dayNum of monthData.leadingDays">
57-
{{dayNum}}
41+
<div class="week-numbers-and-days"
42+
[ngClass]="{'show-week-numbers': !timeOnly && showWeekNumbers}">
43+
<!-- Week -->
44+
<div class="week-numbers" *ngIf="!timeOnly && showWeekNumbers">
45+
<div class="week-number" *ngFor="let weekNumber of monthData.weekNumbers">
46+
{{weekNumber}}
5847
</div>
5948
</div>
49+
50+
<!-- Date -->
51+
<div class="days" *ngIf="!timeOnly">
52+
53+
<!-- Su Mo Tu We Th Fr Sa -->
54+
<div class="day-of-week"
55+
*ngFor="let dayOfWeek of monthData.localizedDaysOfWeek; let ndx=index"
56+
[class.weekend]="isWeekend(ndx + monthData.firstDayOfWeek)"
57+
title="{{dayOfWeek.fullName}}">
58+
{{dayOfWeek.shortName}}
59+
</div>
6060
61-
<div class="day"
62-
*ngFor="let dayNum of monthData.days"
63-
(click)="selectDateTime(toDate(dayNum))"
64-
title="{{monthData.year}}-{{monthData.month+1}}-{{dayNum}}"
65-
[ngClass]="{
66-
selectable: !isDateDisabled(toDate(dayNum)),
67-
selected: toDate(dayNum).getTime() === toDateOnly(selectedDate).getTime(),
68-
today: toDate(dayNum).getTime() === today.getTime(),
69-
weekend: isWeekend(dayNum, monthData.month)
70-
}">
71-
{{dayNum}}
72-
</div>
61+
<!-- Fill up blank days for this month -->
62+
<div *ngIf="monthData.leadingDays.length < 7">
63+
<div class="day"
64+
(click)="updateMonthData(-1)"
65+
*ngFor="let dayNum of monthData.leadingDays">
66+
{{dayNum}}
67+
</div>
68+
</div>
7369
74-
<!-- Fill up blank days for this month -->
75-
<div *ngIf="monthData.trailingDays.length < 7">
7670
<div class="day"
77-
(click)="updateMonthData(+1)"
78-
*ngFor="let dayNum of monthData.trailingDays">
71+
*ngFor="let dayNum of monthData.days"
72+
(click)="selectDateTime(toDate(dayNum))"
73+
title="{{monthData.year}}-{{monthData.month+1}}-{{dayNum}}"
74+
[ngClass]="{
75+
selectable: !isDateDisabled(toDate(dayNum)),
76+
selected: toDate(dayNum).getTime() === toDateOnly(selectedDate).getTime(),
77+
today: toDate(dayNum).getTime() === today.getTime(),
78+
weekend: isWeekend(dayNum, monthData.month)
79+
}">
7980
{{dayNum}}
8081
</div>
82+
83+
<!-- Fill up blank days for this month -->
84+
<div *ngIf="monthData.trailingDays.length < 7">
85+
<div class="day"
86+
(click)="updateMonthData(+1)"
87+
*ngFor="let dayNum of monthData.trailingDays">
88+
{{dayNum}}
89+
</div>
90+
</div>
8191
</div>
8292
</div>
8393
@@ -92,20 +102,24 @@ declare var moment: any;
92102
<span class="timeValue">
93103
{{("0"+hour).slice(-2)}} : {{("0"+minute).slice(-2)}}
94104
</span><br/>
95-
<label class="hourLabel">{{locale.hour}}:</label>
96-
<input #hours class="hourInput"
97-
tabindex="90000"
98-
(change)="selectDateTime()"
99-
type="range"
100-
min="{{minHour || 0}}"
101-
max="{{maxHour || 23}}"
102-
[(ngModel)]="hour" />
103-
<label class="minutesLabel">{{locale.minute}}:</label>
104-
<input #minutes class="minutesInput"
105-
tabindex="90000"
106-
step="{{minuteStep}}"
107-
(change)="selectDateTime()"
108-
type="range" min="0" max="59" range="10" [(ngModel)]="minute"/>
105+
<div>
106+
<label class="hourLabel">{{locale.hour}}:</label>
107+
<input #hours class="hourInput"
108+
tabindex="90000"
109+
(change)="selectDateTime()"
110+
type="range"
111+
min="{{minHour || 0}}"
112+
max="{{maxHour || 23}}"
113+
[(ngModel)]="hour" />
114+
</div>
115+
<div>
116+
<label class="minutesLabel">{{locale.minute}}:</label>
117+
<input #minutes class="minutesInput"
118+
tabindex="90000"
119+
step="{{minuteStep}}"
120+
(change)="selectDateTime()"
121+
type="range" min="0" max="59" range="10" [(ngModel)]="minute"/>
122+
</div>
109123
</div>
110124
</div>
111125
`,
@@ -143,6 +157,9 @@ declare var moment: any;
143157
animation: slideDown 0.1s ease-in-out;
144158
animation-fill-mode: both;
145159
}
160+
.ng2-datetime-picker .days {
161+
width: 210px; /* 30 x 7 days */
162+
}
146163
.ng2-datetime-picker .close-button {
147164
position: absolute;
148165
width: 1em;
@@ -166,6 +183,7 @@ declare var moment: any;
166183
border-bottom: 1px solid #ddd;
167184
position: relative;
168185
}
186+
169187
.ng2-datetime-picker > .month > .prev_next {
170188
color: #555;
171189
display: block;
@@ -187,46 +205,61 @@ declare var moment: any;
187205
.ng2-datetime-picker > .month > .prev_next.next {
188206
float: right;
189207
}
190-
.ng2-datetime-picker > .days {
208+
209+
.ng2-datetime-picker .week-numbers-and-days {
210+
text-align: center;
211+
}
212+
.ng2-datetime-picker .week-numbers {
213+
line-height: 30px;
214+
display: inline-block;
215+
padding: 30px 0 0 0;
216+
color: #ddd;
217+
text-align: right;
218+
width: 21px;
219+
vertical-align: top;
220+
}
221+
222+
.ng2-datetime-picker .days {
223+
display: inline-block;
191224
width: 210px; /* 30 x 7 */
192-
margin: 10px;
193225
text-align: center;
226+
padding: 0 10px;
194227
}
195-
.ng2-datetime-picker > .days .day-of-week,
196-
.ng2-datetime-picker > .days .day {
228+
.ng2-datetime-picker .days .day-of-week,
229+
.ng2-datetime-picker .days .day {
197230
box-sizing: border-box;
198231
-moz-box-sizing: border-box;
199232
border: 1px solid transparent;
200233
width: 30px;
201234
line-height: 28px;
202235
float: left;
203236
}
204-
.ng2-datetime-picker > .days .day-of-week {
237+
.ng2-datetime-picker .days .day-of-week {
205238
font-weight: bold;
206239
}
207-
.ng2-datetime-picker > .days .day-of-week.weekend {
240+
.ng2-datetime-picker .days .day-of-week.weekend {
208241
color: #ccc;
209242
background-color: inherit;
210243
}
211-
.ng2-datetime-picker > .days .day:not(.selectable) {
244+
.ng2-datetime-picker .days .day:not(.selectable) {
212245
color: #ccc;
213246
cursor: default;
214247
}
215-
.ng2-datetime-picker > .days .weekend {
248+
.ng2-datetime-picker .days .weekend {
216249
color: #ccc;
217250
background-color: #eee;
218251
}
219-
.ng2-datetime-picker > .days .day.selectable {
252+
.ng2-datetime-picker .days .day.selectable {
220253
cursor: pointer;
221254
}
222-
.ng2-datetime-picker > .days .day.selected {
255+
.ng2-datetime-picker .days .day.selected {
223256
background: gray;
224257
color: #fff;
225258
}
226-
.ng2-datetime-picker > .days .day:not(.selected).selectable:hover {
259+
.ng2-datetime-picker .days .day:not(.selected).selectable:hover {
227260
background: #eee;
228261
}
229-
.ng2-datetime-picker > .days:after {
262+
.ng2-datetime-picker .days:after {
230263
content: '';
231264
display: block;
232265
clear: left;
@@ -248,13 +281,9 @@ declare var moment: any;
248281
.ng2-datetime-picker .hourLabel,
249282
.ng2-datetime-picker .minutesLabel {
250283
display: inline-block;
251-
width: 40px;
252-
text-align: right;
284+
width: 45px;
285+
vertical-align: top;
253286
}
254-
.ng2-datetime-picker input[type=range] {
255-
width: 200px;
256-
}
257-
258287
.closing-layer {
259288
display: block;
260289
position: fixed;
@@ -282,11 +311,13 @@ declare var moment: any;
282311
bottom: 0;
283312
left: 0;
284313
right: 0;
314+
width: auto !important;
285315
animation: slideUp 0.1s ease-in-out;
286316
}
287317
288-
.ng2-datetime-picker .days {
289-
margin: 10px auto;
318+
.ng2-datetime-picker > .days {
319+
display: block;
320+
margin: 0 auto;
290321
}
291322
292323
.closing-layer {
@@ -319,6 +350,7 @@ export class Ng2DatetimePickerComponent {
319350
@Input('disabled-dates') disabledDates: Date[];
320351
@Input('show-close-button') showCloseButton: boolean;
321352
@Input('show-close-layer') showCloseLayer: boolean;
353+
@Input('show-week-numbers') showWeekNumbers: boolean = false;
322354
@Input('show-today-shortcut') showTodayShortcut: boolean = false;
323355

324356
@Output('selected$') selected$:EventEmitter<any> = new EventEmitter();

src/ng2-datetime-picker.directive.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ export class Ng2DatetimePickerDirective implements OnInit, OnChanges {
4646
@Input('max-hour') maxHour: Date | number;
4747
@Input('disabled-dates') disabledDates: Date[];
4848
@Input('show-close-layer') showCloseLayer: boolean;
49+
@Input('show-week-numbers') showWeekNumbers: boolean;
4950
@Input() formControlName: string;
5051

5152
@Input('ngModel') ngModel: any;
@@ -270,6 +271,7 @@ export class Ng2DatetimePickerDirective implements OnInit, OnChanges {
270271
component.disabledDates = this.disabledDates;
271272
component.showCloseButton = this.closeOnSelect === false;
272273
component.showCloseLayer = this.showCloseLayer;
274+
component.showWeekNumbers = this.showWeekNumbers;
273275

274276
this.styleDatetimePicker();
275277

@@ -318,7 +320,7 @@ export class Ng2DatetimePickerDirective implements OnInit, OnChanges {
318320
private styleDatetimePicker () {
319321
// setting position, width, and height of auto complete dropdown
320322
let thisElBCR = this.el.getBoundingClientRect();
321-
this.ng2DatetimePickerEl.style.width = thisElBCR.width + 'px';
323+
// this.ng2DatetimePickerEl.style.minWidth = thisElBCR.width + 'px';
322324
this.ng2DatetimePickerEl.style.position = 'absolute';
323325
this.ng2DatetimePickerEl.style.zIndex = '1000';
324326
this.ng2DatetimePickerEl.style.left = '0';

src/ng2-datetime.ts

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,33 @@ export class Ng2Datetime {
113113
}
114114
}
115115

116+
static getWeekNumber(date) {
117+
if (!(date instanceof Date)) date = new Date();
118+
119+
// ISO week date weeks start on Monday, so correct the day number
120+
var nDay = (date.getDay() + 6) % 7;
121+
122+
// ISO 8601 states that week 1 is the week with the first Thursday of that year
123+
// Set the target date to the Thursday in the target week
124+
date.setDate(date.getDate() - nDay + 3);
125+
126+
// Store the millisecond value of the target date
127+
var n1stThursday = date.valueOf();
128+
129+
// Set the target to the first Thursday of the year
130+
// First, set the target to January 1st
131+
date.setMonth(0, 1);
132+
133+
// Not a Thursday? Correct the date to the next Thursday
134+
if (date.getDay() !== 4) {
135+
date.setMonth(0, 1 + ((4 - date.getDay()) + 7) % 7);
136+
}
137+
138+
// The week number is the number of weeks between the first Thursday of the year
139+
// and the Thursday in the target week (604800000 = 7 * 24 * 3600 * 1000)
140+
return 1 + Math.ceil((n1stThursday - date) / 604800000);
141+
}
142+
116143
//remove timezone
117144
private static removeTimezone(dateStr): string {
118145
// if no time is given, add 00:00:00 at the end
@@ -171,10 +198,22 @@ export class Ng2Datetime {
171198
trailingDays = trailingDays.slice(0, trailingDays.length - 7);
172199
}
173200

201+
let firstDay = new Date(firstDayOfMonth);
202+
firstDay.setDate(firstDayOfMonth.getDate() - (leadingDays % 7));
203+
let firstWeekNumber = Ng2Datetime.getWeekNumber(firstDay);
204+
let numWeeks = Math.ceil((daysInMonth + leadingDays%7) / 7);
205+
let weekNumbers =Array(numWeeks).fill(0).map(
206+
(el,ndx) => {
207+
let weekNum = (ndx + firstWeekNumber + 52) % 52;
208+
return weekNum === 0 ? 52 : weekNum;
209+
}
210+
);
211+
174212
let localizedDaysOfWeek =
175213
Ng2Datetime.daysOfWeek
176214
.concat(Ng2Datetime.daysOfWeek)
177215
.splice(Ng2Datetime.firstDayOfWeek, 7);
216+
178217

179218
let monthData = {
180219
year: year,
@@ -186,7 +225,8 @@ export class Ng2Datetime {
186225
localizedDaysOfWeek: localizedDaysOfWeek,
187226
days: Ng2Datetime.days.slice(0, daysInMonth),
188227
leadingDays: Ng2Datetime.days.slice(-leadingDays - (31 - daysInLastMonth), daysInLastMonth),
189-
trailingDays: trailingDays
228+
trailingDays: trailingDays,
229+
weekNumbers: weekNumbers
190230
};
191231

192232
return monthData;

0 commit comments

Comments
 (0)