Get the Date from Datepicker programmatically as Text - angularjs

I'm trying to get a date, which is displayed in an input of the bootstrap ui datepicker as pure text. Therefore I use a span.
Now I want to get the text of the span, but it doesn't work. Actually, I get an undefined. Do you have some tips for me?
HTML
<input type="text" class="form-control" datepicker-popup="{{format}}" ng-model="dt" is-open="opened" min-date="minDate" max-date="'2020-06-22'" datepicker-options="dateOptions" date-disabled="disabled(date, mode)" ng-required="true" close-text="Close" />
<span ng-model="textDate">{{dt | date:'dd.MM.yyyy' }}</span>
JS
$scope.$watch('dt', function() {
var tD = $scope.textDate.value;
console.log(tD);
});

Inject $filter into your controller/service and extract the date as a string like so
$scope.getDate = function() {
return $filter('date')($scope.dt, 'dd.MM.yyyy');
}
Plunkr here
Side-note: Assuming that dt already has two-way binding, I don't think it's necessary to $watch for changes. Instead, you can directly use $filter('date')($scope.dt, 'dd.MM.yyyy') where you need the string value.

Angular's ngModel won't work on a span since it is read only. You need some kind of input for two-way-binding with a ng-model. For this you could use a binding to a getter/setter of the model used on the input field. Here is an example:
<input type="text" name="userName"
ng-model="vm.dt"
ng-model-options="{ getterSetter: true }" />
<span ng-bind="vm.dt()"></span>
By adding ng-model-options="{ getterSetter: true }" will expose the model to a getter/setter which is a function you can simply call on your span. Also I would recommend to use the controllerAs syntax to avoid problems with scopes. Notice the vm is the alias for the controller around the input and span.
For more information check the documentation on ngModel.

Related

Why is angular making my inputfield empty?

The value of my inputfield is set but why is my inputfield still empty ? I am using a combination of laravel en angular :
inputfield html :
<input
type="text"
name="name"
value="{{ old('name') }}"
ng-model="name"
ng-model-options='{ debounce: 300 }'
class="form-control"
ng-class="{ enabled : nameIsValid }"
ng-change="checkName(name)"
placeholder="Your nickname"
required>
It is hard to tell the reason if you don't put your controller code in here. But here are some assuptions from my part:
you don't need to set the value if you bind an input-field with ng-model.
rather then ng-change I would use a $scope.$watch() function
are you using more than one scope in this template? maybe changes made by the child-scope aren't altering the original variable of the $parent-scope

ui bootstrap datepicker alternate date format

How can I allow user to type date in input form in different formats? I see option alt-input-formats. I've tried to pass alternate formats with no result.
Controller:
vm.altInputFormats = ['M!/d!/yyyy'];
Markup:
<div class="calendar">
<label>END DATE</label>
<input type="text"
ng-click="vm.toggleCalendar('endDate')"
class="calendar-control"
uib-datepicker-popup="{{'MM/dd/yy'}}"
ng-model="vm.dateFilter.endDate"
is-open="vm.endDateOpened"
datepicker-options="vm.datePickerOptions"
min-date="vm.dateFilter.startDate"
max-date="vm.currentDate"
show-button-bar="false"
alt-input-formats="vm.altInputFormats"
close-text="Close" />
<i ng-click="vm.toggleCalendar('endDate')" class="glyphicon glyphicon-calendar calendar-btn"></i>
</div>
Now i'm able only to type date in such format: 01/01/16, but for 01/01/2016 I got undefined in model.
What's wrong with my code?
The altInputFormats should be provided not as attribute but as the part of the datepicker-options config object. In your case:
<input type="text"
ng-click="vm.toggleCalendar('endDate')"
class="calendar-control"
uib-datepicker-popup="{{'MM/dd/yy'}}"
ng-model="vm.dateFilter.endDate"
is-open="vm.endDateOpened"
datepicker-options="vm.datePickerOptions"
min-date="vm.dateFilter.startDate"
max-date="vm.currentDate"
show-button-bar="false"
close-text="Close" />
and then in controller
vm.datePickerOptions = {
altInputFormats: ['M!/d!/yyyy'],
// rest of options ...
}
alt-input-formats is defined as an attribute in directive uibDatepickerPopup so it can not take vm.altInputFormats as an array. One way to get around this is to insert the array directly into alt-input-formats
<input type="text"
ng-click="vm.toggleCalendar('endDate')"
class="calendar-control"
uib-datepicker-popup="{{'MM/dd/yy'}}"
ng-model="vm.dateFilter.endDate"
is-open="vm.endDateOpened"
datepicker-options="vm.datePickerOptions"
min-date="vm.dateFilter.startDate"
max-date="vm.currentDate"
show-button-bar="false"
alt-input-formats="['M!/d!/yyyy', 'yyyy-M!-d!']"
close-text="Close" />
try to change this line.
alt-input-formats="vm.altInputFormats[0]"

Angular UI Bootstrap DatePicker - get selected date on close / blur

