With the changes to angularjs and bootstrap 3 I have been unable to create a form field that's required where the item will be surrounded with red highlight by only adding the required parameter to the input field. Here is a plunker with how I have it setup on my system and would expect it to work. I can't seem to find any documentation on bootstraps site about required either so that would really help if anyone can find that.
Plunker
EDIT: Replaced all the following with below comments ideas... I would still like a solution where I don't need to write any css and use Bootstrap 3.
My form field looks like this:
<body ng-app>
<div ng-controller="Controller" class="container">
<form novalidate class="simple-form" name="myForm">
<div class="form-group col-sm-4">
Name: <input type="text" ng-model="name" name="name" class="form-control" required/>
E-mail: <input type="email" ng-model="email" name="email" class="form-control" required/>
<small class="error"
ng-show="myForm.email.$error.required">
Your name is required.
</small>
</div>
</form>
</div>
</body>
Script.js Looks like this:
function Controller($scope) {
$scope.name = "Test";
$scope.email = "";
}
Style.css looks like this:
input.ng-invalid {
border: 1px solid red;
}
While this works it replaces the bootstrap css with the css above. I would much prefer to simply add in required to an element and not have to rewrite the css to add the hue and the animation.
I agree with both of the other two answers but would like to add more
I think your main problem is that Bootstrap 3 removed styling based on the :invalid and related pseudo-classes (see here for why). This is where the red outline in bootstrap 2.x came from.
Firstly, to fix your plunker you should:
Bootstrap your app with ng-app as Mike says
Put your input in a form with novalidate
Give a model to your input with ng-model so that it can be invalidated (by angular, using classes)
Move jQuery script include before bootstrap as it is a requirement of bootstrap.
Now you have a plunker where the correct classes are applied to indicate input validity. You won't yet have styling on these, but they won't depend on your browser's HTML5 form validation, so will work in anything angular supports.
To apply styling, you can either use straight CSS and apply it to the ng-valid, ng-invalid, ng-invalid-required etc classes, or you can use the ng-class suggestion from this comment to apply bootstrap's classes when you need them
ng-class="{'has-error': formname.inputname.$invalid}"
if you have named your input and wrapped it in a control.
Updated plunker: http://plnkr.co/edit/mE3dkG?p=preview
Edit
I had a go at making a directive for this too. It may be overkill, but this should work wherever you have a form-group class and add an ng-form to the same element
.directive('formGroup', function(){
return {
restrict: 'C',
require: '?form',
link: function(scope, element, attrs, formController){
if(!formController)
return;
scope.$watch(function(){
return formController.$valid;
}, function(valid) {
if(valid)
element.removeClass('has-error');
else
element.addClass('has-error');
});
}
};
});
Yet another plunker: http://plnkr.co/edit/UQjRrA?p=preview
* The email will not be valid unless it looks like an email
You have a couple of things missing here. First, in order for a form field to validate it needs a unique name:
<input class="form-control" type="text" name="test" required/>
Second, in order to disable stock HTML5 validation, you need to add a novalidate attribute to the form:
<form class="form-horizontal" name="myForm" role="form" novalidate>
Third, and most importantly, your example has no app or controller associated with it, so angular is completely ignoring it. That one you have to fix yourself.
Read more about angular forms here: http://docs.angularjs.org/guide/forms
I suggest you this excellent step by step : http://www.ng-newsletter.com/posts/validations.html
Related
I have a input field that has the uib-popover control on it. I have followed the documentation on how to get the directive to open but I have noticed some discrepancies in the documentation as well as examples on plnker and SO questions here.
Within my hmtl I have the inputs set as follows:
<div class="form-group col-xs-6 col-sm-6 col-md-6 col-lg-6">
<label>Password</label><input type="{{user.inputType}}" ng-blur="user.validatePassword(user.newUser.password, user.newUser.confirmPassword)" placeholder="Enter Password" id="password" required class="form-control" ng-model="user.newUser.password" uib-popover-template="'myPopoverTemplate.html'" uib-popover-trigger="'focus'"/>
</div>
<div class="form-group col-xs-6 col-sm-6 col-md-6 col-lg-6">
<label>Confirm Password</label>
<input type="{{user.inputType}}" ng-keyup="user.validatePassword(user.newUser.password, user.newUser.confirmPassword)" placeholder="Confirm Password" id="confirmPassword" required class="form-control" ng-model="user.newUser.confirmPassword"/>
<span style="color: red">{{user.message}}</span>
</div>
Most examples as well as the SO questions on here are using an older library as attributes are not prefaced with uib-*.
This code/directive currently works and renders but it only work or appears when clicking in the field and then clicking in the same field to close the popover. I have tried both the focus trigger and the oustsideClick trigger. Both have the same result of not rendering or closing the popover unless clicking in the field.
versions of the frameworks used are:
angularjs 1.5.8
ui-bootstrap 1.3.3
Changing the trigger to match earlier examples were popover-trigger is used vs. uib-popover-trigger is used disables the popover
I have created a working plunker that demonstrates what is happening.
Any suggestions on what I am missing or what I need to change.
Thanks in advance
According to tooltip.js description, in order to set a custom trigger,
it needs to be specified via trigger option passed to the $tooltipProvider.options method. In your case for focus trigger it will be:
app.config(['$uibTooltipProvider', function ($uibTooltipProvider) {
$uibTooltipProvider.options({ trigger: 'focus' });
}]);
Updated plunker that shows how to trigger tooltip on focus handler.
There's a problem of your code, please modify like below:
app.js:
(function() {
var app = angular.module('app', ['ui.bootstrap']);
app.controller('main',[ '$scope', main]);
function main($scope)
{
vm = this;
vm.message = 'hello';
vm.dynamicPopover = {
content: 'Hello, World!',
templateUrl: 'myPopoverTemplate.html',
title: 'Title'
};
}
}());
index.html
<input class="form-control" uib-popover-template="vm.dynamicPopover.templateUrl" popover-trigger="focus"/>
Actually, you can not just pass the template's id to the uib-popover-template attribute, you need to create an object to map it waited to pass.
In my Angular app, I'm setting the placeholders in my form through some code in the controller (showing particular text for particular times of day).
When a user begins typing into any field of that form, I want all placeholders to be cleared.
To do this I understand I need to use $dirty using $watch
$scope.$watch('myForm.$dirty', function() {
//clear the placeholders
}, true);
My question is watch quite performance intensive in this situation or is there a more optimised way?
Thanks.
If you use $dirty and $watch it will work but it will clear all placeholders before you begins type or on controller load.
So, you can try this its work for me.
<div ng-controller="Ctrl">
<input type="text" ng-model="name1" ng-change="change()" placeholder={{placeholder1}}>
<input type="text" ng-model="name2" ng-change="change()" placeholder={{placeholder2}}>
<input type="text" ng-model="name3" ng-change="change()" placeholder={{placeholder3}}>
</div>
function Ctrl($scope) {
$scope.placeholder1="name";
$scope.placeholder2="city";
$scope.placeholder3="address";
$scope.change=function() {
$scope.placeholder1="";
$scope.placeholder2="";
$scope.placeholder3="";
};
}
I just tried introducing ngMessages into my app that's using Components that were added in 1.5. As soon as I include any reference to ngMessage in my template I'm receiving this error message:
Error: $compile:ctreq Missing Required Controller.
This is a common error with ngMessages and the normal remedy is
suggested here:
https://docs.angularjs.org/error/$compile/ctreq?p0=ngMessages&p1=ngMessage
However, I'm using components, which are a special type of directive and this doesn't appear to be an option for components.
Has anyone gotten ngMessages to work within a component in 1.5?
The syntax for use with a directive is like this:
myApp.directive('myDirective', function() {
return {
require: 'ngModel',
...
}
}
The component documentation: https://docs.angularjs.org/guide/component doesn't cover an equivalent to require.
This might help you.
<form name="userLoginForm" autocomplete="off">
<input type="text" minlength="10" maxlength="10" ng-pattern="/^[0-9]+$/" required ng-model="userData.mobileNumber" placeholder="Enter Mobile Number" class="form-control login-form-input" id="mobileNumber" name="mobileNumberInput"/>
<div ng-messages="userLoginForm.mobileNumberInput.$error" role="alert">
<div ng-message="required">
This field is required
</div>
<div ng-message="pattern">
Enter correct mobile number
</div>
<div ng-message="minlength, maxlength">
Your mobile number must 10 characters long</div>
</div>
</div>
It happens when you don't have correct div structure.
First div has to include ng-messages, and one inside should be ng-message.
From Documentation:
<ANY **ng-messages**="expression" role="alert">
<ANY **ng-message**="stringValue">...</ANY>
</ANY>
Angular's debug message is unhelpful in this instance and cause more confusion.
I have to style/replace all checkboxes and radio buttons with images.
I can do this easily by simply adding a span tag after every input(checkbox / radio) like.
<label for="rememberme">
<input type="checkbox" class="unique" id="rememberme"/>
<span class="icon-checkbox"></span>
</label>
How can i do this in angular js.
I cannot modify all htmls with adding a span element, as if something went wrong it will take time to revert.
But i have a unique class or i can add an attribute to write a directive.
I tried using an attribute but i am unable to inspect span element generated, it is working good if i use it as an element.
If i use as an attribute it is giving an output as
<input type="text" class="form-control" custom-input="">
<input type="text" class="form-control">
<span class="icon-checkbox">Checkbox icon</span>
</input>
is this Valid ?
Plunker here
I wouldn't worry about a custom directive just to replace the checkboxes with images. You could do this with CSS like this:
<!--HTML-->
<input type="text" class="form-control checkboxwithicon">
/*CSS*/
.checkboxwithicon{
position:relative;
}
.checkboxwithicon::after{
content:url('http://icons.iconarchive.com/icons/icojam/blueberry-basic/32/check-icon.png');
position:absolute;
top:-10px;
left:15px;
}
And position the image properly so that the checkbox is hidden.
You can write a directive that does generate the span icon-checkbox after the element (it's supposed to be a checkbox) for you and make it act like an attribute, then you can tag it in every input checkbox that you want. Even something wrong happens and you are not happy with the change, you don't have to waste your time and effort to revert the things back, just modify on the directive only.
I made it working from your suggestions with out any change to HTML for easy fallback
.directive('input',function(){
return{
require: '?ngModel',
restrict:'EAC',
link:function(scope,element,attr){
var html = angular.element("<span class='icon-checkbox'>Checkbox icon</span");
if( (angular.lowercase(element[0].tagName)==="input") && (angular.lowercase(attr.type)=== "checkbox"))
element.after(html)
}
}
})
Working Plunker
I'm new to AngularJS and needing help on how to toggle classes on form elements if the input is valid or invalid.
I have noted that most validation is done within the DOM - see here: https://scotch.io/tutorials/angularjs-form-validation
However, I'm wanting to avoid using the dom to handle validation. I want to use a custom directive to handle if a input is valid or invalid based upon validation rules.
Here is my HTML / Angular markup so far:
<fieldset ng-class="{error: loginForm.username.$invalid}">
<div class="form-input-error" ng-show="loginForm.$error">
Username is too short.
</div>
<div class="vfnz-fieldWrapper">
<input
type="text"
id="username"
ng-model="username"
class="vfnz-input--text"
placeholder="Username"
ng-minlength="3"
ng-maxlength="8" />
<label for="name" class="vfnz-input-label">
Username
</label>
</div>
</fieldset>
Here is a JSFIDDLE of my code so far
Basically when a input is invalid - add class to the fieldset. If the input is valid add class to fieldset.
from angular 1.3.x they came up with ng-messages ,i think you should try this. The advantages of using it is it will show the appropiate error if your input contains multiple error's.Add your class to the validation div
the below example checks for required and number .
<form name='cliForm'>
<input ng-model="vm.formData.newCreditLimit" type="text" name="changeCreditLimit" ng-pattern="/^[0-9]{1,15}$/" required />
<div class="highlight" ng-messages="cliForm.changeCreditLimit.$error" ng-if="cliForm.$submitted">
<div ng-message="required">* This field is required!</div>
<div ng-message="pattern">* Not a valid number!</div>
</div>
</form>
before using this include the ng-messages script since its in different module and inject the ng-messages to your angular module
I'm also looking for a solution to this issue, but the (lazy) answer I'm opting for right now is just to let some directives determine whether the element is valid or invalid, and just let angular handle the css classes. What I'm doing is to just add the ff to my css file:
.ng-invalid {
border-color: #e51c23;
color: #e51c23 !important;
}
.ng-error {
border-color: #e51c23;
color: #e51c23 !important;
}
.ng-valid {
border-color: #4CAF50;
color: #4CAF50 !important;
}