07 October 2017

Submit Form và Validate Form trong Angular 2

login.html
Angular 2
<div id="header">
    <div id="clouds">
        <div class="cloud-1" data-speed="35000"></div>
        <div class="cloud-2" data-speed="45000" data-delay="15000"></div>
        <div class="cloud-3" data-speed="40000"></div>
        <div class="cloud-4" data-speed="38000" data-delay="20000"></div>
    </div>
</div>
<div id="content">
    <div class="container">
        <form id="login" [formGroup]="formGroup" (ngSubmit)="onSubmit()">
            <div id="login_header"><i class="icon-home"></i> Đăng nhập vào hệ thống</div>
            <div id="login_content">
                <span>
                    <input class="tip border" [ngClass]="{
                        'border-danger': (username.invalid && (username.touched || isSubmit) || false),
                        'border-success': (username.valid && (username.touched || isSubmit) || false)}"
                         [(ngModel)]="this.model.username" formControlName="username" type="text" maxlength="18">
                    <label for="username">Username</label>
                    <i class="icon-user"></i>
                    <div *ngIf="username.invalid && (username.touched || isSubmit) || false" class="text-danger" data-text="填写您的身份证号">Vui lòng nhập lại Username</div>
                </span>
                <span>
                    <input class="tip border" [ngClass]="{
                        'border-danger': (password.invalid && (password.touched || isSubmit) || false),
                        'border-success': (password.valid && (password.touched || isSubmit) || false)}"
                        [(ngModel)]="this.model.password" formControlName="password" type="password" maxlength="16">
                    <label for="password">Password</label>
                    <i class="icon-lock"></i>
                    <div *ngIf="password.invalid && (password.touched || isSubmit) || false" class="text-danger" data-text="填写您的密码">Vui lòng nhập lại Password</div>
                </span>
                <div class="option border">
                    <div class="option_result">Role</div>
                    <div class="option_arrow"><b class="arrow"></b></div>
                    <ul class="option_list">
                        <li>住户</li>
                        <li>管理员</li>
                        <li>运营商</li>
                    </ul>
                    <div class="tooltip" data-text="选择您的用户类型">选择您的用户类型</div>
                </div>
            </div>

            <div id="login_footer">
                <div class="ing"></div>
                <button id="login_btn" type="submit">LOGIN</button>
            </div>

            <div><a id="register_link" href="#">Quên mật khẩu!</a></div>
        </form>
    </div>
</div>
login.ts
Angular 2
import {
    Component,
    OnInit,
    Inject,
    OnDestroy,
    ViewChild,
    ElementRef
} from '@angular/core';
import {
    FormBuilder,
    FormGroup,
    FormControl,
    Validators
} from '@angular/forms';
import { Store } from '@ngrx/store';
import { AppState } from '../../../../AppState';
import { Observable } from 'rxjs/Observable';
import { Subscription } from 'rxjs/Subscription';

@Component({
    selector: 'login',
    templateUrl: './login.html',
    styleUrls: ['./login.scss'],
})
export class LoginComponent implements OnInit, OnDestroy {
    @ViewChild('focusOut') focusOut: ElementRef;

    protected formGroup: FormGroup;
    protected model = {
        username: '',
        password: ''
    }
    protected isSubmit = false;
    protected subscriptions: Subscription[] = [];

//    constructor(@Inject(FormBuilder) fb: FormBuilder,) {
//        this.formGroup = fb.group({
//        });
//    }

    get username() { return this.formGroup.controls.username; }
    get password() { return this.formGroup.controls.password; }

    ngOnInit(): void {
        this.validateFormGroup();
    }

