could you please tell me how to open bootstrap datepicker in angular js .I have two field name and data.I want to open datepicker on click of date field .here is my code
http://plnkr.co/edit/elrOTfEOMmUkPYGmKTdW?p=preview
var app = angular.module('plunker', ['angularMoment']);
app.controller('MainCtrl', function($scope, moment) {
$scope.name = 'World';
console.log(moment)
var d = new Date(613938600000);
$scope.c = {
name: {
name: 'abc'
},
date: {
name: moment(d).format('DD-MMM-YYYY')
}
};
$scope.onclick = function() {
if (!moment($scope.c.date.name).isValid()) {
alert('Everything is wrong dude');
} else {
alert('Everything goood');
}
}
});
any update
Please replace the input field with this.
<input type="text" class="form-control" uib-datepicker-popup="{{format}}" ng-model="x.name" is-open="open" data-ng-click="open = true" datepicker-options="dateOptions" ng-required="true" close-text="Close" alt-input-formats="altInputFormats" />
I have added these directives at the input
<... is-open="open" data-ng-click="open = true" ...>
Add these to directives to your datepicker inputs.
This is should work. Try in your plunker
Not sure if you want to go this route, but my suggestion would be to leverage UI Bootstrap. Opening a datepicker is made fairly easy with this library, along with other bootstrap functionality without having to port bootstrap entirely.
Related
I have an app written in Angular 1.5.3.
Here is what I want to do:
I have a user form with 2 date input types. I need to add some custom validation to my form. I want to show an error message to the user when the "expiry date" on the form is greater than the "effective date" on the form.
I believe that I can do this with a custom directive and with ng-messages.
Here is my code snippet:
<form name="form.mainForm">
<div>
<span>Effective Date: </span>
<input required type="date" name="effectiveDate" ng-model="effectiveDate" />
<div>
<span>Expiry Date: </span>
<input
type="date"
name="expiryDate"
ng-model="expiryDate"
date-greater-than="{{ effectiveDate }}" />
</div>
</div>
</form>
app.directive('dateGreaterThan', function () {
return {
restrict: 'A',
require: 'ngModel',
scope: false,
link: function (scope, elm, attrs, ctrl) {
console.log(' here we are ');
function isValidDateRange(expiryDate, effectiveDate) {
console.log(expiryDate, effectiveDate);
if (effectiveDate == null || expiryDate == null ) {
return true;
}
return effectiveDate > expiryDate;
}
function validateDateRange(inputValue) {
var expiryDate = inputValue;
var effectiveDate = scope.effectiveDate;
var isValid = isValidDateRange(expiryDate, effectiveDate);
console.log("isValid: ", isValid);
ctrl.$setValidity('dateGreaterThan', isValid);
return inputValue;
}
ctrl.$parsers.unshift(validateDateRange);
ctrl.$formatters.push(validateDateRange);
attrs.$observe('dateGreaterThan', function () {
validateDateRange(ctrl.$viewValue);
});
}
};
I have attempted to solve the problem here but I can't get my directive to work properly. It doesn't seem to calculate the dates when they change and it doesn't integrate with ng-messages.
Here's my attempt:
http://jsfiddle.net/aubz88/q7n3abre/
The ngMessages module should be loaded from a cdn. Or installed with a package manager.
The ngMessages module is not included in AngularJS. https://code.angularjs.org/1.4.14/docs/api/ngMessages
var app = angular.module("hello", ['ngMessages']);
Some other points. Use the $validators from the ngModel.
ctrl.$validators.dateGreaterThan = validateDateRange;
Pass the other date with a scope property
scope: {dateGreaterThan: '='},
There is still a lot to improve I think. I did forgot some AngularJS stuff too.
f.e.: you could trigger the validation again when the first date changes. Check the $validate function of https://code.angularjs.org/1.4.14/docs/api/ng/type/ngModel.NgModelController .
You can check this fiddle for a basic setup: http://jsfiddle.net/hcjLkuzt/
I am using knockout js with bootstrap DateTimePicker from here http://eonasdan.github.io/bootstrap-datetimepicker/Installing/#knockout, everything works fine, but the problem is at submission stage that is when I submit the form I can't get the updated value of datetimepicker input field:
Here is my working HTML:
<div data-bind="foreach: params">
<input class="form-control" type="text" data-bind="attr: { name: label}, value: value, dateTimePicker: 'date_field'" />
<button data-bind="event: { click: addParameters } , attr: { class: btn btn-success', href: 'javascript:void(0)'}">Save Settings</button>
</div>
Here is my ViewModel:
function viewModel(data)
{
// date field observable
self.date_field = ko.observable(new Date('2012/12/12'));
// Observable to track the html form
self.params = ko.observableArray();
// when user click by Save Settings button
self.addParameters = function(options)
{
var dataparams = self.params();
console.log(dataparams);
}
}
ko.applyBindings(new viewModel);
Could anyone please guide me what I am doing wrong? Thank you an advance.
I use this datepicker as well. The module doesn't send the update event to knockout observables. I do this for each datepicker after initializing it:
picker.on('dp.change', function (e) {
date_field(e.date);
});
I had the same problem in knockout.js v 3.3.1
update: function(element, valueAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor());
$(element).data('DateTimePicker').setDate(makeStringStandard(value));
$(element).on('dp.change', function (e) {
debugger;
valueAccessor(e.date);
});
}
In my current project I'm using this calendar.js javascript library together AngularJS.
I'm bind calendar.js widget and AngularJS ng-model to my input field in this way:
<input class="vDateField" type="text" ng-model="date" ng-init="date='{{ form.date.value | default_if_none:"" }}'"
vDateField is the class that bing calendars and {{ }} are backend template engine tags.
My problem is when I select the date with calendarjs picker, my input fied is updated but ng-model "date" doesn't.
Is there any solutions without modify calendarjs widget??
Here the rendered input tag:
<div>
<label class="required" for="id_date">Data contratto</label>
<input class="vDateField ng-pristine ng-valid ng-touched" type="text" ng-model="date" ng-init="date=''" name="date" placeholder="02/02/2015">
<span class="datetimeshortcuts"> Oggi | <img src="/static/admin/img/icon_calendar.gif" alt="Calendario"></span>
</div>
Here the javascript sources of the picker. DateTimeShortCuts.js contains the code for display mini link to setup current date time to my input field and a mini calendar icon to open up calendar widget.
I register the widget by adding class="vDateField" to my input tag as shown below.
DateTimeShortCuts.js
calendar.js
Had this same problem, solved it like this (example with jquery datepicker)
$('#myDateInput').datepicker({
dateFormat: 'yy-mm-dd',
onSelect: function (dateText) {
updateDate(dateText);
},
onClose: function (dateText) {
updateDate(dateText);
}
});
function updateDate(dateText) {
var date = angular.element('#myDateInput').val();
angular.element('#myDateInput').val(date);
if (dateText) {
$scope.object.date = dateText;
}
$scope.object.dateReadable = date;
$scope.safeApply(function (childScope) { });
}
// safely apply changes to the $scope
$scope.safeApply = function (fn) {
var phase = this.$root.$$phase;
if (phase == '$apply' || phase == '$digest') {
if (fn && (typeof (fn) === 'function')) {
fn();
}
} else {
this.$apply(fn);
}
};
Set date on page load
$("#myDateInput").datepicker("setDate", $scope.dateReadable);
HTML
<div class="form-group">
<label for="date" class="control-label">Date:</label>
<input type="date" name="date" id="myDateInput" class="form-control" />
</div>
The important thing here is that I use SafeApply to apply the changes to the $scope. Hope the example helps even tough it's a working sample for me.
Why do I have to do this? Well angular isn't aware of what happens outside its $scope, in this case jQUery. So we will have to tell it manually.
EDIT:
It might be a bit confusing with date and dateReadable but ignore the details and look at the safeApply that binds the changes to the $scope.
It will be helpful if you ask your question in more detail. However have you tried ng-init="date='{{ form.date.value | default_if_none:"" }}'" before input element?
I've solved with this directive and by set $('widget_element').trigger('change') on a callback function of 3d-part widget.
In this case, the widget is default Django Admin date widget.
contract_form_app.directive('vDateField', [function() {
return {
require: "ngModel",
restrict: "A",
link: function(scope, element, attrs, ngModelCtrl) {
element.addClass("vDateField");
var updateModel = function (dateText) {
scope.$apply(function () {
ngModelCtrl.$setViewValue(dateText);
});
};
django.jQuery('input').on('change', function() {
updateModel(element.val());
});
}
};
}]);
Problem Question - I am trying to build a directive for the datepicker. But somehow it is not showing the calender popup box. I have tried and looked into most of the post out there. I know it something simple but can't figure this out. Below is my directive
angular.module('App').directive('myDatePicker',function(){
return{
restrict: 'AE',
template:'<input is-open="opened" type="text" datepicker-popup="d/m/yyyy" ng-model="Date" ng-required="true" />'+
'<button type="button" ng-click="open()"></button>',
controller: function($scope){
$scope.open = function () {
$scope.opened = true;
console.log('I am working');
};
}
};
});
HTML
<div my-date-picker></div>
Please guide me where I am making mistake.
I'm trying to use datepicker component from angular-ui bootstrap lib as descibed here: http://angular-ui.github.io/bootstrap/
And I try to set options for the popup picker and accoriding to the documentation I should pass options for datepicker as JSON using the datepicker-options attribute.
In my view I have:
<div class="row">
<div class="col-md-6">
<p class="input-group">
<input type="text" class="form-control" datepicker-popup="{{format}}" ng-model="dt" is-open="opened" min="minDate" max="'2015-06-22'" datepicker-options="dateOptions" date-disabled="disabled(date, mode)" ng-required="true" close-text="Close" />
<span class="input-group-btn">
<button class="btn btn-default" ng-click="open($event)"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</p>
</div>
</div>
And in my controller I have:
$scope.dateOptions = {'show-button-bar': 'false', 'close-text':'SomeText'};
$scope.today = function() {
$scope.dt = new Date();
};
$scope.today();
$scope.showWeeks = false;
$scope.clear = function () {
$scope.dt = null;
};
$scope.toggleMin = function() {
$scope.minDate = ( $scope.minDate ) ? null : new Date();
};
$scope.toggleMin();
$scope.open = function($event) {
$event.preventDefault();
$event.stopPropagation();
$scope.opened = true;
};
$scope.dateOptions = {
'year-format': "'yy'",
'starting-day': 1
};
$scope.format = 'dd/MM/yyyy'
As you can see at the beginning I try to set the options:
$scope.dateOptions = {'show-button-bar': 'false', 'close-text':'SomeText'};
however, it doesn't seem to work, the datepicker does not change.
Any ideas what I'm doing wrong?
I found the solution to this, I put the options as attributes, e.g.:
<input type="text" class="form-control" datepicker-popup="{{format}}" ng-model="dt" is-open="opened" min="minDate" max="'2014-12-31'" datepickerOptions="dateOptions" ng-required="true" show-button-bar="false"/>
so I put show-button-bar as the attribute and not as a part of object passed to datepickerOptions.
You are using dash-cased option names. These dash-cased names are only required when using them as single attributes on an element. i.e.
<input type="text" datepicker-popup="{{format}}" starting-day="1" ng-model="dt" >
However datepicker-options expects named options in json with camelCased format as following:
datepicker-options="{startingDay: 1, yearFormat: 'yy'}"
<input type="text" datepicker-popup="{{format}}"
datepicker-options="{startingDay: 1, yearFormat: 'yy'}" ng-model="dt" >
or
$scope.options = {
'startingDay': 1,
'yearFormat': 'yy'
}
<input type="text" datepicker-popup="{{format}}"
datepicker-options="{{options}}" ng-
The attribute starting-day="1" should also work on the datepicker input, as told at https://angular-ui.github.io/bootstrap/#/datepicker, but I can't seem to get that working (using version 0.12.1)
I know this an old question but thought I'd point out where you were probably having trouble.
In your controller you are assigning to $scope.dateOptions twice and therefore overwriting your first assignment.
So your initial assignment of:
$scope.dateOptions = {'show-button-bar': 'false', 'close-text':'SomeText'};
Is overwritten when you do this towards the end:
$scope.dateOptions = {
'year-format': "'yy'",
'starting-day': 1
};
According to datePicker documentation, popup setting can be globally configured through the datepickerPopupConfig, so you have to add it into you controller.
yourApp.controller('YourController', function ($scope, datepickerPopupConfig) {
datepickerPopupConfig.showButtonBar = true;
datepickerPopupConfig.closeText = 'I am done';
datepickerPopupConfig.clearText = 'Wipe it out';
}
Setting closeText doesn't work for some reason. I don't know why.
Example on Plunker for playing.
datepicker-options was introduced in version 0.11 so make sure you are using angular-ui-bootstrap version 0.11 or higher
Looks like your dateOptions object keys are not camelCased. Try this:
$scope.dateOptions = {
'showButtonBar': 'false',
'closeText':'SomeText'
};
Html attributes should be dash-cased, like show-button-bar, or close-text, etc.
Notice the difference between the datepicker-options html attribute and the datepickerOptions javascript object.
Just provide close-text, current-text and clear-text attributes in the input :)
<input type="text" uib-datepicker-popup ng-model="dt" is-open="popup2.isopen" datepicker-options="dateOptions" ng-required="true" close-text="your close text here" current-text="Your current text here (today for example)" clear-text="Your clear-text here"/>
The site is pretty lite on examples. For me, with version 1.1.1, I passed in the config object as an attrib:
datepicker-options="datepickerOptions"
And in the controller, was able to set some options:
$scope.datepickerOptions = {
formatYear: 'yy',
startingDay: 0,
showWeeks: false
};
But 'showButtonBar' doesn't cooperate, so looking through the code I saw 'uibDatepickerPopupConfig'. I pass that in and and set it separately and it works:
.controller('DatepickerCtrl', function ($scope, uibDatepickerPopupConfig){
uibDatepickerPopupConfig.showButtonBar = false;
With 'datepickerPopupConfig' I get the provider error:
Unknown provider: datepickerPopupConfigProvider <- datepickerPopupConfig