I have an ng-repeat with each row having multiple UI-Bootstrap Datepickers. I am trying to call a function in my controller when the date is selected and the picker closes. I have tried using UI-Event to capture the blur event but the model hasn't been updated when this gets called. My question is how can I get the selected date when the picker closes? Can I do something like ui-event="{ blur : 'myBlurFunction( $event, this.text)' }, or is there another way to get the data with an onClose event?
<li ng-repeat="....">
<div ng-click="openEditStartCal($event, ticket)">
<input ui-event="{ blur : 'blurredStartDate( $event, ticket, this.text)' }"
type="text"
starting-day="2"
show-button-bar="false"
show-weeks="false"
class="form-control addTicketDateInput"
datepicker-popup="dd MMM"
ng-model="ticket.StartDate"
is-open="startEditTicketOpened && currentTicketUpdating == ticket.TicketId"
min-date="{{today()}}"
max-date="'2015-06-22'"
datepicker-options="dateOptions"
date-disabled="disabled(date, mode)"
ng-required="true" close-text="Close" />
</div>
I have solved this by using: ng-change="myChangeFunction()".
This is possible using ng-change :
html/jsp file
<input type="text"
id="StartDate"
name="StartDate"
class="form-control input-sm"
uib-datepicker-popup="{{format}}"
ng-model="StartDateVal"
is-open="status.opened"
min-date="min"
max-date="max"
datepicker-options="dateOptions"
date-disabled="disabled(date, mode)"
ng-required="true"
close-text="Close"
readonly="true"
ng-change="select(StartDateVal)" />
.js Controller
$scope.select = function(date) {
// here you will get updated date
};
You can put a $watch in your controller for your date variable.
$scope.$watch('ticket.StartDate',function(){
var date = $scope.ticket.StartDate;
});
I was dealing with this as well and onChange won't do the job for me, so I went to ui bootstrap .js and added some things. Then I can set a function to be called in HTML via on-close attribute.
<input type="text" on-close="dateClosed()" ng-model="date" datepicker-popup="dd.MM.yyyy" is-open="dateOpened" ng-click="dateOpened=true" />
then you need to change the ui-bootstrap.js at
.directive('datepickerPopup' ... function(...) ... return { ...
scope: { ... , onClose: '&' }
there are 3 options how to close the picker - date selection, click elsewhere or done button. you can find it easily, its the only place where isOpen is set to false
scope.isOpen = false;
Then i just call a function at those 3 places, where i call the function from the attribute
scope.onClosing = function () {
if (angular.isDefined(attrs.onClose))
scope.onClose();
}
If you want the ui-bootstrap.js PM me, I did it in the tpls version only tho.

Angularjs ng-model-options is not working.

I have a pattern on my controller
$scope.pattern = {
name: /[a-zA-Z]{5,}/
}
On the view
<input type="text" name="name" data-ng-model="name" ng-model-options="{ updateOn: 'blur' }" ng-pattern="pattern.name" required />
<div ng-show="contactForm.name.$dirty && contactForm.name.$invalid">
<span ng-show="contactForm.name.$error.required">The name field is mandatory</span>
<span ng-show="contactForm.name.$error.pattern">The name must be at least 5 characters long</span>
</div>
I want the field to be validate only when it looses the focus but it doesn't it validates every time I press a button.
ngModelOptions was introduced only in Angular 1.3.x
https://docs.angularjs.org/api/ng/directive/ngModelOptions
If you want to use similar functionality in Angular 1.2.x, check out this poly fill:
https://github.com/fergaldoyle/modelOptions

Angular UI Bootstrap datepicker: ng-readonly support

Angular UI Bootstrap datepicker does not honors ng-readonly attribute.
If ng-readonly expression is true, text input field is greyed and can not be modified, but datepicker's calendar pops up, allowing modification of form field.
So far i tryed 3 approaches (see http://plnkr.co/edit/KHrbbI6W1pWG5ewSsE9r?p=preview), both of which are rather hackish and ugly:
Disabling of all dates in datepicker if it should be readonly.
<input type="text" datepicker-popup="dd.MM.yyyy" ng-model="dt" ng-readonly="ro" date-disabled="disabled(date, mode)" />
in html file and
$scope.$watch('ro', function(ro) {
$scope.dt = new Date($scope.dt); // force datepicker div refresh
});
$scope.disabled = function(date, mode) {
return $scope.ro;
};
in controller.
Not allowing datepicker popup div to pop up.
<input type="text" datepicker-popup="dd.MM.yyyy" ng-model="dt" ng-readonly="ro" is-open="opened" />
in html file and
$scope.$watch('opened', function(v1, v2, v3) {
if ($scope.ro && v1) {
$timeout(function() {
$scope.opened = false;
});
}
});
in controller. Blinking datepicker looks terrible.
Replacing datepicker's text input with another readonly input field without datepicker attached.
<datepicker-ro-fix datepicker-popup="dd.MM.yyyy" ng-model="dt" ng-readonly="ro" />
in html file and
m.directive('datepickerRoFix', function() {
return {
restrict: 'E',
require: 'ngModel',
scope: {
ngModel: '=',
ngReadonly: '=',
},
template: '<span>'
+ '<input ng-hide="ngReadonly" type="text" datepicker-popup="dd.MM.yyyy" ng-model="ngModel" />'
+ '<input ng-show="ngReadonly" type="text" readonly="true" value="{{ ngModel | date:\'dd.MM.yyyy\'}}" />'
+ '</span>',
};
});
in js file. This seems to be the best solution so far, but the downside is that now there are two input elements instead of one, both have some hardcoded properties.
First and second approaches require me to add a bunch of code into form controller per each date input field, Third is much harder to customise.
I am new to angular and should be missing something.
Is there some better way to make input fields with datepicker really read-only?
ng-disabled="true"
worked for me.
Angularjs: 1.2.9 and
ui-boostrap: 0.8.0
Unfortunately I do not have reputation enough to comment on the original answer
Your third approach is quite nice, imho.
Given that the datepicker itself obviously does not support readonly property, I don't see another way how to make it read-only (and you even created a directive for it)
Your second approach sometimes results in minor flickering when clicking on the input (is it just me?)
As to customization, could you elaborate why it is difficult to do do? You'd have to pipe all the possible attributes of the original directive through to your directive, I guess?
Use ng-disabled="true"
<input type="text" class="form-control" datepicker-popup="{{format}}" ng-model="date" min="minDate" max="maxDate" ng-disabled="true" readonly="true"/>

Resources