Skip to content

Add guidance for styling invalid inputs #348

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Pixcell opened this issue Apr 25, 2016 · 25 comments
Closed

Add guidance for styling invalid inputs #348

Pixcell opened this issue Apr 25, 2016 · 25 comments
Assignees
Labels
docs This issue is related to documentation feature This issue represents a new feature or feature request rather than a bug or bug fix

Comments

@Pixcell
Copy link

Pixcell commented Apr 25, 2016

Note: for support questions, please use one of these channels:
https://github.com/angular/material2/blob/master/CONTRIBUTING.md#question.
This repository's issues are reserved for feature requests and bug reports.

  • Do you want to request a feature or report a bug?
    Feature
  • What is the current behavior?
    The only class available on md-input is .md-focused
  • If the current behavior is a bug,
    please provide steps to reproduce and if possible a minimal demo of the problem

    via https://plnkr.co or similar.
  • What is the expected behavior?
    It would be great if the classes of ngControl could be transfered to the md-input label and the md-input underline, in order to display live return on the validity of inputs
  • What is the motivation / use case for changing the behavior?

Better User experience

  • Which version of Angular and Material, and which browser and OS does this issue affect?
    Did this work in previous versions of Angular / Material?
    Please also test with the latest stable and snapshot versions.
  • Other information
    (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix)
@jelbourn jelbourn changed the title input validation system (ngControl support) (CSS) Add guidance for styling invalid inputs Apr 25, 2016
@jelbourn jelbourn added the feature This issue represents a new feature or feature request rather than a bug or bug fix label Apr 25, 2016
@jelbourn jelbourn added this to the alpha.6 milestone Apr 25, 2016
@cschroeter
Copy link

import {Directive, HostBinding} from '@angular/core';

@Directive({
    selector: '[input-error]'
})
export class InputErrorDirective {

    @HostBinding('attr.dividerColor')
    get isValid() {
         // Checks..
         return 'warn';
    }
}

The @HostBinding or better the setAttribute() function is not case-sensitive. This results in

<md-input [...] dividercolor="warn"></md-input> 

and unfortunately this don't work.

Any ideas?

@leocaseiro
Copy link
Contributor

For the time being, I'm using a md-hint to show my error messages:

<md-input>
    <md-hint *ngIf="error" [ngStyle]="{'color': 'red'}" align="start">{{errorMessage}}</md-hint>
</md-input>

It might help someone

@csabattilas
Copy link

Is there a class we can use linked to theming?

@leocaseiro
Copy link
Contributor

leocaseiro commented Oct 13, 2016

@krigton You can use the SASS md-color for theming,

.unicorn-carousel {
    color: md-color($warn);
}

see more on the guide

@csabattilas
Copy link

so no class already there for errors? we can put what we want?

@leocaseiro
Copy link
Contributor

leocaseiro commented Oct 24, 2016

Hi @krigton, yep. My solution is temporary.

Hope works for you.

You can use any color from material or create your own.

update from md to mat

Example:

@import '~@angular/material/core/theming/all-theme';
@include mat-core();

.red {
    color: mat-color($mat-red, 500, 1);
}

.warn {
   color: mat-color($warn);
}

@jelbourn jelbourn modified the milestone: alpha.7 Nov 1, 2016
@csabattilas
Copy link

@leocaseiro thanks

@artem-galas
Copy link

@leocaseiro Thanks for your idea.
But could you please explain, how to make two validation message?
For example, I have such a form:

<form [formGroup]="signUpForm" class="sign-up" (ngSubmit)="signUp(signUpForm)" >
      <md-input formControlName="fullName" placeholder="Full name">
        <md-hint *ngIf="signUpForm.hasError('required','fullName')" [ngStyle]="{'color': 'red'}" align="start">Full name is required</md-hint>
      </md-input>
      <md-input formControlName="userName" placeholder="User name">
        <md-hint *ngIf="signUpForm.hasError('required','userName')" [ngStyle]="{'color': 'red'}" align="start">User name is required</md-hint>
      </md-input>
      <md-input formControlName="email" type="email" placeholder="Email">
        <md-hint *ngIf="signUpForm.hasError('required','email')" [ngStyle]="{'color': 'red'}" align="start">Email is required</md-hint>
        <md-hint *ngIf="signUpForm.hasError('pattern','email')" [ngStyle]="{'color': 'red'}" align="start">example@mail.com</md-hint>
      </md-input>
</form>

@leocaseiro
Copy link
Contributor

Hi @artem-galas,

I actually made my message error dynamic, so I have a single <md-hint>.

In that case, I update the message depending on the error.

If it's not clear, I'm happy to send you an example.

@artem-galas
Copy link

@leocaseiro Thanks, I got the idea. It would be awesome if you send me a snippet.

@leocaseiro
Copy link
Contributor

export class AppComponent {

  model = { email: '' }

  validateEmail(email) {
    var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
    return re.test(email);
  }

  errorMessageEmail() {
    if (this.model.email === '') {
      return 'Email is required!';
    } else if (!this.validateEmail(this.model.email)) {
      return 'Email is invalid!';
    } else {
      return false;
    }
  }
}
  <form>
    <md-input placeholder="Email" [(ngModel)]="model.email" name="email" type="email" required>
      <md-hint *ngIf="errorMessageEmail()" [ngStyle]="{'color': 'red'}" align="start">{{errorMessageEmail()}}</md-hint>  
    </md-input>
  </form>

