Angular UI date picker error message in same line - angularjs

In this plunk I have an Angular UI date picker with an error message that is displayed when the date is invalid. Problem is that the error message is shown below the date instead of the same line. How to fix this?
HTML
<form name="form1" ng-submit="validate(form1)" novalidate>
<p class="input-group" style="width:160px;margin-bottom:0px;">
<input type="text" class="form-control" ng-model="dtFrom"
is-open="config1.opened" uib-datepicker-popup="MM-dd-yyyy"
close-text="Close" name="dtFrom" />
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="open1($event)">
<i class="glyphicon glyphicon-calendar"></i>
</button>
</span>
</p>
<div style="background-color:red;color:white;width:150px"
ng-show="!form1.dtFrom.$valid">Invalid Date</div>
</form>
Javascript
var app = angular.module('ui.bootstrap.demo', ['ui.bootstrap']);
app.controller('ctl', function ($scope) {
$scope.dtFrom = new Date ();
$scope.config1 = {};
$scope.config1.opened = false;
$scope.open1 = function(event){
event.preventDefault();
event.stopPropagation();
$scope.config1.opened = true;
};
});

You can add class list-inline in it.
Here is plnkr
http://plnkr.co/edit/23CxCMDRK6DBiW115K7T?p=preview

The reason you are seeing this misalignment is because you are using bootstrap classes but are not correctly applying them to all the corresponding elements. When you use an input-group as you've applied to the <p> element, you are using a specific bootstrap class that adds styling to the components, like display:table. To have a correct behavior for the whole form, you need to keep using these classes on sibling elements. Namely input-group and form-control. Using these you will notice that its better aligned to its neighbor in both position and height. Additionally its best to wrap all these components in a valid row and column classes for parent elements. I've added an updated version of your plnkr showing how these changes behave:
plnkr

Related

Get pristine value in Angular controller