    validateFormGroup() {
        const regex = /^[a-zA-Z0-9$@$!%*?&#^-_. +]+$/;
        this.formGroup = new FormGroup({
            username: new FormControl('', (c: FormControl) => {
                if (c.value && !regex.test(c.value)) {
                    return { halfsize: { valid: true, value: c.value } };
                }
                if (!c.value) {
                    return null;
                }
            }),
            password: new FormControl('', (c: FormControl) => {
                if (c.value && !regex.test(c.value)) {
                    return { halfsize: { valid: true, value: c.value } };
                }
                if (!c.value) {
                    return null;
                }
            }),
        });
    }

    onSubmit(): void {
        console.log(this.formGroup);
        if (this.formGroup.valid) {
            console.log(this.formGroup.valid);
            // do submit form data to server
        }
    }

    ngOnDestroy(): void {
        this.subscriptions.forEach((subscriptsion) => subscriptsion.unsubscribe());
    }

}
login.scss
Angular 2+ 2017
:host {
    /* #Reset & Basics (Inspired by E. Meyers) */
    html,
    body,
    div,
    span,
    applet,
    object,
    iframe,
    h1,
    h2,
    h3,
    h4,
    h5,
    h6,
    p,
    blockquote,
    pre,
    a,
    abbr,
    acronym,
    address,
    big,
    cite,
    code,
    del,
    dfn,
    em,
    img,
    ins,
    kbd,
    q,
    s,
    samp,
    small,
    strike,
    strong,
    sub,
    sup,
    tt,
    var,
    b,
    u,
    i,
    center,
    dl,
    dt,
    dd,
    ol,
    ul,
    li,
    fieldset,
    form,
    label,
    legend,
    table,
    caption,
    tbody,
    tfoot,
    thead,
    tr,
    th,
    td,
    article,
    aside,
    canvas,
    details,
    embed,
    figure,
    figcaption,
    footer,
    header,
    hgroup,
    menu,
    nav,
    output,
    ruby,
    section,
    summary,
    time,
    mark,
    audio,
    video {
        margin: 0;
        padding: 0;
        border: 0;
        font-size: 100%;
        font: inherit;
        vertical-align: baseline;
    }
    article,
    aside,
    details,
    figcaption,
    figure,
    footer,
    header,
    hgroup,
    menu,
    nav,
    section {
        display: block;
    }
    body {
        line-height: 1;
    }
    ol,
    ul {
        list-style: none;
    }
    blockquote,
    q {
        quotes: none;
    }
    blockquote:before,
    blockquote:after,
    q:before,
    q:after {
        content: '';
        content: none;
    }
    table {
        /*border-collapse: collapse;*/
        border-spacing: 0;
    }
    /* #Basic Styles
================================================== */
    #content {
        height: 100vh;
        background:-webkit-gradient(linear, 10% 87%, 10% 21%, from(#74C6FB), to(#9CD4F8));
        background: #9CD4F8;
        overflow: hidden;
        font: normal 16px/1.5 Helvetica, "Microsoft Yahei", Arial, sans-serif;
        color: #444;
        -webkit-font-smoothing: antialiased;
        /* Fix for webkit rendering */
        -webkit-text-size-adjust: 100%;
    }
    input {
        padding: 10px 15px;
        outline: 0;
        border: 0;
        border-radius: 3px;
        width: 200px;
    }
    a,
    a:visited {
        color: #333;
        text-decoration: none;
        outline: 0;
    }
    a:hover,
    a:focus {
        color: #000;
    }
    /*云层*/
    #clouds {
        position: absolute;
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;
        overflow: hidden;
    }
    [class^="cloud-"] {
        position: absolute;
        right: 120%;
        width: 200px;
        height: 60px;
        background: white;
        -webkit-border-radius: 200px;
        -moz-border-radius: 200px;
        border-radius: 200px;
    }
    [class^="cloud-"]:before,
    [class^="cloud-"]:after {
        content: '';
        position: absolute;
        top: -15px;
        left: 10px;
        width: 100px;
        height: 80px;
        background: #fff;
        -webkit-border-radius: 100px;
        border-radius: 100px;
        -webkit-transform: rotate(30deg);
        -moz-transform: rotate(30deg);
        transform: rotate(30deg);
    }
    [class^="cloud-"]:after {
        top: -55px;
        left: auto;
        right: 15px;
        width: 120px;
        height: 120px;
    }
    .cloud-1 {
        top: 50px;
        -webkit-animation: moveclouds 30s linear infinite;
        -moz-animation: moveclouds 30s linear infinite;
        -o-animation: moveclouds 30s linear infinite;
        animation: moveclouds 30s linear infinite;
    }
    .cloud-2 {
        top: 100px;
        opacity: 0.8;
        -webkit-transform: scale(0.8);
        -moz-transform: scale(0.8);
        transform: scale(0.8);
        -webkit-animation: moveclouds 45s linear infinite;
        -moz-animation: moveclouds 45s linear infinite;
        -o-animation: moveclouds 45s linear infinite;
        animation: moveclouds 45s linear infinite;
        -webkit-animation-delay: 5s;
        -moz-animation-delay: 5s;
        animation-delay: 5s;
    }
    .cloud-3 {
        top: 150px;
        opacity: 0.6;
        -webkit-transform: scale(0.6);
        -moz-transform: scale(0.6);
        transform: scale(0.6);
        -webkit-animation: moveclouds 40s linear infinite;
        -moz-animation: moveclouds 40s linear infinite;
        -o-animation: moveclouds 40s linear infinite;
        animation: moveclouds 40s linear infinite;
    }
    .cloud-4 {
        top: 200px;
        opacity: 0.75;
        -webkit-transform: scale(0.75);
        -moz-transform: scale(0.75);
        transform: scale(0.75);
        -webkit-animation: moveclouds 26s linear infinite;
        -moz-animation: moveclouds 26s linear infinite;
        -o-animation: moveclouds 26s linear infinite;
        animation: moveclouds 26s linear infinite;
        -webkit-animation-delay: 8s;
        -moz-animation-delay: 8s;
        animation-delay: 8s;
    }
    /*云层移动*/
    @-webkit-keyframes moveclouds {
        0% {
            right: -20%;
        }
        100% {
            right: 120%;
        }
    }
    @-moz-keyframes moveclouds {
        0% {
            right: -20%;
        }
        100% {
            right: 120%;
        }
    }
    @-o-keyframes moveclouds {
        0% {
            right: -20%;
        }
        100% {
            right: 120%;
        }
    }
    /* #Content Styles
================================================== */
    /*内容*/
    #content {
        width: 100%;
    }
    .container {
        width: 960px;
        margin: 0 auto;
        text-align: center;
    }
    /*登录/注册*/
    #login,
    #register {
        z-index: 9999;
        width: 400px;
        height: 380px;
        position: absolute;
        top: 50%;
        left: 50%;
        margin-top: -200px;
        margin-left: -200px;
        background: #F8F8F8;
        border-radius: 10px;
        box-shadow: 0 3px 6px rgba(0, 0, 0, 0.5);
    }
    #register {
        left: 120%;
    }
    #login_header,
    #register_header {
        height: 60px;
        line-height: 60px;
        font-size: 20px;
        font-weight: bold;
        color: #77CA60;
        background: #FFF;
        border-radius: 10px 10px 0 0;
        -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, .1);
        -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, .1);
        box-shadow: 0 1px 3px rgba(0, 0, 0, .1);
    }
    .icon-home {
        font-size: 30px;
        position: relative;
        top: 3px;
    }
    #login_content,
    #register_content {
        height: 260px;
        padding: 30px 20px;
    }
    input {
        width: 300px;
        padding: 14px 15px;
        background: #F0F0F0;
        font: normal 16px/1.5 Helvetica, "Microsoft Yahei", Arial, sans-serif;
        color: #444;
    }
    span {
        position: relative;
        display: inline-block;
        height: 50px;
        margin-bottom: 30px;
    }
    .tip {
        text-indent: 80px;
        -webkit-transition: all .3s ease-in-out;
        -moz-transition: all .3s ease-in-out;
        transition: all .3s ease-in-out;
    }
    .tip:focus,
    .tip:active {
        text-indent: 0;
    }
    .tip+label {
        position: absolute;
        top: 16px;
        left: 15px;
        -webkit-transition: all .3s ease-in-out;
        -moz-transition: all .3s ease-in-out;
        transition: all .3s ease-in-out;
    }
    .tip:focus+label,
    .tip:active+label {
        -webkit-transform: translateY(-40px);
        -moz-transform: translateY(-40px);
        transform: translateY(-40px);
    }
    .icon-user,
    .icon-lock {
        position: absolute;
        top: 16px;
        right: 14px;
        color: #999;
    }
    .tooltip {
        width: 200px;
        padding: 14px;
        position: absolute;
        left: 20%;
        top: 0;
        right: 0;
        color: #999;
        background: white;
        text-align: left;
        z-index: -1;
        box-shadow: 0 1px 3px rgba(0, 0, 0, .1);
    }
    .tooltip:after {
        width: 0;
        height: 0;
        content: "";
        position: absolute;
        right: 100%;
        top: 18px;
        color: #87CEFA;
        border: 8px solid;
        border-right-color: white;
    }
    #login_footer,
    #register {}
    #login_btn,
    #register_btn {
        width: 100%;
        height: 60px;
        line-height: 60px;
        outline: 0;
        border: none;
        color: white;
        font-weight: bold;
        font-size: 20px;
        background: #77CA60;
        border-radius: 0 0 10px 10px;
        cursor: pointer;
        text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.3);
    }
    .ing {
        width: 100%;
        height: 5px;
        position: absolute;
        bottom: 60px;
    }
    #register_link,
    #login_link {
        width: 120px;
        display: block;
        margin: 20px auto;
        color: white;
        border-bottom: 1px dashed;
    }
    /*下拉菜单*/
    .option {
        width: 300px;
        position: absolute;
        margin: 0 0 0 30px;
        text-align: left;
        background: #F0F0F0;
        cursor: pointer;
        border-radius: 3px;
    }
    .option_result {
        display: inline-block;
        padding: 11px 15px;
    }
    .option_arrow {
        padding: 10px 19px;
        float: right;
    }
    .option_arrow .arrow {
        width: 0;
        height: 0;
        font-size: 0;
        border: 6px solid;
        border-color: #6F7880 #F0F0F0 #F0F0F0;
    }
    .option_list {
        background: #F3F3F3;
        display: none;
    }
    .option_list li {
        padding: 10px 15px;
        float: none;
    }
    .option_list li:hover {
        background: #DFDFDF;
    }
} 
Run refer

0 nhận xét:

Post a Comment

 

BACK TO TOP

Xuống cuối trang