1576655655
Material Design features pretty cool widgets for date range selection, but if you are just like me, a curious learner, you could implement a widget like that with some CSS/HTML and TypeScript.
Let’s constrain ourselves with a use case that I found and helped to resolve at Stack Overflow which had the following criteria:
At a high level, there seem to be a few components here:
Implement all components mentioned above with the first iteration to roughly position everything.
<div class="outerCard">
<div class="topPanel">
<button class="prevYearButton">
<i class="arrow left"></i>
</button>
<span class="yearLabel">CURRENT YEAR</span>
<button class="nextYearButton">
<i class="arrow right"></i>
</button>
</div>
<div class="contentPanel">
<div class="monthItem">
<div class="monthItemHighlight">
MON
</div>
</div>
</div>
</div>
As seen above, we created basic elements and added classes according to the components we mentioned. Now, let’s add some CSS to make it all look close to what we need:
.outerCard {
touch-action: none;
overflow: hidden;
width: 400px;
height: 400px;
box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);
}
.topPanel {
width: 400px;
height: 50px;
text-align: center;
line-height: 50px;
}
.prevYearButton {
float: left;
}
.nextYearButton {
float: right;
}
button {
width: 50px;
height: 50px;
background:none;
border:none;
margin:0;
padding:0;
cursor: pointer;
}
button:focus {outline:0;}
i {
border: solid black;
border-width: 0 3px 3px 0;
display: inline-block;
padding: 6px;
}
.right {
transform: rotate(-45deg);
-webkit-transform: rotate(-45deg);
}
.left {
transform: rotate(135deg);
-webkit-transform: rotate(135deg);
}
.topPanel.yearLabel {
display: inline-block;
margin: 0 auto;
}
.contentPanel {
padding: 24px 8px;
}
.monthItem {
display: inline-block;
height: 64px;
width: 64px;
cursor: pointer;
text-align: center;
line-height: 64px;
margin-top: 1px;
margin-bottom: 1px;
}
Some highlights of the above:
touch-action: none
to prevent default actions such as text select. Since we will add listeners ourselves, this makes interaction with the component cleaner.text-align
, line-height
, and margin: 0 auto
magic to position text elements horizontally and vertically centered.inline-block
— this helps to render all 24 months line-by-line, forming a table-like view (without actually creating a table), this way our months are just an ordered list and we do not have to worry about actual rows and columns.Let’s add some TypeScript and let’s also use *ngFor
in our template to replicate all 24 months and see what things look like:
.import { Component } from '@angular/core';
@Component({
selector: 'month-picker',
templateUrl: 'month-picker.component.html',
styleUrls: ['month-picker.component.scss']
})
export class MonthPickerComponent {
years: Array<number>;
months: Array<string>;
ngOnInit() {
this.years = [ 2018, 2019, 2020, 2021, 2022, 2023, 2024 ];
this.months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
}
}
We declare properties with their type and we initialize the values inside the ngOnInit
Hook. Let’s not worry about these being “hardcoded” for now. It is indeed a tech debt and we will deal with it later in the article.
<div class="outerCard">
<div class="topPanel">
<button class="prevYearButton">
<i class="arrow left"></i>
</button>
<span class="yearLabel">{{ years[0] }}</span>
<button class="nextYearButton">
<i class="arrow right"></i>
</button>
</div>
<div class="contentPanel">
<div class="monthItem" *ngFor="let month of months">
<div class="monthItemHighlight">
{{ month }}
</div>
</div>
</div>
</div>
Our template is now a thing, but we need to start working on the next set of challenges here:
label
?)First, let’s create monthsData
property that will store the list of all the months with their current state:
monthsData: Array<{
monthName: string,
monthYear: number,
isInRange: boolean,
isLowerEdge: boolean,
isUpperEdge: boolean
}>
It is an array of objects (Month) that can help us track important states. Next, we will create the list of all the months for all the years we have so far (2018–2024):
initMonthsData() {
this.monthsData = new Array();
this.years.forEach( year => {
this.months.forEach( month => {
this.monthsData.push({
monthName: month,
monthYear: year,
isInRange: false,
isLowerEdge: false,
isUpperEdge: false
})
})
})
}
ngOnInit() {
this.years = [ 2018, 2019, 2020, 2021, 2022, 2023, 2024 ];
this.months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
this.initMonthsData();
}
In the snippet above, we are iterating over our initial months
and years
properties to create our monthsData
array in its initial state. Since we might need to use such a data “reset” in our component, we wrapped this operation inside the initMonthsData
method.
Next, we can update our view (HTML) to read from this entire (huge) list:
<div class="contentPanel">
<div class="monthItem" *ngFor="let month of monthsData">
<div class="monthItemHighlight">
{{ month.monthName }}
</div>
</div>
</div>
OK, good stuff. Next, we need a simple way to track the state of our range
, for this I chose (you will see later on why) to use a simple array with two values representing the indexes of a chosen “range start” month and “range end” month:
rangeIndexes: Array<number>;
initRangeIndexes() {
this.rangeIndexes = [ null, null ];
};
The null value is intentional and will help us track the range’s state. As with our monthsData
— we are adding this method into our ngOnInit
Hook.
Alright, now we need to add a method that we will call each time a user clicks on a month:
onClick(indexClicked) {
if (this.rangeIndexes[0] === null) {
this.rangeIndexes[0] = indexClicked;
} else
if (this.rangeIndexes[1] === null) {
this.rangeIndexes[1] = indexClicked;
this.rangeIndexes.sort((a,b) => a-b);
this.monthsData.forEach((month, index) => {
if ((this.rangeIndexes[0] <= index) && (index <= this.rangeIndexes[1])) {
month.isInRange = true;
};
if (this.rangeIndexes[0] === index) {
month.isLowerEdge = true;
};
if (this.rangeIndexes[1] === index) {
month.isUpperEdge = true;
};
})
} else {
this.initRangeIndexes();
this.initMonthsData();
this.onClick(indexClicked);
};
}
The logic here should be straightforward:
rangeIndexes
.Alright, the above gives us data model changes but our widget does not yet handle any changes based on model changes. We will leverage ngClass
to bind data states to the CSS classes that will help alter the view:
<div class="outerCard">
<div class="topPanel">
<button class="prevYearButton">
<i class="arrow left"></i>
</button>
<span class="yearLabel">{{ years[0] }}</span>
<button class="nextYearButton">
<i class="arrow right"></i>
</button>
</div>
<div class="contentPanel">
<div (click)="onClick(i)" class="monthItem" *ngFor="let month of monthsData; let i = index" [ngClass]="{ isEdge: rangeIndexes[0]===i || rangeIndexes[1]===i }">
<div class="monthItemHighlight" [ngClass]="{ inRange: month.isInRange, isLowerEdge: month.isLowerEdge, isUpperEdge: month.isUpperEdge }">
{{ month.monthName }}
</div>
</div>
</div>
</div>
The isEdge
class will now be auto-added to our month at .monthItem
level if it equals the index of our range edges.
Month highlight is a bit trickier: here we need to know which month represents the lower edge vs. the upper edge as the class we are adding is specific — we are using the “gradient” CSS trick to only color one half of the highlight div.
See the full CSS classes here:
.monthItem:hover {
border-radius: 100%;
background-color: #1474a4;
color: white;
}
.isEdge {
border-radius: 100%;
background-color: #1474a4;
color: white;
}
.inRange {
background-color: #1474a4;
opacity: 0.5;
color: white;
}
.isLowerEdge {
background-color: none;
background: linear-gradient(to right, transparent 50%, #1474a4 50%);
}
.isUpperEdge {
background-color: none;
background: linear-gradient(to right, #1474a4 50%, transparent 50%);
}
Cool, now our range is sort of operational, we can actually select a range of months. Still, three problems remain for us to solve:
Let’s push for the last few steps, we are almost there!
Since we need to display 6+12+6 = 24 months for each year, I decided to leverage the Array.slice
method and periodically slice our source of truth (monthsData
) and display it to our user, which will require new functionality and some refactoring for what we already created:
initViewSlices
).monthsData
array as well as new methods for our arrow buttons to increment/decrement the current year in the view.[ngClass]
changes to our template.It seems like a lot. Let’s start:
initYearLabels() {
const currentYear = (new Date()).getFullYear();
const range = (start, stop, step) => Array.from({ length: (stop - start) / step + 1}, (_, i) => start + (i * step));
this.years = range(currentYear-1, currentYear + 5, 1)
};
initMonthLabels() {
this.months = new Array(12).fill(0).map((_, i) => {
return new Date(`${i + 1}/1`).toLocaleDateString(undefined, {month: 'short'})
});
};
2. Obtaining the current year’s index:
this.currentYearIndex = this.years.findIndex(year => year === (new Date()).getFullYear());
3. The InitViewSlices
method will create a simple array that will contain offset for each year (0, 6, 18, 30, 42, 54, 66). The offset basically tells us where to start slicing our global data model (monthsData
) and we know where to finish it already (it is always going to be == 24, which is the number of month delegates in our view):
initViewSlices() {
this.monthViewSlicesIndexes = [];
this.years.forEach((year,index) => {
if (index===0) { this.monthViewSlicesIndexes.push(0) } else
if (index===1) { this.monthViewSlicesIndexes.push(6) } else
this.monthViewSlicesIndexes.push(this.monthViewSlicesIndexes[index-1]+12);
})
};
4. Slicing data into the view and implementing increment/decrement per year:
sliceDataIntoView() {
this.globalIndexOffset = this.monthViewSlicesIndexes[this.currentYearIndex];
this.monthDataSlice = this.monthsData.slice(this.globalIndexOffset,this.globalIndexOffset+24);
};
incrementYear() {
if (this.currentYearIndex !== this.years.length-1) {
this.currentYearIndex++
this.sliceDataIntoView()
};
};
decrementYear() {
if (this.currentYearIndex !==0) {
this.currentYearIndex--;
this.sliceDataIntoView()
};
};
5. Added the missing notCurrentYear
class (.notCurrentYear { color: #c4cbd6;}
) and added all the changes to our template which is now final:
<div class="outerCard">
<div class="topPanel">
<button class="prevYearButton" (click)="decrementYear()">
<i class="arrow left"></i>
</button>
<span class="yearLabel">{{ years[currentYearIndex] }}</span>
<button class="nextYearButton" (click)="incrementYear()">
<i class="arrow right"></i>
</button>
</div>
<div class="contentPanel">
<div (click)="onClick(i)" class="monthItem" *ngFor="let month of monthDataSlice; let i = index" [ngClass]="{ isEdge: rangeIndexes[0]===globalIndexOffset+i || rangeIndexes[1]===globalIndexOffset+i, notCurrentYear: currentYearIndex===0? i > 11:(i < 6 || i > 17)}">
<div class="monthItemHighlight" [ngClass]="{ inRange: month.isInRange, isLowerEdge: month.isLowerEdge, isUpperEdge: month.isUpperEdge }">
{{ month.monthName }}
</div>
</div>
</div>
</div>
The last step is actually refactoring everything (just a bit) to support the logic of sliced views. Specifically, we needed changes with the onClick
method, which now looks like this:
onClick(indexClicked) {
if (this.rangeIndexes[0] === null) {
this.rangeIndexes[0] = this.globalIndexOffset+indexClicked;
} else
if (this.rangeIndexes[1] === null) {
this.rangeIndexes[1] = this.globalIndexOffset+indexClicked;
this.rangeIndexes.sort((a,b) => a-b);
this.monthsData.forEach((month, index) => {
if ((this.rangeIndexes[0] <= index) && (index <= this.rangeIndexes[1])) {
month.isInRange = true;
};
if (this.rangeIndexes[0] === index) {
month.isLowerEdge = true;
};
if (this.rangeIndexes[1] === index) {
month.isUpperEdge = true;
};
})
let fromMonthYear = this.monthsData[this.rangeIndexes[0]];
let toMonthYear = this.monthsData[this.rangeIndexes[1]];
this.emitData(`Range is: ${fromMonthYear.monthName} ${fromMonthYear.monthYear} to ${toMonthYear.monthName} ${toMonthYear.monthYear}`)
} else {
this.initRangeIndexes();
this.initMonthsData();
this.onClick(indexClicked);
this.sliceDataIntoView();
};
};
As seen above, now we are supporting a global index offset and we reset the view before each new range.
For convenience, I added a simple event emitter as well…
Thakn you for reading !
#Angular #Angular8 #JavaScript #Front End Development #Web Development
1650785100
Angular Material is ground running with significant, modern UI components that work across the web, mobile, and desktop.
Angular Material components will help us construct attractive UI and UX, consistent and functional web pages, and web applications while keeping to modern web design principles like browser portability and compatibility, device independence, and graceful degradation.
Angular Datepicker is a built-in material component that allows us to enter the date through text input or by choosing the date from a calendar. Angular Material Datepicker allows users to enter the date through text input or by choosing the date from the calendar. The Material Datepicker comprises several components and directives that work together.
It is made up of various angular components and directives that work together. First, we need to install Angular. We are using Angular CLI to install the Angular.
Type the following command.
npm install -g @angular/cli
Now, create the Angular project using the following command.
ng new datepicker
Go into the project and install the hammerjs using the following command.
npm install --save hammerjs
Hammer.js is the optional dependency and helps with touch support for a few components.
Now, install Angular Material and Angular Animations using the following command.
npm install --save @angular/material @angular/animations @angular/cdk
Now, include hammerjs inside the angular.json file. You can find this file at the root of the project.
Angular Material comes with some pre-built themes. These themes have set off the colors and basic styling.
The main available themes are indigo-pink, deeppurple-amber, purple-green, and pink-bluegrey.
To import the theme, you can add the following code to your global styles.css file. The file is inside the src folder.
@import '~@angular/material/prebuilt-themes/indigo-pink.css';
You can also access the Material Design icons and use named icons with a <mat-icon> component.
If we want to import them to your project, we can add this to the head section of your project’s root index.html file.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Datepicker</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
</head>
<body>
<app-root></app-root>
</body>
</html>
Inside the src,>> app folder, create one file called material.module.ts and add the following code.
// material.module.ts
import { NgModule } from '@angular/core';
import { MatDatepickerModule } from '@angular/material';
@NgModule({
imports: [
MatDatepickerModule
],
exports: [
MatDatepickerModule
]
})
export class MaterialModule {}
We have imported MatDatepickerModule, MatNativeDateModule, and other components that we need in our Angular Datepicker Example App.
We can add additional components in the future if we need to.
This file is written on its own because it is easy to include all the Material components in this file, and then this file will be imported inside the app.module.ts.
// material.module.ts
import { NgModule } from '@angular/core';
import { MatDatepickerModule,
MatNativeDateModule,
MatFormFieldModule,
MatInputModule } from '@angular/material';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
@NgModule({
imports: [
MatDatepickerModule,
MatFormFieldModule,
MatNativeDateModule,
MatInputModule,
BrowserAnimationsModule
],
exports: [
MatDatepickerModule,
MatFormFieldModule,
MatNativeDateModule,
MatInputModule,
BrowserAnimationsModule
],
providers: [ MatDatepickerModule ],
})
export class MaterialModule {}
Import MaterialModule inside the app.module.ts file.
// app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { MaterialModule } from './material.module';
import { AppComponent } from './app.component';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
MaterialModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Also, finally, write the Datepicker HTML code inside the app.component.html file.
<!-- app.component.html -->
<mat-form-field>
<input matInput [matDatepicker]="picker" placeholder="Choose a date">
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
</mat-form-field>
Save the file, go to a terminal or cmd, and start Angular Development Server.
ng serve --open
Go to the browser, and see something like the below image.
A datepicker comprises text input and a calendar popup, connected via the matDatePicker property on the text input.
<input [matDatepicker]="myDatepicker">
<mat-datepicker #myDatepicker></mat-datepicker>
There is an optional datepicker toggle button available. The toggle button can be added to the example above:
<input [matDatepicker]="myDatepicker">
<mat-datepicker-toggle [for]="myDatepicker"></mat-datepicker-toggle>
<mat-datepicker #myDatepicker></mat-datepicker>
It works the same with an input that is part of a <mat-form-field> and a toggle button can easily be used as a prefix or suffix on the material input:
<mat-form-field>
<input matInput [matDatepicker]="myDatepicker">
<mat-datepicker-toggle matSuffix [for]="myDatepicker"></mat-datepicker-toggle>
<mat-datepicker #myDatepicker></mat-datepicker>
</mat-form-field>
The startView property of <mat-datepicker> could be used to set the look that will show up when the calendar first opens. It can be configured to month, year, or multi-year; by default, it will begin to month view.
A month, year, or range of years that a calendar opens to is determined by first checking if any date is currently selected, and if so, it will open to a month or year containing that date. Otherwise, it will open in a month or year, providing today’s date.
This behavior can be easily overridden using the startAt property of <mat-datepicker>. In this case, a calendar will open to the month or year containing the startAt date.
<mat-form-field>
<input matInput [matDatepicker]="picker" placeholder="Choose a date">
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker startView="year" [startAt]="startDate"></mat-datepicker>
</mat-form-field>
You can find the code on Github.
Three properties add the date validation to the datepicker input.
The first two are the min and max properties.
Also, to enforce validation on input, these properties will disable all the dates on the calendar popup before or after the respective values and prevent the user from advancing the calendar past the month or year (depending on current view) containing the min or max date.
See the following HTML markup.
<mat-form-field class="example-full-width">
<input matInput [min]="minDate" [max]="maxDate" [matDatepicker]="picker" placeholder="Choose a date">
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
</mat-form-field>
Also, see the typescript file related to the above markup.
import {Component} from '@angular/core';
/** @title Datepicker with min & max validation */
@Component({
selector: 'datepicker-min-max-example',
templateUrl: 'datepicker-min-max-example.html',
styleUrls: ['datepicker-min-max-example.css'],
})
export class DatepickerMinMaxExample {
minDate = new Date(2000, 0, 1);
maxDate = new Date(2020, 0, 1);
}
The second way to add the date validation is by using the matDatepickerFilter property of the datepicker input.
This property accepts a function of <D> => boolean (where <D> is the date type used by the datepicker, see Choosing a date implementation).
A true result indicates that the date is valid, and a false result suggests that it is not.
Again this will also disable the dates on a calendar that are invalid.
However, a critical difference between using matDatepickerFilter vs. using min or max is that filtering out all dates before or after a certain point will not prevent a user from advancing a calendar past that point.
See the following code example. See first the HTML markup.
<mat-form-field class="example-full-width">
<input matInput [matDatepickerFilter]="myFilter" [matDatepicker]="picker" placeholder="Choose a date">
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
</mat-form-field>
Now, see the Typescript file related to the above markup.
import {Component} from '@angular/core';
/** @title Datepicker with filter validation */
@Component({
selector: 'datepicker-filter-example',
templateUrl: 'datepicker-filter-example.html',
styleUrls: ['datepicker-filter-example.css'],
})
export class DatepickerFilterExample {
myFilter = (d: Date): boolean => {
const day = d.getDay();
// Prevent Saturday and Sunday from being selected.
return day !== 0 && day !== 6;
}
}
In this example, the user can go back past 2005, but all of the dates before then will be unselectable. They will not be able to go further back in the calendar than 2000.
If they manually type in a date before the min, after the max, or filtered out, the input will have validation errors.
Each validation property has a different error that can be checked:
The input’s native (input) and (change) events will only trigger user interaction with the input element; they will not fire when the user selects the date from the calendar popup.
Therefore, a datepicker input also has support for (dateInput) and (dateChange) events — these triggers when a user interacts with either an input or the popup.
The (dateInput) event will fire whenever the value changes due to the user typing or selecting a date from the calendar. Likewise, the (dateChange) event will fire whenever the user finishes typing input (on <input> blur) or when a user chooses the date from a calendar.
See the following HTML Markup.
<mat-form-field>
<input matInput [matDatepicker]="picker" placeholder="Input & change events"
(dateInput)="addEvent('input', $event)" (dateChange)="addEvent('change', $event)">
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
</mat-form-field>
<div class="example-events">
<div *ngFor="let e of events">{{e}}</div>
</div>
Now, see the typescript file related to that markup.
import {Component} from '@angular/core';
import {MatDatepickerInputEvent} from '@angular/material/datepicker';
/** @title Datepicker input and change events */
@Component({
selector: 'datepicker-events-example',
templateUrl: 'datepicker-events-example.html',
styleUrls: ['datepicker-events-example.css'],
})
export class DatepickerEventsExample {
events: string[] = [];
addEvent(type: string, event: MatDatepickerInputEvent) {
this.events.push(`${type}: ${event.value}`);
}
}
As with any standard <input>, it is possible to disable the datepicker input by adding the disabled property.
By default, the <mat-datepicker> and <mat-datepicker-toggle> will inherit their disabled state from the <input>, but this can be overridden by setting a disabled property on the datepicker or toggle elements.
This is very useful if you want to disable the text input but allow selection via the calendar or vice-versa.
See the following HTML Markup.
<p>
<mat-form-field>
<input matInput [matDatepicker]="dp1" placeholder="Completely disabled" disabled>
<mat-datepicker-toggle matSuffix [for]="dp1"></mat-datepicker-toggle>
<mat-datepicker #dp1></mat-datepicker>
</mat-form-field>
</p>
<p>
<mat-form-field>
<input matInput [matDatepicker]="dp2" placeholder="Popup disabled">
<mat-datepicker-toggle matSuffix [for]="dp2" disabled></mat-datepicker-toggle>
<mat-datepicker #dp2></mat-datepicker>
</mat-form-field>
</p>
<p>
<mat-form-field>
<input matInput [matDatepicker]="dp3" placeholder="Input disabled" disabled>
<mat-datepicker-toggle matSuffix [for]="dp3"></mat-datepicker-toggle>
<mat-datepicker #dp3 disabled="false"></mat-datepicker>
</mat-form-field>
</p>
Now, see the typescript file.
import {Component} from '@angular/core';
/** @title Disabled datepicker */
@Component({
selector: 'datepicker-disabled-example',
templateUrl: 'datepicker-disabled-example.html',
styleUrls: ['datepicker-disabled-example.css'],
})
export class DatepickerDisabledExample {}
That’s it for this tutorial.
Source: https://appdividend.com/2022/02/16/angular-datepicker/
1650810840
Angular Material está funcionando desde cero con componentes de interfaz de usuario significativos y modernos que funcionan en la web , dispositivos móviles y computadoras de escritorio .
Los componentes de Angular Material nos ayudarán a construir una interfaz de usuario y una experiencia de usuario atractivas , páginas web y aplicaciones web consistentes y funcionales, manteniendo los principios de diseño web modernos, como la portabilidad y compatibilidad del navegador, la independencia del dispositivo y la degradación elegante.
Angular Datepicker es un componente de material incorporado que nos permite ingresar la fecha a través de la entrada de texto o eligiendo la fecha de un calendario. Angular Material Datepicker permite a los usuarios ingresar la fecha a través de la entrada de texto o eligiendo la fecha del calendario. Material Datepicker consta de varios componentes y directivas que funcionan juntos.
Se compone de varios componentes angulares y directivas que funcionan en conjunto. Primero, necesitamos instalar Angular. Estamos usando Angular CLI para instalar Angular.
Escriba el siguiente comando.
npm install -g @angular/cli
Ahora, crea el proyecto Angular usando el siguiente comando.
ng new datepicker
Ingrese al proyecto e instale hammerjs usando el siguiente comando.
npm install --save hammerjs
Hammer.js es la dependencia opcional y ayuda con la compatibilidad táctil para algunos componentes.
Ahora, instale Angular Material y Angular Animations usando el siguiente comando.
npm install --save @angular/material @angular/animations @angular/cdk
Ahora, incluya hammerjs dentro del archivo angular.json . Puede encontrar este archivo en la raíz del proyecto.
Angular Material viene con algunos temas prediseñados. Estos temas han resaltado los colores y el estilo básico.
Los principales temas disponibles son rosa índigo , ámbar morado oscuro , verde púrpura y gris azulado rosa .
Para importar el tema, puede agregar el siguiente código a su archivo global styles.css . El archivo está dentro de la carpeta src .
@import '~@angular/material/prebuilt-themes/indigo-pink.css';
También puede acceder a los íconos de Material Design y usar íconos con nombre con un componente <mat-icon> .
Si queremos importarlos a su proyecto, podemos agregar esto a la sección principal del archivo raíz index.html de su proyecto.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Datepicker</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
</head>
<body>
<app-root></app-root>
</body>
</html>
Dentro de la carpeta src,>> app , cree un archivo llamado material.module.ts y agregue el siguiente código.
// material.module.ts
import { NgModule } from '@angular/core';
import { MatDatepickerModule } from '@angular/material';
@NgModule({
imports: [
MatDatepickerModule
],
exports: [
MatDatepickerModule
]
})
export class MaterialModule {}
Hemos importado MatDatepickerModule, MatNativeDateModule y otros componentes que necesitamos en nuestra aplicación de ejemplo Angular Datepicker .
Podemos agregar componentes adicionales en el futuro si es necesario.
Este archivo se escribe solo porque es fácil incluir todos los componentes de Material en este archivo, y luego este archivo se importará dentro de app.module.ts.
// material.module.ts
import { NgModule } from '@angular/core';
import { MatDatepickerModule,
MatNativeDateModule,
MatFormFieldModule,
MatInputModule } from '@angular/material';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
@NgModule({
imports: [
MatDatepickerModule,
MatFormFieldModule,
MatNativeDateModule,
MatInputModule,
BrowserAnimationsModule
],
exports: [
MatDatepickerModule,
MatFormFieldModule,
MatNativeDateModule,
MatInputModule,
BrowserAnimationsModule
],
providers: [ MatDatepickerModule ],
})
export class MaterialModule {}
Importe MaterialModule dentro del archivo app.module.ts .
// app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { MaterialModule } from './material.module';
import { AppComponent } from './app.component';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
MaterialModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Además, finalmente, escriba el código HTML de Datepicker dentro del archivo app.component.html .
<!-- app.component.html -->
<mat-form-field>
<input matInput [matDatepicker]="picker" placeholder="Choose a date">
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
</mat-form-field>
Guarde el archivo, vaya a una terminal o cmd e inicie Angular Development Server.
ng serve --open
Vaya al navegador y vea algo como la imagen de abajo.
Un selector de fecha consta de entrada de texto y una ventana emergente de calendario, conectados a través de la propiedad matDatePicker en la entrada de texto.
<input [matDatepicker]="myDatepicker">
<mat-datepicker #myDatepicker></mat-datepicker>
Hay un botón de alternar selector de fecha opcional disponible. El botón de alternar se puede agregar al ejemplo anterior:
<input [matDatepicker]="myDatepicker">
<mat-datepicker-toggle [for]="myDatepicker"></mat-datepicker-toggle>
<mat-datepicker #myDatepicker></mat-datepicker>
Funciona de la misma manera con una entrada que es parte de un <mat-form-field> y un botón de alternar se puede usar fácilmente como prefijo o sufijo en la entrada de material:
<mat-form-field>
<input matInput [matDatepicker]="myDatepicker">
<mat-datepicker-toggle matSuffix [for]="myDatepicker"></mat-datepicker-toggle>
<mat-datepicker #myDatepicker></mat-datepicker>
</mat-form-field>
La propiedad startView de <mat-datepicker> podría usarse para establecer el aspecto que se mostrará cuando se abra el calendario por primera vez. Puede configurarse para mes , año o varios años ; de forma predeterminada, comenzará a ver el mes.
Un mes, año o rango de años en los que se abre un calendario se determina comprobando primero si alguna fecha está actualmente seleccionada y, de ser así, se abrirá en un mes o año que contenga esa fecha. De lo contrario, se abrirá en un mes o año, proporcionando la fecha de hoy.
Este comportamiento se puede anular fácilmente usando la propiedad startAt de <mat-datepicker> . En este caso, se abrirá un calendario en el mes o año que contiene la fecha startAt .
<mat-form-field>
<input matInput [matDatepicker]="picker" placeholder="Choose a date">
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker startView="year" [startAt]="startDate"></mat-datepicker>
</mat-form-field>
Puedes encontrar el código en Github.
Tres propiedades agregan la validación de fecha a la entrada del selector de fecha.
Los dos primeros son las propiedades min y max .
Además, para hacer cumplir la validación en la entrada, estas propiedades deshabilitarán todas las fechas en la ventana emergente del calendario antes o después de los valores respectivos y evitarán que el usuario avance el calendario más allá del mes o año (según la vista actual) que contiene la fecha mínima o máxima. .
Consulte el siguiente marcado HTML.
<mat-form-field class="example-full-width">
<input matInput [min]="minDate" [max]="maxDate" [matDatepicker]="picker" placeholder="Choose a date">
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
</mat-form-field>
Además, consulte el archivo mecanografiado relacionado con el marcado anterior.
import {Component} from '@angular/core';
/** @title Datepicker with min & max validation */
@Component({
selector: 'datepicker-min-max-example',
templateUrl: 'datepicker-min-max-example.html',
styleUrls: ['datepicker-min-max-example.css'],
})
export class DatepickerMinMaxExample {
minDate = new Date(2000, 0, 1);
maxDate = new Date(2020, 0, 1);
}
La segunda forma de agregar la validación de fecha es usando la propiedad matDatepickerFilter de la entrada del selector de fecha.
Esta propiedad acepta una función de <D> => booleano (donde <D> es el tipo de fecha utilizado por el selector de fecha, consulte Elección de una implementación de fecha).
Un resultado verdadero indica que la fecha es válida y un resultado falso sugiere que no lo es.
Nuevamente, esto también deshabilitará las fechas en un calendario que no son válidas.
Sin embargo, una diferencia crítica entre usar matDatepickerFilter y usar min o max es que filtrar todas las fechas antes o después de cierto punto no evitará que un usuario avance un calendario más allá de ese punto.
Consulte el siguiente ejemplo de código. Vea primero el marcado HTML.
<mat-form-field class="example-full-width">
<input matInput [matDatepickerFilter]="myFilter" [matDatepicker]="picker" placeholder="Choose a date">
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
</mat-form-field>
Ahora, vea el archivo TypeScript relacionado con el marcado anterior.
import {Component} from '@angular/core';
/** @title Datepicker with filter validation */
@Component({
selector: 'datepicker-filter-example',
templateUrl: 'datepicker-filter-example.html',
styleUrls: ['datepicker-filter-example.css'],
})
export class DatepickerFilterExample {
myFilter = (d: Date): boolean => {
const day = d.getDay();
// Prevent Saturday and Sunday from being selected.
return day !== 0 && day !== 6;
}
}
En este ejemplo, el usuario puede retroceder hasta 2005, pero todas las fechas anteriores no podrán seleccionarse. No podrán retroceder más en el calendario que 2000.
Si escriben manualmente una fecha antes del mínimo, después del máximo o filtrada, la entrada tendrá errores de validación.
Cada propiedad de validación tiene un error diferente que se puede verificar:
Los eventos nativos (entrada) y (cambio) de la entrada solo activarán la interacción del usuario con el elemento de entrada; no se activarán cuando el usuario seleccione la fecha de la ventana emergente del calendario.
Por lo tanto, una entrada de selector de fecha también admite eventos (dateInput) y (dateChange), que se activan cuando un usuario interactúa con una entrada o la ventana emergente.
El evento (dateInput) se activará siempre que el valor cambie debido a que el usuario escribe o selecciona una fecha del calendario. Del mismo modo, el evento (dateChange) se activará cada vez que el usuario termine de escribir la entrada (en <input> blur) o cuando un usuario elija la fecha de un calendario.
Consulte el siguiente marcado HTML.
<mat-form-field>
<input matInput [matDatepicker]="picker" placeholder="Input & change events"
(dateInput)="addEvent('input', $event)" (dateChange)="addEvent('change', $event)">
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
</mat-form-field>
<div class="example-events">
<div *ngFor="let e of events">{{e}}</div>
</div>
Ahora, vea el archivo mecanografiado relacionado con ese marcado.
import {Component} from '@angular/core';
import {MatDatepickerInputEvent} from '@angular/material/datepicker';
/** @title Datepicker input and change events */
@Component({
selector: 'datepicker-events-example',
templateUrl: 'datepicker-events-example.html',
styleUrls: ['datepicker-events-example.css'],
})
export class DatepickerEventsExample {
events: string[] = [];
addEvent(type: string, event: MatDatepickerInputEvent) {
this.events.push(`${type}: ${event.value}`);
}
}
Al igual que con cualquier <entrada> estándar, es posible deshabilitar la entrada del selector de fecha agregando la propiedad deshabilitada.
De forma predeterminada, <mat-datepicker> y <mat-datepicker-toggle> heredarán su estado deshabilitado de <input>, pero esto se puede anular configurando una propiedad deshabilitada en el selector de fecha o los elementos de alternancia.
Esto es muy útil si desea deshabilitar la entrada de texto pero permitir la selección a través del calendario o viceversa.
Consulte el siguiente marcado HTML.
<p>
<mat-form-field>
<input matInput [matDatepicker]="dp1" placeholder="Completely disabled" disabled>
<mat-datepicker-toggle matSuffix [for]="dp1"></mat-datepicker-toggle>
<mat-datepicker #dp1></mat-datepicker>
</mat-form-field>
</p>
<p>
<mat-form-field>
<input matInput [matDatepicker]="dp2" placeholder="Popup disabled">
<mat-datepicker-toggle matSuffix [for]="dp2" disabled></mat-datepicker-toggle>
<mat-datepicker #dp2></mat-datepicker>
</mat-form-field>
</p>
<p>
<mat-form-field>
<input matInput [matDatepicker]="dp3" placeholder="Input disabled" disabled>
<mat-datepicker-toggle matSuffix [for]="dp3"></mat-datepicker-toggle>
<mat-datepicker #dp3 disabled="false"></mat-datepicker>
</mat-form-field>
</p>
Ahora, vea el archivo mecanografiado.
import {Component} from '@angular/core';
/** @title Disabled datepicker */
@Component({
selector: 'datepicker-disabled-example',
templateUrl: 'datepicker-disabled-example.html',
styleUrls: ['datepicker-disabled-example.css'],
})
export class DatepickerDisabledExample {}
Eso es todo por este tutorial.
Fuente: https://appdividend.com/2022/02/16/angular-datepicker/
1650810960
Angular Materialは、 Web、モバイル、デスクトップで機能 する重要で最新のUIコンポーネントを備えた地上運用です。
Angular Materialコンポーネントは、ブラウザーの移植性と互換性、デバイスの独立性、適切な機能低下などの最新のWebデザイン原則を維持しながら、魅力的なUIとUX、一貫性のある機能的なWebページ、およびWebアプリケーションを構築するのに役立ちます。
Angular Datepickerは、テキスト入力またはカレンダーから日付を選択して日付を入力できる組み込みのマテリアルコンポーネントです。Angular Material Datepickerを使用すると、ユーザーはテキスト入力またはカレンダーから日付を選択して日付を入力できます。Material Datepickerは、連携して機能するいくつかのコンポーネントとディレクティブで構成されています。
これは、連携して機能するさまざまな角度コンポーネントとディレクティブで構成されています。まず、Angularをインストールする必要があります。 AngularCLIを使用して Angularをインストールしてい ます。
次のコマンドを入力します。
npm install -g @angular/cli
次に、次のコマンドを使用してAngularプロジェクトを作成します。
ng new datepicker
プロジェクトに移動し、次のコマンドを使用してhammerjs をインストールし ます。
npm install --save hammerjs
Hammer.jsはオプションの依存関係であり、いくつかのコンポーネントのタッチサポートに役立ちます。
次に、次のコマンドを使用してAngularMaterial と AngularAnimations をインストール します。
npm install --save @angular/material @angular/animations @angular/cdk
ここで、 angular.json ファイル内に hammerjs を含めます。このファイルはプロジェクトのルートにあります。
Angular Materialには、いくつかの事前に作成されたテーマが付属しています。これらのテーマは、色と基本的なスタイリングを際立たせています。
利用可能な主なテーマは、 インディゴピンク、 ディープパープルアンバー、 パープルグリーン、 ピンク ブルーグレーです。
テーマをインポートするには、次のコードをグローバル styles.css ファイルに追加します。ファイルはsrc フォルダー内にあります。
@import '~@angular/material/prebuilt-themes/indigo-pink.css';
マテリアルデザインアイコンにアクセスして、 <mat-icon> コンポーネント で名前付きアイコンを使用 することもできます。
それらをプロジェクトにインポートする場合は、これをプロジェクトのルート index.html ファイルのheadセクションに追加できます。
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Datepicker</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
</head>
<body>
<app-root></app-root>
</body>
</html>
src、>> app フォルダー内に、 material.module.ts というファイルを1つ作成 し、次のコードを追加します。
// material.module.ts
import { NgModule } from '@angular/core';
import { MatDatepickerModule } from '@angular/material';
@NgModule({
imports: [
MatDatepickerModule
],
exports: [
MatDatepickerModule
]
})
export class MaterialModule {}
MatDatepickerModule、MatNativeDateModule、 およびAngularDatepickerサンプル アプリに必要なその他のコンポーネントを インポートしました。
必要に応じて、将来的にコンポーネントを追加できます。
このファイルにはすべてのマテリアルコンポーネントを 簡単に含めることができるため、このファイルは独自に作成され、このファイルはapp.module.ts内にインポートされます。
// material.module.ts
import { NgModule } from '@angular/core';
import { MatDatepickerModule,
MatNativeDateModule,
MatFormFieldModule,
MatInputModule } from '@angular/material';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
@NgModule({
imports: [
MatDatepickerModule,
MatFormFieldModule,
MatNativeDateModule,
MatInputModule,
BrowserAnimationsModule
],
exports: [
MatDatepickerModule,
MatFormFieldModule,
MatNativeDateModule,
MatInputModule,
BrowserAnimationsModule
],
providers: [ MatDatepickerModule ],
})
export class MaterialModule {}
app.module.ts ファイル内にMaterialModuleをインポートします。
// app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { MaterialModule } from './material.module';
import { AppComponent } from './app.component';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
MaterialModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
また、最後に、app.component.html ファイル内にDatepickerHTMLコードを記述します。
<!-- app.component.html -->
<mat-form-field>
<input matInput [matDatepicker]="picker" placeholder="Choose a date">
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
</mat-form-field>
ファイルを保存し、ターミナルまたはcmdに移動して、AngularDevelopmentServerを起動します。
ng serve --open
ブラウザに移動すると、次の画像のようなものが表示されます。
日付ピッカーは、テキスト入力とカレンダーポップアップで構成され、テキスト入力のmatDatePicker プロパティを介して接続されます。
<input [matDatepicker]="myDatepicker">
<mat-datepicker #myDatepicker></mat-datepicker>
オプションの日付ピッカートグルボタンが利用可能です。上記の例にトグルボタンを追加できます。
<input [matDatepicker]="myDatepicker">
<mat-datepicker-toggle [for]="myDatepicker"></mat-datepicker-toggle>
<mat-datepicker #myDatepicker></mat-datepicker>
<mat-form-field>の一部である入力でも同じように機能し、トグルボタンをマテリアル入力のプレフィックスまたはサフィックスとして簡単に使用できます。
<mat-form-field>
<input matInput [matDatepicker]="myDatepicker">
<mat-datepicker-toggle matSuffix [for]="myDatepicker"></mat-datepicker-toggle>
<mat-datepicker #myDatepicker></mat-datepicker>
</mat-form-field>
<mat-datepicker>の startViewプロパティを使用して、カレンダーを最初に開いたときに表示される外観を設定できます。月、 年、または 複数年に構成できます 。デフォルトでは、月表示を開始します。
カレンダーが開く月、年、または年の範囲は、最初に日付が現在選択されているかどうかを確認することによって決定され、選択されている場合は、その日付を含む月または年が開きます。それ以外の場合は、1か月または1年で開き、今日の日付を提供します。
この動作は、 <mat-datepicker>のstartAt プロパティを使用して簡単にオーバーライドできます。この場合、カレンダーは startAt 日付を含む月または年に開きます。
<mat-form-field>
<input matInput [matDatepicker]="picker" placeholder="Choose a date">
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker startView="year" [startAt]="startDate"></mat-datepicker>
</mat-form-field>
コードはGithubにあります。
3つのプロパティにより、日付検証がdatepicker入力に追加されます。
最初の2つは、最小プロパティと最大プロパティです。
また、入力の検証を強制するために、これらのプロパティは、それぞれの値の前後のカレンダーポップアップのすべての日付を無効にし、ユーザーが最小または最大の日付を含む月または年(現在のビューに応じて)を超えてカレンダーを進めるのを防ぎます。
次のHTMLマークアップを参照してください。
<mat-form-field class="example-full-width">
<input matInput [min]="minDate" [max]="maxDate" [matDatepicker]="picker" placeholder="Choose a date">
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
</mat-form-field>
また、上記のマークアップに関連するtypescriptファイルも参照してください。
import {Component} from '@angular/core';
/** @title Datepicker with min & max validation */
@Component({
selector: 'datepicker-min-max-example',
templateUrl: 'datepicker-min-max-example.html',
styleUrls: ['datepicker-min-max-example.css'],
})
export class DatepickerMinMaxExample {
minDate = new Date(2000, 0, 1);
maxDate = new Date(2020, 0, 1);
}
日付検証を追加する2番目の方法は、datepicker入力のmatDatepickerFilterプロパティを使用することです。
このプロパティは、<D> =>ブール値の関数を受け入れます(<D>は、datepickerで使用される日付型です。日付の実装の選択を参照してください)。
真の結果は日付が有効であることを示し、偽の結果は日付が有効でないことを示します。
繰り返しますが、これにより、無効なカレンダーの日付も無効になります。
ただし、matDatepickerFilterを使用する場合とminまたはmaxを使用する場合の重要な違いは、特定のポイントの前後のすべての日付を除外しても、ユーザーがそのポイントを超えてカレンダーを進めることを妨げないことです。
次のコード例を参照してください。最初にHTMLマークアップを参照してください。
<mat-form-field class="example-full-width">
<input matInput [matDatepickerFilter]="myFilter" [matDatepicker]="picker" placeholder="Choose a date">
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
</mat-form-field>
ここで、上記のマークアップに関連するTypescriptファイルを参照してください。
import {Component} from '@angular/core';
/** @title Datepicker with filter validation */
@Component({
selector: 'datepicker-filter-example',
templateUrl: 'datepicker-filter-example.html',
styleUrls: ['datepicker-filter-example.css'],
})
export class DatepickerFilterExample {
myFilter = (d: Date): boolean => {
const day = d.getDay();
// Prevent Saturday and Sunday from being selected.
return day !== 0 && day !== 6;
}
}
この例では、ユーザーは2005年を過ぎて戻ることができますが、それ以前のすべての日付は選択できなくなります。彼らは2000年よりもカレンダーに戻ることはできません。
最小値の前、最大値の後、またはフィルターで除外された日付を手動で入力すると、入力に検証エラーが発生します。
各検証プロパティには、チェックできる異なるエラーがあります。
入力のネイティブ(入力)および(変更)イベントは、入力要素とのユーザーインタラクションのみをトリガーします。ユーザーがカレンダーポップアップから日付を選択しても、これらは起動しません。
したがって、datepicker入力は、(dateInput)および(dateChange)イベントもサポートします。これらは、ユーザーが入力またはポップアップのいずれかを操作したときにトリガーされます。
(dateInput)イベントは、ユーザーがカレンダーから日付を入力または選択したために値が変更されるたびに発生します。同様に、(dateChange)イベントは、ユーザーが入力の入力を終了するたびに(<input>ブラーで)、またはユーザーがカレンダーから日付を選択したときに発生します。
次のHTMLマークアップを参照してください。
<mat-form-field>
<input matInput [matDatepicker]="picker" placeholder="Input & change events"
(dateInput)="addEvent('input', $event)" (dateChange)="addEvent('change', $event)">
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
</mat-form-field>
<div class="example-events">
<div *ngFor="let e of events">{{e}}</div>
</div>
次に、そのマークアップに関連するtypescriptファイルを参照してください。
import {Component} from '@angular/core';
import {MatDatepickerInputEvent} from '@angular/material/datepicker';
/** @title Datepicker input and change events */
@Component({
selector: 'datepicker-events-example',
templateUrl: 'datepicker-events-example.html',
styleUrls: ['datepicker-events-example.css'],
})
export class DatepickerEventsExample {
events: string[] = [];
addEvent(type: string, event: MatDatepickerInputEvent) {
this.events.push(`${type}: ${event.value}`);
}
}
他の標準の<input>と同様に、disabledプロパティを追加することで、datepicker入力を無効にすることができます。
デフォルトでは、<mat-datepicker>と<mat-datepicker-toggle>は<input>から無効な状態を継承しますが、これは、datepickerまたはtoggle要素にdisabledプロパティを設定することでオーバーライドできます。
これは、テキスト入力を無効にしたいが、カレンダーを介した選択を許可したい場合、またはその逆の場合に非常に便利です。
次のHTMLマークアップを参照してください。
<p>
<mat-form-field>
<input matInput [matDatepicker]="dp1" placeholder="Completely disabled" disabled>
<mat-datepicker-toggle matSuffix [for]="dp1"></mat-datepicker-toggle>
<mat-datepicker #dp1></mat-datepicker>
</mat-form-field>
</p>
<p>
<mat-form-field>
<input matInput [matDatepicker]="dp2" placeholder="Popup disabled">
<mat-datepicker-toggle matSuffix [for]="dp2" disabled></mat-datepicker-toggle>
<mat-datepicker #dp2></mat-datepicker>
</mat-form-field>
</p>
<p>
<mat-form-field>
<input matInput [matDatepicker]="dp3" placeholder="Input disabled" disabled>
<mat-datepicker-toggle matSuffix [for]="dp3"></mat-datepicker-toggle>
<mat-datepicker #dp3 disabled="false"></mat-datepicker>
</mat-form-field>
</p>
ここで、typescriptファイルを参照してください。
import {Component} from '@angular/core';
/** @title Disabled datepicker */
@Component({
selector: 'datepicker-disabled-example',
templateUrl: 'datepicker-disabled-example.html',
styleUrls: ['datepicker-disabled-example.css'],
})
export class DatepickerDisabledExample {}
このチュートリアルは以上です。
1648564858
Angular Datepicker is a built-in material component that allows us to enter the date through text input or by choosing the date from a calendar. Angular Material Datepicker allows users to enter the date through text input or by choosing the date from the calendar. The Material Datepicker comprises several components and directives that work together.
It is made up of various angular components and directives that work together. First, we need to install Angular. We are using Angular CLI to install the Angular.
Type the following command.
npm install -g @angular/cli
Now, create the Angular project using the following command.
ng new datepicker
Go into the project and install the hammerjs using the following command.
npm install --save hammerjs
Hammer.js is the optional dependency and helps with touch support for a few components.
Now, install Angular Material and Angular Animations using the following command.
npm install --save @angular/material @angular/animations @angular/cdk
Now, include hammerjs inside the angular.json file. You can find this file at the root of the project.
Angular Material comes with some pre-built themes. These themes have set off the colors and basic styling.
The main available themes are indigo-pink, deeppurple-amber, purple-green, and pink-bluegrey.
To import the theme, you can add the following code to your global styles.css file. The file is inside the src folder.
@import '~@angular/material/prebuilt-themes/indigo-pink.css';
You can also access the Material Design icons and use named icons with a <mat-icon> component.
If we want to import them to your project, we can add this to the head section of your project’s root index.html file.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Datepicker</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
</head>
<body>
<app-root></app-root>
</body>
</html>
Inside the src,>> app folder, create one file called material.module.ts and add the following code.
// material.module.ts
import { NgModule } from '@angular/core';
import { MatDatepickerModule } from '@angular/material';
@NgModule({
imports: [
MatDatepickerModule
],
exports: [
MatDatepickerModule
]
})
export class MaterialModule {}
We have imported MatDatepickerModule, MatNativeDateModule, and other components that we need in our Angular Datepicker Example App.
We can add additional components in the future if we need to.
This file is written on its own because it is easy to include all the Material components in this file, and then this file will be imported inside the app.module.ts.
// material.module.ts
import { NgModule } from '@angular/core';
import { MatDatepickerModule,
MatNativeDateModule,
MatFormFieldModule,
MatInputModule } from '@angular/material';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
@NgModule({
imports: [
MatDatepickerModule,
MatFormFieldModule,
MatNativeDateModule,
MatInputModule,
BrowserAnimationsModule
],
exports: [
MatDatepickerModule,
MatFormFieldModule,
MatNativeDateModule,
MatInputModule,
BrowserAnimationsModule
],
providers: [ MatDatepickerModule ],
})
export class MaterialModule {}
Import MaterialModule inside the app.module.ts file.
// app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { MaterialModule } from './material.module';
import { AppComponent } from './app.component';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
MaterialModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Also, finally, write the Datepicker HTML code inside the app.component.html file.
<!-- app.component.html -->
<mat-form-field>
<input matInput [matDatepicker]="picker" placeholder="Choose a date">
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
</mat-form-field>
Save the file, go to a terminal or cmd, and start Angular Development Server.
ng serve --open
Go to the browser, and see something like the below image.
A datepicker comprises text input and a calendar popup, connected via the matDatePicker property on the text input.
<input [matDatepicker]="myDatepicker">
<mat-datepicker #myDatepicker></mat-datepicker>
There is an optional datepicker toggle button available. The toggle button can be added to the example above:
<input [matDatepicker]="myDatepicker">
<mat-datepicker-toggle [for]="myDatepicker"></mat-datepicker-toggle>
<mat-datepicker #myDatepicker></mat-datepicker>
It works the same with an input that is part of a <mat-form-field> and a toggle button can easily be used as a prefix or suffix on the material input:
<mat-form-field>
<input matInput [matDatepicker]="myDatepicker">
<mat-datepicker-toggle matSuffix [for]="myDatepicker"></mat-datepicker-toggle>
<mat-datepicker #myDatepicker></mat-datepicker>
</mat-form-field>
The startView property of <mat-datepicker> could be used to set the look that will show up when the calendar first opens. It can be configured to month, year, or multi-year; by default, it will begin to month view.
A month, year, or range of years that a calendar opens to is determined by first checking if any date is currently selected, and if so, it will open to a month or year containing that date. Otherwise, it will open in a month or year, providing today’s date.
This behavior can be easily overridden using the startAt property of <mat-datepicker>. In this case, a calendar will open to the month or year containing the startAt date.
<mat-form-field>
<input matInput [matDatepicker]="picker" placeholder="Choose a date">
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker startView="year" [startAt]="startDate"></mat-datepicker>
</mat-form-field>
You can find the code on Github.
Three properties add the date validation to the datepicker input.
The first two are the min and max properties.
Also, to enforce validation on input, these properties will disable all the dates on the calendar popup before or after the respective values and prevent the user from advancing the calendar past the month or year (depending on current view) containing the min or max date.
See the following HTML markup.
<mat-form-field class="example-full-width">
<input matInput [min]="minDate" [max]="maxDate" [matDatepicker]="picker" placeholder="Choose a date">
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
</mat-form-field>
Also, see the typescript file related to the above markup.
import {Component} from '@angular/core';
/** @title Datepicker with min & max validation */
@Component({
selector: 'datepicker-min-max-example',
templateUrl: 'datepicker-min-max-example.html',
styleUrls: ['datepicker-min-max-example.css'],
})
export class DatepickerMinMaxExample {
minDate = new Date(2000, 0, 1);
maxDate = new Date(2020, 0, 1);
}
The second way to add the date validation is by using the matDatepickerFilter property of the datepicker input.
This property accepts a function of <D> => boolean (where <D> is the date type used by the datepicker, see Choosing a date implementation).
A true result indicates that the date is valid, and a false result suggests that it is not.
Again this will also disable the dates on a calendar that are invalid.
However, a critical difference between using matDatepickerFilter vs. using min or max is that filtering out all dates before or after a certain point will not prevent a user from advancing a calendar past that point.
See the following code example. See first the HTML markup.
<mat-form-field class="example-full-width">
<input matInput [matDatepickerFilter]="myFilter" [matDatepicker]="picker" placeholder="Choose a date">
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
</mat-form-field>
Now, see the Typescript file related to the above markup.
import {Component} from '@angular/core';
/** @title Datepicker with filter validation */
@Component({
selector: 'datepicker-filter-example',
templateUrl: 'datepicker-filter-example.html',
styleUrls: ['datepicker-filter-example.css'],
})
export class DatepickerFilterExample {
myFilter = (d: Date): boolean => {
const day = d.getDay();
// Prevent Saturday and Sunday from being selected.
return day !== 0 && day !== 6;
}
}
In this example, the user can go back past 2005, but all of the dates before then will be unselectable. They will not be able to go further back in the calendar than 2000.
If they manually type in a date before the min, after the max, or filtered out, the input will have validation errors.
Each validation property has a different error that can be checked:
The input’s native (input) and (change) events will only trigger user interaction with the input element; they will not fire when the user selects the date from the calendar popup.
Therefore, a datepicker input also has support for (dateInput) and (dateChange) events — these triggers when a user interacts with either an input or the popup.
The (dateInput) event will fire whenever the value changes due to the user typing or selecting a date from the calendar. Likewise, the (dateChange) event will fire whenever the user finishes typing input (on <input> blur) or when a user chooses the date from a calendar.
See the following HTML Markup.
<mat-form-field>
<input matInput [matDatepicker]="picker" placeholder="Input & change events"
(dateInput)="addEvent('input', $event)" (dateChange)="addEvent('change', $event)">
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
</mat-form-field>
<div class="example-events">
<div *ngFor="let e of events">{{e}}</div>
</div>
Now, see the typescript file related to that markup.
import {Component} from '@angular/core';
import {MatDatepickerInputEvent} from '@angular/material/datepicker';
/** @title Datepicker input and change events */
@Component({
selector: 'datepicker-events-example',
templateUrl: 'datepicker-events-example.html',
styleUrls: ['datepicker-events-example.css'],
})
export class DatepickerEventsExample {
events: string[] = [];
addEvent(type: string, event: MatDatepickerInputEvent) {
this.events.push(`${type}: ${event.value}`);
}
}
As with any standard <input>, it is possible to disable the datepicker input by adding the disabled property.
By default, the <mat-datepicker> and <mat-datepicker-toggle> will inherit their disabled state from the <input>, but this can be overridden by setting a disabled property on the datepicker or toggle elements.
This is very useful if you want to disable the text input but allow selection via the calendar or vice-versa.
See the following HTML Markup.
<p>
<mat-form-field>
<input matInput [matDatepicker]="dp1" placeholder="Completely disabled" disabled>
<mat-datepicker-toggle matSuffix [for]="dp1"></mat-datepicker-toggle>
<mat-datepicker #dp1></mat-datepicker>
</mat-form-field>
</p>
<p>
<mat-form-field>
<input matInput [matDatepicker]="dp2" placeholder="Popup disabled">
<mat-datepicker-toggle matSuffix [for]="dp2" disabled></mat-datepicker-toggle>
<mat-datepicker #dp2></mat-datepicker>
</mat-form-field>
</p>
<p>
<mat-form-field>
<input matInput [matDatepicker]="dp3" placeholder="Input disabled" disabled>
<mat-datepicker-toggle matSuffix [for]="dp3"></mat-datepicker-toggle>
<mat-datepicker #dp3 disabled="false"></mat-datepicker>
</mat-form-field>
</p>
Now, see the typescript file.
import {Component} from '@angular/core';
/** @title Disabled datepicker */
@Component({
selector: 'datepicker-disabled-example',
templateUrl: 'datepicker-disabled-example.html',
styleUrls: ['datepicker-disabled-example.css'],
})
export class DatepickerDisabledExample {}
That’s it for this tutorial.
1598940617
Angular is a TypeScript based framework that works in synchronization with HTML, CSS, and JavaScript. To work with angular, domain knowledge of these 3 is required.
In this article, you will get to know about the Angular Environment setup process. After reading this article, you will be able to install, setup, create, and launch your own application in Angular. So let’s start!!!
For Installing Angular on your Machine, there are 2 prerequisites:
First you need to have Node.js installed as Angular require current, active LTS or maintenance LTS version of Node.js
Download and Install Node.js version suitable for your machine’s operating system.
Angular, Angular CLI and Angular applications are dependent on npm packages. By installing Node.js, you have automatically installed the npm Package manager which will be the base for installing angular in your system. To check the presence of npm client and Angular version check of npm client, run this command:
· After executing the command, Angular CLI will get installed within some time. You can check it using the following command
Now as your Angular CLI is installed, you need to create a workspace to work upon your application. Methods for it are:
To create a workspace:
#angular tutorials #angular cli install #angular environment setup #angular version check #download angular #install angular #install angular cli