Here is the plunker: http://plnkr.co/edit/ZKd1OR2rpey3WddbEpRv?p=preview

PS: It's just a snippet for demo purpose, use ReactiveFormsModule for validation.

@mcalmus
Copy link
Contributor

mcalmus commented Jan 25, 2017

md-hint works fine for inputs, but there's no similar facility for select items, checkboxes, etc.

@DmitryEfimenko
Copy link

DmitryEfimenko commented Feb 28, 2017

I created directives similar to ng1's ng-messages. Here's an example how you'd use it:

<md-input-container>
  <input mdInput formControlName="name" placeholder="Account name" required type="text">
  <md-hint [val-messages]="myForm.get('name')">
    <span val-message="required">Required</span>
  </md-hint>
</md-input-container>

The example above conviniently slaps it on md-hint, but you can put it on any html element.
I know this does not directly addresses the issue, but hopefully helps a bit.

@jelbourn jelbourn added the docs This issue is related to documentation label Apr 9, 2017
@abqadeer
Copy link

How to divider color for md-select? I have got validations to work on inputs on submit but for select it works only if you have touched it once atleast and then click submit.

@tmburnell
Copy link

@abqadeer, can you give an example of how you got the validations on submit to work?
I could not figure out how to set touched on elements on submit for it to work correctly.

however i did the following for the error message colors:
+input did not mark errors in red
+select does not have a container, so not md-hint. So i created one that mocked it.

md-input-container.ng-touched.ng-invalid {
	/deep/ .mat-input-placeholder {
		color: $error;
	}

	/deep/ .mat-input-underline {
		border-top-width: 1px;
		border-color: $error;
	}

	/deep/ .mat-input-ripple {
		background-color: $error;
	}

	md-hint {
		color: $error;
		float: right;
	}
}

div.select-container {
	position: relative;

	.md-hint {
		color: $error;
		padding-top: 2px;
		font-size: 75%;
		position: absolute;

		right: 0;
	}
}

@tmburnell
Copy link

I just realized they they added md-error ... and the need for some of my css is no longer needed. However I still dont know how to make the input trigger in error when you have not touched it.

@coder925
Copy link

coder925 commented May 3, 2017

@tmburnell , there is a workaround described in #4232 for allowing the md-error to show an error even if the control is not touched.

@CDDelta
Copy link

CDDelta commented May 3, 2017

@tmburnell running .valid on the input form will also show the md-error on all invalid inputs. (*for reactive forms)

@onalbi
Copy link

onalbi commented May 3, 2017

If this can help someone, md-error works fine with formControl, for example:

[HTML]

          <fieldset [disabled]="isSubmitting">
                <md-input-container class="full-width">
                    <md-error>{{tagField.errors ? tagField.errors.missedTag : null}}</md-error>
                    <input mdInput class="article-tags" type="text" placeholder="Enter tags"
                           [formControl]="tagField" (keyup.enter)="addTag()"/>
                    <md-chip-list>
                        <md-chip *ngFor="let tag of article.tags">
                            <md-icon (click)="removeTag(tag)">delete</md-icon>
                            <span>{{tag}}</span>
                        </md-chip>
                    </md-chip-list>
                    <md-hint>Press [enter] to add the tag</md-hint>
                </md-input-container>
            </fieldset>
            <fieldset [disabled]="isSubmitting">
                <button md-raised-button type="button" (click)="submitForm()" [disabled]="checkValidForm()">
                    <md-icon>publish</md-icon>
                    <span>Submit</span>
                </button>
            </fieldset>

[TS]

this.fb.group({tagField: []});

checkValidForm(): boolean {
        if (this.article.tags.length < 1) {
            this.tagField.setErrors({'missedTag': 'Please add at last one tag'});
        }
        return !this.articleForm.valid || this.article.tags.length < 1;
}

@mmalerba
Copy link
Contributor

mmalerba commented May 5, 2017

Closing this since we now have <md-error> and a section in the input documentation on how to use it

@mmalerba mmalerba closed this as completed May 5, 2017
@davorzdralo
Copy link

@mmalerba - we do? The documentation on https://material.angular.io/components/input/overview is broken, I can't see example code and Plunkers don't do anything, and docs don't even try to explain how to have multiple messages.

@steve-todorov
Copy link

The docs seems to be broken here as well. Was looking forward to experimenting with this feature, but will have to wait a while until everything is back to normal.

@atbe
Copy link

atbe commented Jul 3, 2017

@davorzdralo Confirmed still broken on my end.

@willshowell
Copy link
Contributor

@davorzdralo @steve-todorov @atbe

Dunno why that particular example is broken (cc @amcdnl), but the source is here:

https://github.com/angular/material2/tree/master/src/material-examples/input-errors

and here's the example in a plunker:

https://plnkr.co/edit/mS8vyDKHLUhC9YOr84Aw?p=preview

andrewseguin pushed a commit to andrewseguin/components that referenced this issue Oct 15, 2018
@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 6, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
docs This issue is related to documentation feature This issue represents a new feature or feature request rather than a bug or bug fix
Projects
None yet
Development

No branches or pull requests