2016-12-01 198 views
9

我有一個表單,其中一個字段充當自動完成。如果用戶輸入一個單詞並按下回車鍵,則該字段的內容應添加到該字段下方的列表中。Angular 2:如何防止表單按鍵提交輸入?

問題:當用戶點擊輸入時,自然會提交整個表單。我在return false上處理按鍵的功能。但是在調用這個函數之前,表單似乎已經被提交了。

如何防止這種情況發生?

基本形式:

<div id="profileForm"> 
    <form [formGroup]="profileForm" (ngSubmit)="onSubmit()" method="post" *ngIf="!showSuccessMessage"> 

    <div class="row"> 

     <div class="form-group col-xs-12 col-sm-6"> 
     <label for="first_name">My Skills</label> 
     <div class="autocomplete"> 
      <input formControlName="skill_string" [(ngModel)]="skillString" name="skill_string" 
      type="text" class="form-control" id="skill_string" placeholder="Comma separated" (keyup.enter)="skillsHandleEnter(skillString)"> 
      <ul class="autocomplete-list" *ngIf="skillHints.length > 0"> 
      <li class="list-item" *ngFor="let skill of skillHints" (click)="addSkillFromAutocomplete(skill)">{{skill}}</li> 
      </ul> 
     </div> 
     <div id="skill-cloud" class="tag-cloud"> 
      <span class="skill-tag tag label label-success" *ngFor="let skill of selectedSkills" (click)="removeSkill(skill)">{{skill}} x</span> 
     </div> 
     </div> 

    </div> 

    <div class="row"> 

     <hr> 

     <div class="form-group submit-group"> 
     <div class="col-sm-12"> 
      <button type="submit" class="btn btn-primary pull-right" [disabled]="!profileForm.valid">Save</button> 
     </div> 
     </div> 

    </div> 

    </form> 
</div> 

的基本成分(我剝奪了很多邏輯的在這裏張貼):

import { Component, OnInit } from '@angular/core'; 
import { FormGroup, FormBuilder } from '@angular/forms'; 
import { ActivatedRoute, Router } from '@angular/router'; 

import { Subscription } from 'rxjs/Rx'; 
import 'rxjs/add/operator/debounceTime'; 
import * as _ from 'lodash'; 

import { MemberService } from '../shared/index'; 

@Component({ 
    moduleId: module.id, 
    selector: 'signup', 
    templateUrl: 'signup.component.html', 
    styleUrls: ['signup.component.css'] 
}) 
export class SignupComponent implements OnInit { 

    private profileForm:FormGroup; 
    private validation_errors:Array<any>; 
    private selectedSkills:Array<string>; 
    private skillHints:Array<string>; 
    private skillString:string; 

    constructor(private route: ActivatedRoute, 
    private formBuilder: FormBuilder, 
    private memberService: MemberService, 
    private router: Router) { 

     this.selectedSkills = []; 
     this.skillHints = []; 
     this.skillString = ''; 

     // Set up form 
     this.profileForm = this.formBuilder.group({ 
     skill_string: [''] 
     }); 

    } 

    ngOnInit(): any { 
    // Do something 
    } 



    updateSelectedSkills(skillString:string):void { 
    if(skillString)) { 
     let cleanString = skillString.trim().replace(/[ ]{2,}/g, ' '); 
     this.selectedSkills = _.compact(this.selectedSkills.concat(cleanString.split(','))); 
     this.skillString = ''; 
     this.skillHints = []; 
    } 
    } 

    skillsHandleEnter(skillString:string):void { 
    console.log("ENTER"); 
    this.updateSelectedSkills(skillString); 
    return false; 
    } 

    autocompleteSkills(term:string):void { 
    this.memberService.autocompleteSkills(term).subscribe(
     res => { 
     this.skillHints = []; 
     for(let i = 0; i < res.data.length; i++) { 
      this.skillHints.push(res.data[i].name); 
     } 
     } 
    ); 
    } 

    addSkillFromAutocomplete(skillString:string):void { 
    this.selectedSkills.push(skillString); 
    this.memberProfile.skill_string = ''; 
    this.skillHints = []; 
    this.skillString = ''; 
    } 


    onSubmit():void { 
    this.memberService.saveProfile(this.memberProfile, this.selectedSkills).subscribe(
     res => { 
     console.log(res); 
     } 
    ); 
    } 

} 
+0

你看到了嗎? http://stackoverflow.com/questions/19549985/prevent-form-submission-on-enter-key – Matthias

+0

@Matthias:是的,但是:「這個解決方案只適用於按鈕,但如果你在輸入類型中按」enter「 - 文本字段 - 您仍然有表單發送。「 - 我也已經嘗試刪除提交按鈕。沒有運氣。 –

回答

10

嘗試

<form (keydown.enter)="$event.target.tagName == 'TEXTAREA'" [formGroup]="profileForm" (ngSubmit)="onSubmit($event)"> 

它也將允許enterTextarea s。

+0

只是一個提示。返回'false'還會調用'$ event.preventDefault()' –

+0

@GünterZöchbauer感謝提醒,讓它更緊湊然後 –

+0

但是現在它不會返回'false'。也許'「!!($ event.target.tagName =='TEXTAREA)'」'(不知道這個'!!'操作符 - 我自己沒有使用JS/TS - 只有Dart) –

2

活動在角2的行爲像正常的DOM事件。要捕獲事件對象,通過$event在從模板事件回調參數:

HTML:使用

<button (keyup.enter)="skillsHandleEnter($event, skillString)"></button> 

的JavaScript Event.preventDefault()

@Component(...) 
class MyComponent { 
    skillsHandleEnter(event, skillString) { 
    event.preventDefault(); 
    // ... your logic 
    } 
} 
6

所以答案其實很簡單......這不是Event.preventDefault(),因爲我在輸入字段上輸入Enter而不是按鈕。從button中刪除type="submit"是不夠的,因爲所有按鈕默認都是鍵入提交的。必要的唯一的變化是按鈕元素添加type="button"明確並增加了(click)聽衆:

<button type="button" (click)="onSubmit()" class="btn btn-primary pull-right" [disabled]="!profileForm.valid">Save</button> 

唯一一種-的問題:現在提交表單與輸入永遠不會奏效。如果焦點位於自動填充輸入字段中,只會阻止提交表單,這會稍微優雅一些​​。

編輯:

要僅防止提交表單輸入當光標在自動完成場可以通過使用ANKIT Singh的溶液並修改它位來實現:

<form [formGroup]="profileForm" (ngSubmit)="onSubmit()" method="post" (keydown.enter)="$event.target.id != 'skill_string'" *ngIf="!showSuccessMessage"> 

(注意:條件必須返回false以防止默認動作被觸發)

當然,我們需要再次使用我們的常規提交按鈕(沒有附加的點擊事件或fo RM將提交兩次):

<button type="submit" class="btn btn-primary pull-right" [disabled]="!profileForm.valid">Save</button> 

你也可以檢查event.target.classList,如果你想使用一個.autocomplete類。或者將檢查邏輯移至您通過$event的功能。

相關問題