The user aims to incorporate datetimepicker.js, a jQuery plugin, into an AngularJS application by developing a custom directive. The primary obstacle is that the datetimepicker does not seamlessly bind to AngularJS’s ng-model, which disrupts the two-way data binding mechanism. As a result, there are inconsistencies between the Angular model and the date chosen through the datetimepicker.
Here in example we have Eonasdan/bootstrap-datetimepicker
The Eonasdan/bootstrap-datetimepicker library is a jQuery-based datetime picker and does not natively support Angular. To integrate it with Angular, you would need to use a wrapper or directive that bridges the gap between jQuery and Angular.
So here we have given solution for all angular versions
app.directive('datetimepicker', function() {
return {
restrict: 'A',
require: 'ngModel',
link: function(scope, element, attrs, ngModelCtrl) {
console.log('call datetimepicker link...');
var picker = element.datetimepicker({
dateFormat: 'dd/MM/yyyy hh:mm:ss',
useCurrent: false // Prevent default date setting on initialization
});
// Model -> View (render)
ngModelCtrl.$render = function() {
console.log('ngModelCtrl.$viewValue@' + ngModelCtrl.$viewValue);
picker.setDate(ngModelCtrl.$viewValue || '');
};
// View -> Model (change event)
picker.on('dp.change', function(e) {
console.log('dp.change ' + e.date);
scope.$apply(function(){
// Store Date object in the model
ngModelCtrl.$setViewValue(e.date ? e.date.toISOString() : null); // Using ISO string format
});
});
// Optional: Clear date when modal is opened again
scope.$on('modalOpened', function() {
ngModelCtrl.$setViewValue(null); // Reset the date on modal open
picker.clear();
});
// Optional: Listen for modal closing event and clear date if needed
scope.$on('modalClosed', function() {
picker.clear();
});
}
};
});
Controller app.controller('MainCtrl', [ '$scope', function ($scope) { $scope.dueDate = new Date(); }, ]);Datetime Picker Example
For Angular 2+ versions , need to install packages using below command
npm install jquery moment eonasdan-bootstrap-datetimepicker
Need to add styles and scripts in angular.json file
"styles": [ "node_modules/bootstrap/dist/css/bootstrap.min.css", "node_modules/eonasdan-bootstrap-datetimepicker/build/css/bootstrap-datetimepicker.min.css" ], "scripts": [ "node_modules/jquery/dist/jquery.min.js", "node_modules/moment/min/moment.min.js", "node_modules/eonasdan-bootstrap-datetimepicker/build/js/bootstrap-datetimepicker.min.js" ]
datetime-picker.directive.ts
import $ from 'jquery';
import { Directive, ElementRef, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core';
import 'eonasdan-bootstrap-datetimepicker';
@Directive({
selector: '[appDatetimepicker]',
standalone: true
})
export class DatetimepickerDirective implements OnInit, OnDestroy {
@Input() options: any;
@Output() dateChange = new EventEmitter();
private picker: any;
constructor(private el: ElementRef) {}
ngOnInit(): void {
// Use type assertion to avoid TypeScript error
this.picker = ($(this.el.nativeElement)).datetimepicker(this.options);
this.picker.on('dp.change', (e: any) => {
this.dateChange.emit(e.date ? e.date.format('YYYY-MM-DD HH:mm') : '');
});
}
ngOnDestroy(): void {
if (this.picker) {
(this.picker.data('DateTimePicker')).destroy();
}
}
}
App.component.html
app.component.ts
import { Component } from '@angular/core';
import { DatetimepickerDirective } from './datetime-picker/datetime-picker.directive';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
standalone : true,
imports: [DatetimepickerDirective],
})
export class AppComponent {
datetimeOptions = {
format: 'YYYY-MM-DD HH:mm',
sideBySide: true,
showTodayButton: true
};
onDateChange(date: string): void {
console.log('Selected date:', date);
}
}
No Standalone Components: Angular 2 to 17 doesn’t support the standalone: true flag in components or directives, so the directive needs to be declared in the module.
Module-based Declaration: The directive will be declared within an Angular module (@NgModule) instead of being standalone.
datetime-picker.directive.ts
import * as $ from 'jquery';
import { Directive, ElementRef, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core';
import 'eonasdan-bootstrap-datetimepicker';
@Directive({
selector: '[appDatetimepicker]'
})
export class DatetimepickerDirective implements OnInit, OnDestroy {
@Input() options: any;
@Output() dateChange = new EventEmitter();
private picker: any;
constructor(private el: ElementRef) {}
ngOnInit(): void {
this.picker = $(this.el.nativeElement).datetimepicker(this.options);
this.picker.on('dp.change', (e: any) => {
this.dateChange.emit(e.date ? e.date.format('YYYY-MM-DD HH:mm') : '');
});
}
ngOnDestroy(): void {
if (this.picker) {
this.picker.data('DateTimePicker').destroy();
}
}
}
Now need to import DatetimepickerDirective in the app module’s import array. Other than this everything is the same as angular 18.
In summary, while Eonasdan/bootstrap-datetimepicker itself is not natively compatible with Angular, there are Angular-specific wrappers and alternative libraries available that can provide similar functionality.
Work with our skilled Angular developers to accelerate your project and boost its performance.
Hire Angular Developers