2016-12-01 121 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的功能。