Search code examples
angularjsangular-ui-bootstrapbootstrap-datetimepickerangular-ui-datepicker

Angular UI Bootstrap Datetimepicker with seconds


I want to get bootstrap datetimepicker input value in angularjs controller. I am using following custom directive to achieve this . But i am getting the value is undefined. I have added the code related to html and angular code related to the issue.

HTML

    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/4.17.43/css/bootstrap-datetimepicker.min.css">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.15.2/moment.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.15.2/locale/en-gb.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/4.17.43/js/bootstrap-datetimepicker.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.4/angular-resource.js"></script>

    <div class="form-group">
          <div class='input-group date'  id='datetimepickerFrom' datetimepicker  
ng-model="fromDate" >

           <input type='text'  class="form-control" />

           <span class="input-group-addon"> 
           <span class="glyphicon glyphicon-calendar"></span>
           </span>
          </div>
         </div>

JS

'use strict';
var App = angular.module('app',['ngResource']);

App.directive('datetimepicker', function(){
    return {
        require: '?ngModel',
        restrict: 'A',

        link: function(scope, element, attrs, ngModel){

            if(!ngModel) return; // do nothing if no ng-model

            ngModel.$render = function(){
                element.find('#datetimepickerFrom').val( ngModel.$viewValue || '' );
            };

            element.datetimepicker({ 
                format : 'YYYY-MM-DD HH:mm:ss'

            });

            element.on('dp.change', function(){
                scope.$apply(read);
            });

            read();

            function read() {
                var value = element.find('#datetimepickerFrom').val();
                ngModel.$setViewValue(value);
                console.log(ngModel.$setViewValue(value));
            }
        }
    };
});

App.controller('myController', ['$scope', function($scope) {
    $scope.fromDate = moment();
}]);

Solution

  • I have found a package for you to fix your problem which is in the link. LINK

    Easy way to achieve it follow these below steps

    1. Add this markup.

    2. You need to include the following scripts

      • //ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js

      • //angular-ui.github.io/bootstrap/ui-bootstrap-tpls-2.0.1.js

      • //maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css

      • //cdn.rawgit.com/zhaber/datetimepicker/master/datetimepicker.js

      • //cdn.rawgit.com/zhaber/datetimepicker/master/datetimepicker.css

    3. Controller will hold the model value in $scope.date which contains the date and time.

    Update 1

    This control does not support Seconds, I would suggest you to go with Angular UI Bootstrap as below Include the above references expect last two and use the below markup.

    <p class="input-group">
        <input type="text" class="form-control" uib-datepicker-popup is-open="popup1.opened"  ng-model="fromDate" datepicker-options="dateOptions" ng-required="true"  close-text="Close" />
        <span class="input-group-btn">
            <button type="button" class="btn btn-default" ng-click="open1()"><i class="glyphicon glyphicon-calendar"></i></button>
        </span>
    </p>
    <div uib-timepicker ng-model="fromTime" ng-change="changed()" hour-step="1" minute-step="1"  show-meridian="ismeridian" show-seconds="true"></div>
    

    Add this module as a dependency ui.bootstrap

    Use the below code to combine your value

    $scope.changed = function () {
    var month = $scope.fromDate.getMonth()+1;
    var day = $scope.fromDate.getDate();
    var year = $scope.fromDate.getFullYear();
    
    var hour = $scope.fromTime.getHours();
    if (hour < 10)
     hour = "0"+hour;
    
    var min = $scope.fromTime.getMinutes();
    if (min < 10)
     min = "0"+min;
    
    var sec = $scope.fromTime.getSeconds();
    if (sec < 10)
     sec = "0"+sec;
    
     //put it all togeter
    var dateTimeString = month+'/'+day+'/'+year+' '+hour+':'+min+':'+sec;
    
    $scope.fromDateTime= dateTimeString;
    };
    

    Your live ng-model value combined together

    fromDateTime:{{fromDateTime |date : 'yyyy-MM-dd HH:mm:ss'}}
    

    So by this if the seconds value is changed only you will get the actual Date Time