I need to be able to see in the Angular controller if the datepicker is pristine or not. Tried all sorts of things including sending the pristine value in a method but cannot get this value. Below is the view code:
<form name="myForm">
<!-- Datepicker From -->
<div class="small-6 medium-5 large-2 columns" ng-if="vm.subViewActive">
<div class="input-group">
<input name="valuationDatePickerFrom" ng-model="name" type="text" class="datepicker" id="valuationDatePickerFrom" placeholder="DD/MM/YYYY" pikaday="vm.datePickerFrom" on-select="vm.selectStartDate(pikaday)" year-range="{{ vm.yearRange }}" >
<div class="input-group-addon">
<label for="valuationDatePickerFrom" class="postfix">
<i class="fa fa-calendar"></i> From
</label>
</div>
</div>
</div>
</form>
and then I also tried :
var isPristine = $scope.myForm.valuationDatePickerFrom.$pristine;
console.log(isPristine);
in my controller but cannot get the pristine value. Read lots of posts here but mainly to do with CSS classes and front-end control or setting the pristine state from the backend not getting or checking the pristine state.
Thanks anybody that can help.
You are using:
var isPristine = $scope.myForm.valuationDatePickerFrom.$pristine;
but your form's name is not myForm.
Change <input name="name"... <input name="valuationDatePickerFrom"...
Then you can use:
var isPristine = $scope.userForm.valuationDatePickerFrom.$pristine;
Also, the controller is getting called before the view is created, so no myForm exists at the time the controller runs. Try adding a $timeout like so:
$timeout(function() {
var isPristine = $scope.userForm.valuationDatePickerFrom.$pristine;
console.log(isPristine);
}, 100);
plunkr
The above solution only works on page load, but you need to know this value when the page is being used. Instead pass the value to the controller when an action happens:
<form name="myForm">
<input type="text" name="valuationDatePickerFrom" ng-model="valuationDatePicker" ng-blur="alerty(myForm.$pristine)">
</form>
.controller('MainController', function($scope) {
$scope.alerty = function(isPristine){
alert('isPristine: ' + isPristine);
};
https://plnkr.co/edit/f0EWvYmoXCn8UOH3QCfE?p=preview

Placement not working in Angular UI datepicker

In this plunk I have an Angular UI datepicker that shows up below the input field. I want the calendar to be displayed on top of the field, so I tried with popup-placement="top-left" but it doesn't work. Any ideas?
HTML
<p class="input-group">
<input type="text" class="form-control" ng-model="dt" is-open="opened"
datepicker-popup="dd-MMM-yyyy" popup-placement="top-left"
datepicker-options="dateOptions" ng-required="true" close-text="Close" />
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="open1($event)">
<i class="glyphicon glyphicon-calendar"></i>
</button>
</span>
</p>
Javascript
var app = angular.module('app', ['ui.bootstrap']);
app.controller('ctl', function ($scope) {
$scope.opened = false;
$scope.dateOptions = {
showWeeks: false
};
$scope.open1 = function(event){
event.preventDefault();
event.stopPropagation();
$scope.opened = true;
};
});
popup-placement directive does not exist on ui-bootstrap version 0.13.
it seems like it's only been added since version 1.2.0.
Best thing would be to update your version, previous versions don't seem to support that option (you can always manipulate the css but that's quite dangerous).
Working plunker with updated ui-bootstrap and angular versions.
i have solved your problem and created a plunker: http://plnkr.co/edit/PsCjLBzWk5QRHO2EIPIe?p=preview.
your ui-bootstrap version should be updated.
you need to updated your angularjs version 1.5.0, ui-bootstrap version 1.2.4, bootstrap 3.3.6, and then add uib-datepicker-popup="{{format}}" to your datepicker input element.

bind not working for required input field

I've this AngularJS HTML using Bootstrap:
<div class="col-sm-6" ng-app ng-controller="MyController">
<br/><br/>
<form name="myForm">
<div class="input-group">
<input type="text" name="input" class="form-control" ng-model="input" maxlength="{{inputMaxLength}}" ng-minlength="{{inputMaxLength}}" ng-maxlength="{{inputMaxLength}}" placeholder="Type input.." aria-describedby="basic-addon2" required />
<span class="input-group-addon" id="basic-addon2" ng-bind="{{inputMaxLength-input.length}}"></span>
</div>
<div class="btn-group">
<button type="button" class="btn btn-default btn-primary" ng-disabled="myForm.$invalid">Submit</button>
</div>
</form>
</div>
and this controller:
function MyController($scope) {
$scope.input = "";
$scope.inputMaxLength = 18;
}
The Bootstrap addon in the field, should always count the remaining characters. The Submit button should be disabled as long the form is not valid.
The button works as aspected, but the "count down" in the add on is always 18.
Why?
See this JSFiddle.
You have a typo in ng-min-length, you should have:
ng-minlength="{{inputMinLength}}"
instead of
ng-minlength="{{inputMaxLength}}"
Oh and you should lose the curly braces on ng-bind, you can use one or the other but not both
So either:
<span class="input-group-addon" id="basic-addon2" ng-bind="inputMaxLength-input.length"></span>
or
<span class="input-group-addon" id="basic-addon2">{{inputMaxLength-input.length}}</span>
(same applies for ng-minlength="{{inputMaxLength}}" ng-maxlength="{{inputMaxLength}}", no need for interpolation here, use ng-minlength="inputMaxLength" ng-maxlength="inputMaxLength" instead)
Note that while the input does not fulfill the requirements ie. larger than minLength and shorter than maxLength input will not have a value.
In this case you can get the value using myForm.input.$viewValue
I have updated you fiddle http://jsfiddle.net/29m5tdsc/9/
This can't work : your ng-validation (ng-minlength) will set $scope.input to null. So your counter wont work.
Besides, you wrote :
ng-bind="{{inputMaxLength - input.length}}"
When angular will work he will replace variables with values. You should wrote :
ng-bind="(inputMaxLength - input.length)"
JS Fiddle

Angular UI datepicker not updating

I have tried to extend the UI datepicker with previous and next day buttons.
As you can see from the plunker I can change the model either by using the datepicker or the prev/next buttons. But when the model is changed with the prev/next buttons, the datepicker ist not updated.
http://plnkr.co/edit/k1flklFny5BoX6zdwyWJ?p=preview
<div class="form-group">
<div class="input-group">
<input type="text" class="form-control"
datepicker-popup="{{ctrl.format}}" ng-model="ctrl.dt"
is-open="ctrl.opened" datepicker-options="ctrl.dateOptions"
ng-required="true" close-text="Close" />
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="ctrl.open($event)">
<i class="glyphicon glyphicon-calendar"></i>
</button>
</span>
</div>
</div>
I tried several approaches already (including $scope and the demonstrated controller as syntax) but it simply does not work. Any ideas?
PS: I tried very hard to have prev button, datepicker, next button in one line, centered, the datepicker occupying just enough space it needs. If anyone has an idea how to accomplish that, any help is greatly appreciated.
I don't know why, but seems that ngModel doesn't react when Date object changed itself. But it changed if you assign to scope property new instance of Date.
Try this:
this.prevDay = function() {
this.dt = getPrevNextDate(this.dt, -1);
};
this.nextDay = function() {
this.dt = getPrevNextDate(this.dt, 1);
};
function getPrevNextDate(date, increment)
{
var newDate = new Date();
newDate.setDate(date.getDate() + increment);
return newDate;
}
And better to cache this into some variable like var self = this at top of controller function and use self variable instead of this
This way you will avoid error in this line:
$log.log('GET api/v1/person/' + this.person.id + '/entry returned: ' + data.length + ' entries')

AngularJS not validating email field in form

I have the html below where I have a form that I want to submit to the AngularJS Controller.
<div class="newsletter color-1" id="subscribe" data-ng-controller="RegisterController">
<form name="registerForm">
<div class="col-md-6">
<input type="email" placeholder="your#e-mail.com" data-ng-model="userEmail" required class="subscribe">
</div>
<div class="col-md-2">
<button data-ng-click="register()" class="btn btn-primary pull-right btn-block">Subsbcribe</button>
</div>
</form>
</div>
And the controller is below
app.controller('RegisterController', function ($scope,dataFactory) {
$scope.users = dataFactory.getUsers();
$scope.register = function () {
var userEmail = $scope.userEmail;
dataFactory.insertUser(userEmail);
$scope.userEmail = null;
$scope.ThankYou = "Thank You!";
}
});
The problem is that no validation is taking place when I click the button. It is always routed to the controller although I do not supply a correct email. So every time I click the button I get the {{ThankYou}} variable displayed. Maybe I do not understand something.
AngularJS does not disable enable any functionality for form validations. What is does is, it makes the state of the form and its control in terms of validation available on the current scope. You are required to implement the behaviour yourself.
In your case if you need to check user email is valid your html input should have a name attribute like
<input type="email" placeholder="your#e-mail.com" data-ng-model="userEmail" required class="subscribe" name='userEmail'>
Then on your controller you can check
$scope.registerForm.userEmail.$invalid property.
You can use the same property to disable the button on the form using ng-disabled
<button data-ng-click="register()" class="btn btn-primary pull-right btn-block" ng-disabled='registerForm.userEmail.$invalid'>Subsbcribe</button>
Basically the registerForm object is a ngFormController and userEmail is ngModelController. Please read the developer guide for forms
You are missing some part to achieve what you want. Normally you will need to add some code to enable disable the submit button base on the state of the form i.e valid/invalid. In your case this can be done like that :
<button data-ng-click="register()" class="btn btn-primary pull-right btn-block" ng-disabled="registerForm.$invalid">Subsbcribe</button>
Notice the ng-disabled="registerForm.$invalid".
You can as well provided inline feedback to the user with something like :
<input type="email" placeholder="your#e-mail.com" data-ng-model="userEmail" required="" class="subscribe" name="userName"/>
<span ng-show="registerForm.userName.$error.required">Please enter a name</span>
Or with CSS like that :
input.ng-invalid-required {
background-color: #FA787E;
}
You have a working plunker here

Resources