Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
Tags
- 앵귤러 모달
- egov spring ajax 사용 예시
- Oracle LISTAGG 사용 예시
- modal
- flex-1
- 모달
- summary
- formgroup
- 아이오닉 스크롤 이벤트
- angular button
- 셀렉트박스 커스텀
- 검색
- Router
- ajax 사용 예시
- Angular Router
- 호버
- 스크롤 이벤트 감지
- mysql if
- scroll
- route
- prisma
- 스크롤 이벤트
- angular route
- angular modal
- Ionic modal
- TAILWIND
- 앵귤러 애니메이션
- ApexChart
- angular animation
- 옵저버블
Archives
- Today
- Total
깜놀하는 해므찌로
Angular input-date component 활용 예시 본문
반응형
SMALL
<div
class="relative flex w-full"
[class]="class"
(outside)="isOpen = false"
appClickOutside
>
<div
class="flex w-full items-center shadow-sm border-2 px-3 py-2 border-gray-200 hover:border-gray-400 focus-within:border-gray-400 focus-within:border-2 rounded-md cursor-pointer"
(click)="isOpen = !isOpen"
>
<input
class="text-sm whitespace-nowrap"
(keyup)="keyup($event)"
[value]="(value | date : 'yyyy-MM-dd') ?? label"
class="w-full text-sm transition-all outline-none"
readonly
/>
<app-icon name="material-symbols:calendar-today-outline" class="w-5 h-5" />
</div>
<app-date-picker
*ngIf="isOpen"
class="absolute left-0 z-50 top-[calc(100%+0.25rem)]"
[ngModel]="value"
(selected)="isOpen = false"
(selectedDate)="writeValue($event)"
></app-date-picker>
</div>
import { CommonModule } from '@angular/common';
import {
AfterViewInit,
Component,
ElementRef,
EventEmitter,
Input,
Optional,
Output,
Self,
ViewChild,
} from '@angular/core';
import { FormsModule, NgControl } from '@angular/forms';
import * as dayjs from 'dayjs';
import { debounceTime, fromEvent } from 'rxjs';
import { CustomValueAccessor } from 'src/app/components/custom-value-accessor';
import { DatePickerComponent } from 'src/app/components/date-picker/date-picker.component';
import { ClickOutsideDirective } from '../derectives/directives/click-outside.directive';
import { IconComponent } from '../icon/icon.component';
@Component({
selector: 'app-input-date',
templateUrl: './input-date.component.html',
styleUrls: ['./input-date.component.scss'],
standalone: true,
imports: [
DatePickerComponent,
CommonModule,
IconComponent,
FormsModule,
ClickOutsideDirective,
],
})
export class InputDateComponent
extends CustomValueAccessor<Date>
implements AfterViewInit
{
@ViewChild('input') input: ElementRef<HTMLInputElement> | undefined;
@Output() selectedDate: EventEmitter<Date> = new EventEmitter<Date>();
@Input() label?: string;
@Input() type?: 'text' | 'password' = 'text';
@Input() maxlength?: string | number = 0;
@Input() override required: boolean = false;
@Input() class!: string;
isOpen: boolean = false;
constructor(
@Self() @Optional() private ngControl: NgControl,
private outArea: ElementRef<HTMLDivElement>
) {
super();
if (this.ngControl) this.ngControl.valueAccessor = this;
}
ngOnInit() {}
ngAfterViewInit(): void {
this.change();
}
change() {
if (this.input) {
this.input.nativeElement.value = dayjs(this.value).format('YYYY-MM-DD');
}
}
keyup(ev: any) {
if (this.input) {
fromEvent(this.input.nativeElement, 'keyup')
.pipe(debounceTime(1000))
.subscribe({
next: () => this.writeValue(dayjs(ev.target.value).toDate()),
});
}
}
}
1. input-date 템플릿과 컴포넌트
<div
id="date-range"
class="fade-in z-[100] flex w-max flex-col gap-2.5 rounded border-2 border-primary-600 bg-white p-3 text-sm shadow-md"
>
<div class="flex items-center justify-between text-gray-500 select-none">
<div
class="flex items-center p-2 rounded cursor-pointer hover:bg-gray-100"
(click)="prevYear()"
>
<app-icon class="w-3 h-3" name="heroicons:chevron-double-left"></app-icon>
</div>
<div
class="flex items-center p-2 rounded cursor-pointer hover:bg-gray-100"
(click)="prevMonth()"
>
<app-icon class="w-3 h-3" name="heroicons:chevron-left"></app-icon>
</div>
<div class="text-gray-600">{{ selectedMonth.format("YYYY년 MM월") }}</div>
<div
class="flex items-center p-2 rounded cursor-pointer hover:bg-gray-100"
(click)="nextMonth()"
>
<app-icon class="w-3 h-3" name="heroicons:chevron-right"></app-icon>
</div>
<div
class="flex items-center p-2 rounded cursor-pointer hover:bg-gray-100"
(click)="nextYear()"
>
<app-icon
class="w-3 h-3"
name="heroicons:chevron-double-right"
></app-icon>
</div>
</div>
<div class="w-full h-px bg-gray-100"></div>
<div class="flex items-center justify-between w-full px-3 py-1 pb-0">
<div class="text-danger">일</div>
<div>월</div>
<div>화</div>
<div>수</div>
<div>목</div>
<div>금</div>
<div class="text-primary">토</div>
</div>
<div class="grid items-center grid-cols-7 pb-0">
<ng-container *ngFor="let day of days">
<div
class="min-w-max cursor-pointer rounded p-2.5 py-2"
[ngClass]="setStyle(day)"
(click)="handleSelectDate(day)"
>
{{ day.format("DD") }}
</div>
</ng-container>
</div>
</div>
import {
Component,
EventEmitter,
Input,
OnInit,
Optional,
Output,
Self,
} from '@angular/core';
import { NgControl } from '@angular/forms';
import * as dayjs from 'dayjs';
import { BehaviorSubject } from 'rxjs';
import { CustomValueAccessor } from 'src/app/components/custom-value-accessor';
import { IconComponent } from '../icon/icon.component';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-date-picker',
templateUrl: './date-picker.component.html',
styleUrls: ['./date-picker.component.scss'],
standalone: true,
imports: [IconComponent, CommonModule],
})
export class DatePickerComponent
extends CustomValueAccessor<Date>
implements OnInit
{
@Input() keyupDate: BehaviorSubject<Date> = new BehaviorSubject(new Date());
@Output() selected: EventEmitter<void> = new EventEmitter();
@Output() selectedDate: EventEmitter<Date> = new EventEmitter<Date>();
selectedMonth: dayjs.Dayjs = dayjs();
days: dayjs.Dayjs[] = [];
constructor(@Self() @Optional() private ngControl: NgControl) {
super();
if (this.ngControl) this.ngControl.valueAccessor = this;
}
ngOnInit() {
this.setDays();
this.keyupDate.subscribe((res: Date) => {
this.value = dayjs(res).toDate();
this.selectedMonth = dayjs(res);
this.setDays();
});
}
prevYear() {
this.selectedMonth = dayjs(this.selectedMonth).subtract(1, 'year');
this.setDays();
}
prevMonth() {
this.selectedMonth = dayjs(this.selectedMonth).subtract(1, 'month');
this.setDays();
}
nextYear() {
this.selectedMonth = dayjs(this.selectedMonth).add(1, 'year');
this.setDays();
}
nextMonth() {
this.selectedMonth = dayjs(this.selectedMonth).add(1, 'month');
this.setDays();
}
setDays() {
this.days = [];
const firstDay = this.selectedMonth.startOf('month');
const lastDay = dayjs(this.selectedMonth).daysInMonth();
for (let i = 0; i < firstDay.day(); i++) {
this.days.push(
this.selectedMonth.startOf('month').subtract(i + 1, 'day')
);
}
this.days.reverse();
for (let i = 0; i < lastDay; i++) {
this.days.push(this.selectedMonth.startOf('month').add(i, 'day'));
}
for (
let i = 0;
i < 6 - dayjs(this.selectedMonth).endOf('month').day();
i++
) {
this.days.push(this.selectedMonth.endOf('month').add(i + 1, 'day'));
}
}
setStyle = (day: any) => {
let style = '';
if (day.format('YY-MM-DD') === dayjs(this.value).format('YY-MM-DD')) {
style += 'bg-primary text-white';
} else if (dayjs(this.selectedMonth).month() !== day.month()) {
style += 'hover:bg-gray-100 text-gray-400';
} else if (day.day() === 0) {
style += 'hover:bg-gray-100 text-danger';
} else if (day.day() === 6) {
style += 'hover:bg-gray-100 text-primary';
} else {
style += 'bg-white hover:bg-gray-100 text-gray-500';
}
return style;
};
handleSelectDate = (day: any) => {
if (dayjs(this.selectedMonth).month() > day.month()) {
this.prevMonth();
} else if (dayjs(this.selectedMonth).month() < day.month()) {
this.nextMonth();
}
this.writeValue(dayjs(day).toDate());
this.selectedDate.emit(dayjs(day).toDate());
this.selected.emit();
};
}
2. datepiker 템플릿과 컴포넌트
<app-input-date
class="flex-1"
label="시작일"
[(ngModel)]="startAt"
(ngModelChange)="searchCondition()"
/>
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import * as dayjs from 'dayjs';
imports: [
FormsModule,
ReactiveFormsModule,
],
startAt: Date = MONTH_BEFORE;
endAt: Date = TODAY;
export const TODAY = new Date();
export const MONTH_BEFORE = dayjs().subtract(1, 'month').toDate();
3. input-date 컴포넌트를 가져와서 사용하는 예시
반응형
LIST
'IT' 카테고리의 다른 글
Angular Ionic 스크롤 이벤트 감지 / Angular animation 앵귤러 애니메이션 (0) | 2023.06.26 |
---|---|
Typescript 배열 중복 제거 (0) | 2023.06.25 |
Angular Toast IONIC토스트 활용 예시 (0) | 2023.06.23 |
Angular router params 데이터 받기 예시 (0) | 2023.06.23 |
Angular Typescript 날짜 비교 (0) | 2023.06.22 |