4

I have the following code for demo purposes, showing a simple form row with error messages and a submit button:

<form [ngFormOptions]="{updateOn: 'submit'}">
   <tid-form-row>
      <label tid-ui-label for="temperatureInput">Temperature:</label>
      <input [tid-ui-input]="{required: true}" id="temperatureInput" name="temperatureName" placeholder="20,4"
             [(ngModel)]="temperatureModel" #temperature="ngModel" [tidDigits]="{integer: 2, fraction: 1}" required>
      <ng-template #hint>
         <small tid-ui-hint>The yellow color indicates that this field is required.</small>
      </ng-template>
      <div tid-ui-error *ngIf="temperature.invalid && (temperature.dirty || temperature.touched); else hint">
         <span *ngIf="temperature?.errors.required">Field is required.</span>
         <span *ngIf="temperature?.errors.tidDigits">Must be max 2 integer digits and max 1 fraction digit.</span>
      </div>
   </tid-form-row>
   <tid-button type="submit">Check validation</tid-button>
</form>

where tidDigits is a custom ValidatorDirective with this ValidatorFactory:

export function digitsValidator(config: any): ValidatorFn {
  return (control: AbstractControl): {[key: string]: any} => {
    const value = control.value;
    const errorObject: any = {tidDigits: {value: control.value}};
    let passed = true;

    if (value) {
      const [integer, fraction] = value.split(',');
      if (config.integer && config.integer >= 0) {
        if (integer.length > config.integer) {
          passed = false;
          errorObject.tidDigits.integer = integer.length;
        }
      }
      if (config && config.fraction && config.fraction >= 0) {
        if (fraction.length > config.fraction) {
          passed = false;
          errorObject.tidDigits.fraction = fraction.length;
        }
      }
    }
    return passed ? null : errorObject;
  };
}

I want the demo to show the different error messages when the user clicks the submit button. For this is a demo form, I do not want the form to submit at all.

The error messages show up correctly (after pressing the submit button) when the field is empty (required-Validator) or e.g. 20,44 is entered (tidDigits-Validator). However, if a valid value is entered (e.g. 20,4), the form submits - i.e. the page is reloaded and the field name is appended to the URL: /tid-form-row?temperatureName=20,4

Is there any way to prevent a form from submitting at all?

I tried (ngSubmit)="onSubmit()" with onSubmit() { return false; } and also (ngSubmit)="$event.preventDefault()" as stated here, but it did not work. Any other ideas?

Adrien Brunelat
  • 4,492
  • 4
  • 29
  • 42
Florian Gössele
  • 4,376
  • 7
  • 25
  • 49

2 Answers2

6

The default value of the type attribute in a <button> tag is submit, if you want to prevent that, you need to overwrite this with:

<button type="button"></button>

Removing type="submit" won't suffice, more details here: HTML button to NOT submit form


If you want to validate anyway, maybe you could try the following:

<form #form>
    <button type="button" (click)="validateForm(form)"></button>
</form>

And, in your Typescript code:

public validateForm(form: NgForm) {
  for (const control in form.controls) {
    control.updateValueAndValidity();
  }
}
Adrien Brunelat
  • 4,492
  • 4
  • 29
  • 42
0

Try removing the type="submit" on the button.

If you have (ngOnSubmit) defined on your form element, any submit button will activate that function. I typically just use the (click) event listener on buttons within forms to activate functions.

Is there a reason you are bypassing the validation on input changes? Unfortunately you are listening for submit. So you may have to backtrack a little and re-engineer the solution. You could run the updateValueAndValidity on your form controls when the button has a (click) event. For most of this to work, you may need to use a Reactive Form instead of a Template Driven Form though.

Check out AbstractControl

joshrathke
  • 7,564
  • 7
  • 23
  • 38
  • 1
    "submit" is the default button type in a form, isn't it? It is a customer requirement to validate the input fields not on blur or changes but on submit. The problem here is, that I need the "submit" action for Angular to validate the form - but I want to prevent the form from being submitted, also if the validation succeeds. Switching to Reactive Forms is possible, but would be some kind of effort. – Florian Gössele Jan 04 '18 at 07:49
  • 1
    If I were you I'd switch to reactive forms. And setup your `(ngOnSubmit)` function to run the `updateValueAndValidity()` function on the form controls. I think you might be hitting your head on the ceiling with the template driven approach. – joshrathke Jan 04 '18 at 15:06