Marcus
Marcus

Reputation: 81

Angularjs bootstrap datetimepiker not bind model

I have a little problem in using an AngularJS directive with a object property inside an MVC project. The overall structure is a .cshtml page that contains a reference to the scripts file that contains definitions for the app, controller and directives. Everything works fine and the access to all objects and variables is perfectly fine with no errors show on the console.

This is my setup, first of all the directive:

var app = angular.module("dataContainer", ['ngMaterial']);
app.directive('dateTime', function () {
    return {
        template: '<input type="text" id="datetimepicker" class="form-control">',
        restrict: 'E',
        require: 'ngModel',
        scope: {},
        link: function (scope, element, attr) {
            $('#datetimepicker').datetimepicker({
                format: 'DD/MM/YYYY'
            });
        }
    };
});

First of all I've tried to bind this value inside a $scope variable, without success, here is the portion of the controller:

app.controller("InvoiceDetailController", function ($scope, $http) {
    $scope.dateValue = "";
    ...

After that I've inserted the html tag like this:

<date-time ng-model="dateValue"></date-time>

But when I trigger an action on a ng-click to save information the $scope.dateValue is always an empty string, like it is not able to correctly bind to the div. I also have tried removing scope property from the directive, change it to true and false, but nothing works. It is an accessibility problem (maybe related to the datepicker)? Is there a better way to bind variables to directives in AngularJS? Thank you all for the help!

Upvotes: 1

Views: 31

Answers (1)

Mosh Feu
Mosh Feu

Reputation: 29277

You already require ngModel, you need to use it. See this answer.

Also, you can't set the input id because there might be many in the same page. Instead, find the input inside the directive element and call the plugin on it.

var app = angular.module("app", []);
app.controller('controller', function($scope) {
  $scope.dateValue = new Date();
  $scope.foo = 'bar';
});
app.directive('dateTime', function () {
  return {
    template: '<input type="text" class="form-control">',
    restrict: 'E',
    require: 'ngModel',
    scope: {},
    link: function (scope, element, attr, ngModel) {
      const input = element.find('input');
      input.datetimepicker({
        onChangeDateTime: function(date) {
          scope.$apply(function() {
            ngModel.$setViewValue(date);
          });
        }
      });
      
      ngModel.$render = function() {
        input.val(ngModel.$modelValue);
      }
    }
  };
});
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jquery-datetimepicker/2.5.20/jquery.datetimepicker.min.css" />
<script src="https://code.jquery.com/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.8.2/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-datetimepicker/2.5.20/jquery.datetimepicker.full.min.js"></script>

<div ng-app="app" ng-controller="controller">
  <date-time ng-model="dateValue"></date-time>
  {{dateValue}}
</div>

Upvotes: 1

Related Questions