paulyoder / angular-bootstrap-show-errors Goto Github PK
View Code? Open in Web Editor NEWAn Angular directive for Bootstrap to intelligently show form validation errors
License: MIT License
An Angular directive for Bootstrap to intelligently show form validation errors
License: MIT License
I'd like to use and apply your project. For this purpose, please add a license type :) thx
I'm asking this, because I think it is worth to find an example in the docs explaining how to include the directive in own directives.
When including the directive into my own directive I have the following problem:
The $error
property is required
if the input field is left blank in the main app. In my directive the $error
property has no required
property. I can display error message still, because the has-error
class is added but I think it is better to work with ng-if.
<form name="myDataForm" ng-submit="save()">
<myDirective form="myDataForm" model="myModel" itemname="someName" error-msg="abc"></myDirective>
</form>
angular.module 'tsd.myDirective', ['ui.bootstrap.showErrors', 'tsd.fatSearch', 'myManageSomesService']
.directive 'myDirective', ($http, $rootScope, manageSomesService) ->
return {
restrict: 'E'
replace: true
scope:
form: '='
model: '='
size: '@'
itemname: '@'
label: '@'
templateUrl: 'directives/autocomplete-some/autocomplete-some.html'
controller: 'AutocompleteSomeCtrl'
}
<div class="form-group search-field" ng-class="size" show-errors>
<label>{{label}}</label>
<input type="text" class="form-control" name="{{itemname}}" ng-model="model" required placeholder="{{label}}" id="searchInput" ng-keydown="checkKeyDown($event)" ng-change="search()" required/>
<p class="help-block" ng-if="form[itemname][$error]">{{errorMsg}}</p>
...
When I nested two input
element with the ngSwitch
directive linked with a boolean flag, The show-errors
does not recognize the nested input
elements(in sub scope), but prints a error message on the console:
show-errors element has no child input elements with a 'name' attribute and a 'form-control' class <div class="form-group" show-errors="">
I am having trouble using the angularjs directive to show me errors on a bootstrap datefield:
<div class="form-group" show-errors>
<input type="date" name="dob" class="form-control" ng-model="fields.newDOB" style="width:75%; margin: 0 auto;" required/>
</div>
ng-required
does not work.
And for another form-group
in the same form, the errors display on all fields if there is one error. I tried adding show-error to each fields separately, but i got errors like that.
<div class="form-group" show-errors>
<label>Mobile Phone Number</label>
<input type="number" name="phone" class="form-control" ng-model="fields.newPhone" style="width: 75%; margin: 0 auto;" />
<label>Email</label>
<input type="email" name="email" class="form-control" ng-model="fields.newEmail" style="width:75%; margin: 0 auto;"/>
</div>
How can I fix these two issues?
Thanks!
From the angular docs:
Best Practice: In order to avoid collisions with some future standard, it's best to prefix your own directive names. For instance, if you created a
<carousel>
directive, it would be problematic if HTML7 introduced the same element. A two or three letter prefix (e.g. btfCarousel) works well. Similarly, do not prefix your own directives with ng or they might conflict with directives included in a future version of Angular.
See the Creating Directives section of the Angular Docs.
Thank you for this awesome directive. It works great for client side validation, but can I also use this to return an error message back from server side validation?
For example, if the user's email address does not exist, I display a custom error message in a separate div at the bottom of the form. What I would like to do, is remove that custom error message as soon as the user starts typing in a field.
Thanks
Here is an example of my div:
<div class="form-group" show-errors>
<div class="alert alert-danger" ng-repeat="error in formErrors">
<p>{{error}}</p>
</div>
</div>
I ran into trouble when i was combining angular-bootstrap-show-errors with angular-fontawesome. Looks like the selector used to select the input element is a little to lax.
Take a look at this quick and dirty plnkr here. As you can see the icon character for "user" is not displayed because the expression "formCtrl[inputName]" evaluates to undefined. Naturally showing errors fails too as a result for the user name input element. In the example "inputName" has the value "user" instead of "name" because the selector used in el[0].querySelector("[name]") takes whatever descendant element happens to have a name attribute. Unfortunately angular-fontawesome uses the name attribute too which causes the aforementioned error.
I suggest to use ".form-control[name]" as a selector instead since bootstrap form input elements are supposed to have the class "form-control" anyway as far as i can tell. What do you think?
The following example is given in the section "Force Validity Check":
<form name="userForm">
<div class="form-group" show-errors>
<input type="text" name="firstName" ng-model="firstName" ng-required />
</div>
<input type="submit" ng-click="save()" />
</form>
This does not set the required
attribute for current versions of Angular. ng-required
should be replaced by required
or ng-required="true"
here.
I am new to both Angular and Bootstrap, so take this with a grain of salt.
I have a requirement to have multiple form elements in a form group in a horizontal form.
<div class="form-group" show-errors>
<label for="firstName" class="col-sm-2 control-label">First Name*</label>
<div class="col-sm-4">
<input name='firstName' type="text" class="form-control" id="firstName" placeholder="First Name" ng-maxlength="50" ng-model="addPersonCtrl.dto.person.firstName" required>
<p class="help-block" ng-show="addPersonForm.firstName.$error.required">First name is required</p>
<p class="help-block" ng-show="addPersonForm.firstName.$error.maxlength">Max length exceeded</p>
</div>
<label for="lastName" class="col-sm-2 control-label">Last Name*</label>
<div class="col-sm-4">
<input name='lastName' type="text" class="form-control" id="lastName" placeholder="Last Name" ng-maxlength="50" ng-model="addPersonCtrl.dto.person.lastName" required>
<p class="help-block" ng-show="addPersonForm.lastName.$error.required">Last name is required</p>
<p class="help-block" ng-show="addPersonForm.lastName.$error.maxlength">Max length exceeded</p>
</div>
</div>
Coding it like this (which I believe to be correct) if one item in the row becomes invalid, the errors are shown on all items in the form group. As a work around I have created my own class, dh-sub-form-group, and applied it to a span that wraps the form elements:
<div class="form-group" >
<span class="dh-sub-form-group" show-errors>
<label for="firstName" class="col-sm-2 control-label">First Name*</label>
<div class="col-sm-4">
<input name='firstName' type="text" class="form-control" id="firstName" placeholder="First Name" ng-maxlength="50" ng-model="addPersonCtrl.dto.person.firstName" required>
<p class="help-block" ng-show="addPersonForm.firstName.$error.required">First name is required</p>
<p class="help-block" ng-show="addPersonForm.firstName.$error.maxlength">Max length exceeded</p>
</div>
</span>
<span class="dh-sub-form-group" show-errors>
<label for="lastName" class="col-sm-2 control-label">Last Name*</label>
<div class="col-sm-4">
<input name='lastName' type="text" class="form-control" id="lastName" placeholder="Last Name" ng-maxlength="50" ng-model="addPersonCtrl.dto.person.lastName" required>
<p class="help-block" ng-show="addPersonForm.lastName.$error.required">Last name is required</p>
<p class="help-block" ng-show="addPersonForm.lastName.$error.maxlength">Max length exceeded</p>
</div>
</span>
</div>
and then modified the show-errors javascript code to look for a different class:
return {
restrict: 'A',
require: '^form',
compile: function(elem, attrs) {
if (!elem.hasClass('dh-sub-form-group')) {
throw "show-errors element does not have the 'dh-sub-form-group' class";
}
return linkFn;
}
and modified the css
.dh-sub-form-group .help-block {
display: none;
}
.dh-sub-form-group.has-error .help-block {
display: block;
}
Is there a better way to do this or maybe this could be a future enhancement to support multiple form elements per group.
thanks
Hi,
very useful directive. But is there something planned (or an already existing approach) to easily support nested form validation? I know that doing it with a separate scope, like wrapping the form with a new controller would fix the issue, but isn't always wanted (as too much overhead for simple scenarios).
Currently the broadcast for showing validation errors is handled like...
scope.$on('show-errors-check-validity', function() {
return toggleClasses(formCtrl[inputName].$invalid);
});
where the formCtrl
is the one being injected into the directive.
Do you think it would be feasible do change the current implementation in order to be able to "optionally" pass in the form on which the validation error should be shown. I.e. like this:
$scope.$broadcast('show-errors-check-validity', $scope.mySubForm);
I'd also be willing to submit a PR, just wanted to know whether there are already any ideas/approches on handling this.
Thx 😄
Would it be possible to support placing show-errors
directive directly on form so that one doesn't need to repeat it on every form-group
in form?
There is any way to validate 2 fields like password and repeat password are same?
Thanks
First of all: tnx for the plugin, it works really nice :) It might as well be me doing something wrong but if I validate the form before any input is filled and then fill the form using autofill the .has-error class stays on all the fields. I've added this to the linkFn to make it work:
scope.$watch(function () {
return formCtrl.$invalid
}, function (val) {
if(val === false) {
toggleClasses(val);
}
});
Not sure if it's the right way to go though.
Good Morning,
I ve been reading that angular 2.0 will get rid off the $scope for controllers, so i took the approach not to use it. Do you know of any way to do $broadcast or any other workaround to get the same or some functionality as if i was using $scope?
I tried using the fix from #16, but unfortunately it doesn't work for me. What I have is something that looks like:
<div ng-repeat="field in fields" class="row form-group" show-errors>
<div class="col-md-8" ng-switch on="field.type">
<select ng-switch-when="select" name="form{{$index}}" class="form-control"></select>
<input type="number" ng-switch-when="number" name="form{{$index}}" class="form-control">
<input type="text" ng-switch-when="text" name="form{{$index}}" class="form-control">
</div>
</div>
This results in the error: show-errors element has no child input elements with a 'name' attribute and a 'form-control' class
However, if I change the code to:
<div ng-repeat="field in fields" class="row form-group" show-errors>
<div class="col-md-8">
<input type="text" name="form{{$index}}" class="form-control">
</div>
</div>
Everything works as expected.
Hey,
I love what you have done, but I seem to have hit a problem that hasn't been accounted for,
I have the following code:
<label class="radio-inline">
<input type="radio" name="gender" ng-model="model.gender" required value="Male" />Male
</label>
<label class="radio-inline">
<input type="radio" name="gender" ng-model="model.gender" required value="Female" />Female
</label>
For a button group, there isn't meant to be any form-control class on the inputs.
Is there any way of using your plugin to show errors here?
Given a form which has one label but multiple input elements per row:
zip/city [____] [_______]
Unfortunately angular-bootstrap-show-errors validates only the first input element.
Could you add an setting which turns blurred
into an array?
https://github.com/paulyoder/angular-bootstrap-show-errors/blob/master/src/showErrors.js#L27
This would allow us to show errors for multiple elements after all of them were touched.
Is possible to show a validation message together with the error
css class?
I'm getting the following errors after inserting into the script on my index page and module in application.
Script:
<script src="assets/global/scripts/showErrors.js" type="text/javascript"></script>Module:
var MetronicApp = angular.module('MetronicApp', ['MetronicApp.constants', 'MetronicApp.directives',
'MetronicApp.controllers', 'MetronicApp.services', 'ui.bootstrap', 'ui.router', 'ui.bootstrap.showErrors', 'oc.lazyLoad',
'ngSanitize', 'ngCookies']);
Errors:
SyntaxError: expected expression, got '<'
The current README file does not mention using a form-control
class on the target field, but when not used, script throws error: show-errors element has no child input elements with a 'name' attribute and a 'form-control' class <div class="form-group" show-errors="">
.
Using .form-control
class on a checkbox, ie. requiring a user to check that they agree with your terms and conditions, it's invalid bootstrap code for a checkbox. So the result is the checkbox has style applied to it that makes it look really messed up (appears gigantic and with a shadow border). Therefore, angular-bootstrap-show-errors
should not rely on a form-control
class being present.
Checkbox without .form-control
class:
On submit of the form, the control shoould be validated, even if they didn't blur.
So I propose to add this $watch:
scope.$watch(function () {
return formCtrl.$submitted;
}, function (submitted) {
if (submitted)
scope.$broadcast('show-errors-check-validity');
});
i've tested it, and it seems to work
Paul,
One more bug fix I forgot about that needs to be included (probably not the last one tbh, I always seem to find these odd bugs).
In AngularJS 1.3.0-rc.4 (finished in 5) they now allow the name
attribute to be dynamic. This is for dynamic forms validation with use of the ng-repeat
.
I think it should be 100% fine for legacy users, but I did not test the idea.
Include $interpolate
.
inputName = $interpolate(inputNgEl.attr('name') || '')(scope);
No rush to get this in, but at the moment show-errors
will not work in ng-repeat
without it. 😅
Thanks,
Austin
My controller function:
`$scope.save = function() {
$scope.$broadcast('show-errors-check-validity');
if ($scope.hotelForm.$valid) {
// save the user
}
}`
Form element
`
</div>
</form>`
I have a custom directive using a dropdown (which is using the dropdown ui of angular-bootstrap). My directive binds value to the ngModel, and $error messages onto the dom element. I have this wrapped in html like so:
<div class="form-group" show-errors>
<label for="pickColor">What is your favorite color?</label>
<my-color-dropdown name="pickColor" ng-model="params.color"></my-color-field>
<p class="help-block" ng-show="myForm.pickColor.$error.required">
Color is a required field</p>
<p class="help-block" ng-show="myForm.pickColor.$error.isNotBlack">
Your favorite color cannot be black!</p>
</div>
Any idea how I could get this to work?
Right now it complains that no input
field with class .form-control
is found. But I'm not using an input field, I have a <button></button>
which triggers a <ul>...</ul>
. The parent wrapper to which I attach the $error messages is a <section>
element.
I have a Settings
page with two subsections: General Settings
and Password Change
— two separate <form>
tags with the Submit
button each. When I press Submit button on any of this form I do $scope.$broadcast('show-errors-check-validity');
to check all fields in this form... but other form is also showing errors. So, how to validate fields only for one form, not for all forms on a page?
It took me a while to figure this out.
In addition to any other problems it may cause, if a form field has a name="name" attribute then the has-error class is not placed correctly allowing for the styles to trigger.
there may be number of cases when this is not possible due to form markup. One possible solution is to use *[name]
instead .form-control['name']
seems it breaks only one spec which tests .form-control class for existence. So there is no reason to restrict to .form-control.
just one of use cases may be directives similar to ui-select or other no standard form controls.
First, thank you very much for this great directive!
I try to use this with ui-select (https://github.com/angular-ui/ui-select). But I think there are conflicts and I'm not shure how to get it work. Also I'm not sure, if it's fixable in show-errors (maybe it must be "fixed" in ui-select?).
With this plunker (http://plnkr.co/edit/PRsXlYuJfrP46FhC5O0s?p=preview) you can reproduce the following:
show-errors-reset
) -> there is still an error indicator on the select (please notice: this is a different one of ui-select -> conflict?)Do you know a way to fix this? I already tried to "override" the ui-select style. Look at this hack:
.ui-select-bootstrap.ng-dirty.ng-invalid > button.btn.ui-select-match {
border-color: #CCC !important;
}
Obviously show-error isn't able to set the border-color, anymore.
Any help would be appreciated!
New directives show-errors-feedback
/show-success-feedback
could be created to add has-feedback
style to element, and glyphicon-remove
/glyphicon-ok
to $(element, .form-control-feedback.glyphicon)
I'm casting ng-repeat on a set of form-groups, each of which has the show-errors directive.
The ng-repeat repeats over a set of answers (ng-repeat="answer in answers"), each of which has a value attribute.
The graphics does not work properly, since the ng-model is 'answer.value', I suppose the directive thinks many form values are the same. Thus, only the last input created with that ng-model name is functional, though the other ones do change color according to the validation state of the last one.
Any solutions?
My code: http://hastebin.com/ikoyasusel.xml
Hi,
It would be very nice if this directive would support toggling the bootstrap icons as shown here: http://getbootstrap.com/css/#forms-control-validation ("With optional icons"). I'm still not 100% sure how to do this, but I guess that one way would be to check for the presence of a < i > tag, perhaps with a special CSS class attached to it, and then toggle the icons in it at the same time as the has-success and has-errors classes are turned on/off.
This could either be done automatically (detecting the presence of said < i > element), or configurable similar to the showSuccess option.
I use $setPristine on input (ng-model) control.
The resulting ng-form field has attributes:
{"$viewValue":"Пупкин","$modelValue":"Пупкин","$validators":{},"$asyncValidators":{},"$parsers":[],"$formatters":[null],"$viewChangeListeners":[],"$untouched":false,"$touched":true,"$pristine":true,"$dirty":false,"$valid":true,"$invalid":false,"$error":{},"$name":"last_name","$options":null}
I would suggest to indicate state only on $dirty inputs.
I used
bower install angular-bootstrap-show-errors
to install your directive and it pulled down version 1.0.0 not the latest git version 1.0.2
1.0.0 is missing the following text:
scope.$on('show-errors-check-validity', function () {
return el.toggleClass('has-error', formCtrl[inputName].$invalid);
});
Otherwise great work :)
Now it seems that library only supports <input>
elements and not <select>
nor <textarea>
.
I'm not sure if showErrors
can handle <select>
tag. After implementing show-errors
, it does not validate my dropdown.
<div class="form-group" show-errors> <label for="department" class="control-label col-md-2">Department</label> <div class="col-md-10"> <select class="form-control" id="department" name="department" ng-model="employee.departmentId" required> <option ng-repeat="d in departments" value="{{d.DepartmentID}}">{{d.DepartmentName}}</option> </select> <p class="help-block" ng-if="employeeFrm.department.$error.required">The department is required</p> </div> </div>
Thanks
With the change of the element queryselector to select elements based on type input and not an applied class of .form-control we have lost the ability to use show-errors to validate dropdown select boxes.
Hi is it possible to use this directive together with some WYSIWYG editor controls?
e.g. https://github.com/TerryMooreII/angular-wysiwyg
Since these editors need to display layout, they use DIV instead of INPUTs.
Following is the error message I got:
show-errors element has no child input elements with a 'name' attribute and a 'form-control' class
Hello,
Is it possible to trigger an error based on the errors returned by an AJAX form submit?
I couldn't get this working:
$scope.myForm.formField.$setValidity 'required', false
Thanks :)
A new directive show-success
could be created to apply has-success
style.
Should show-errors work inside of another (parent) directive's template? I see 'formCtrl' being injected as a result of require: '^form' but the instance of formCtrl is missing fields. This results in formCtrl[inputName] being undefined on line 39 when the event is triggered.
My parent directive uses templateUrl, so not sure if related to this issue. Still digging.
Update: Plunker Example -- hope I'm not missing something obvious, here.
Solution: This was unrelated to nesting in a directive template but rather a simple issue of not defining ng-model on the input fields. Lo siento.
Hey, I noticed it looks like you have a package.json
file for this repository, but the actual package (angular-bootstrap-show-errors
) does not exist in npm.
I'm using the bower version for now, but I've been trying to use npm versions of packages where possible. It's worth considering publishing this to npm!
Thanks for the hard work on this package btw!
Can I use show-errors with angular material ? I do not want to use bootstrap !
When I have filled a form out correctly and then hit submit, as the page is sent all the error styling and the help blocks become visible briefly before the page then re-navigates.
It is a minor issue but wondered if you a solution or workaround to prevent this?
Hi,
I've been using this directive in many forms, and it works like a charm.
Just one trouble i'm getting is about a form which has 2 states > non editable ; editable.
I'm using a boolean on my controller + ng-if on label & input to show just a static label or an input.
Once a ng-if is added on my input, show-errors directive won't work at all on the field.
I forked the default plunker with an easy example > email input is showed only if Name is filled with something.
http://plnkr.co/edit/4y48oj3xlBptcjqp4rws?p=preview
Any idea on how to keep show-errors working with ng-if ?
Thanks a lot, and keep the good work :-)
Thanks for this great directive. Really really thank you!
IMHO Check for class 'form-group' is nice but is done too early. It is a nice trick to do it during compilation phase but in my case 'form-group' class is added later by another directive during that directive's postLink function.
To fix my issue I moved the check to beginning of linkFn.
Any feedback is appreciated.
Thanks again!
Any examples on to use with an async validation function?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.