29

Here is the html for the date field :

<div class='form-group'>
  <label>Check out</label>
    <input type='text' ng-model='checkOut' class='form-control' data-date-format="yyyy-mm-dd" placeholder="Check out" required id="check-out">
</div>
<script>
$('#check-out').datepicker();
</script>

The datepicker shows up in the input field. However if I do this in my controller :

console.log($scope.checkOut);

I get undefined in the javascript console. How to solve this ?
Is there a better way to use bootstrap-datepicker with angularjs ?

I don't want to use angular-ui/angular-strap since my project is bloated with javascript libraries.

5
  • 3
    Try ng-model="$parent.checkOut" Commented Oct 11, 2013 at 11:34
  • You cannot bind to datepicker() outside of a $digest cycle. Commented Oct 11, 2013 at 11:51
  • 1
    Try using Angular-UI-Bootstrap's datepicker directives with Bootstrap, I've used it with Bootstrap 2 & 3 and works perfect - angular-ui.github.io/bootstrap/#/datepicker (I should note you can include just the directive script for the Angular-UI-Bootstrap datepicker if you're worried about library bloat) Commented Oct 11, 2013 at 13:54
  • You can create a custom Angular-UI-Bootstrap minified lib with just the datepicker here: angular-ui.github.io/bootstrap/#/getting_started Commented Oct 11, 2013 at 13:57
  • I'd like to point out that angular-ui bootstrap is currently not a viable option if you are using AngularJS 1.3+ This is a known issue: github.com/angular-ui/bootstrap/issues/2830 Commented Apr 2, 2015 at 0:49

11 Answers 11

23

As @lort suggests, you cannot access the datepicker model from your controller because the datepicker has its own private scope.

If you set: ng-model="parent.checkOut"

and define in the controller: $scope.parent = {checkOut:''};

you can access the datepicker using: $scope.parent.checkOut

Sign up to request clarification or add additional context in comments.

3 Comments

@lort's suggestion of ng-model="$parent.checkOut" worked for me.
Wrecked my head over this one - check out isolateScope for better understanding
i don't understand very well your answer, are we supposed to litterally write the same thing you wrote? or set the ng-model directive in the parent div
21

I am using bootstrap 3 datepicker https://eonasdan.github.io/bootstrap-datetimepicker/ and angularjs, I had the same problem with ng-model, so I am getting input date value using bootstrap jquery function, below is the code in my controller, it's worked for me.

Html

<input class="form-control" name="date" id="datetimepicker" placeholder="select date">

Controller

$(function() {

    //for displaying datepicker

    $('#datetimepicker').datetimepicker({
        viewMode: 'years',
        format: 'DD/MM/YYYY',
    });

    //for getting input value

    $("#datetimepicker").on("dp.change", function() {

        $scope.selecteddate = $("#datetimepicker").val();
        alert("selected date is " + $scope.selecteddate);

    });

 });

3 Comments

just wanted to say this is the only answer that has come close to working for me. +1 and thanks
This worked for me, with the small exception that calling val() didn't work. The event receives an "e" parameter that contains the new date (as a moment instance), so the code for me was $scope.selecteddate = e.date.toDate();
As of Feb 2018, this is still the best workaround there is, I can't express how much this helped me right now.
2

I just found a solution to this myself. I just pass in the model name to the directive (which I found most of online). This will set the value of the model when the date changes.

<input data-ng-model="datepickertext" type="text" date-picker="datepickertext" />{{datepickertext}}    

angular.module('app').directive('datePicker', function() {
    var link = function(scope, element, attrs) {
        var modelName = attrs['datePicker'];
        $(element).datepicker(
            {
                onSelect: function(dateText) {
                    scope[modelName] = dateText;
                    scope.$apply();
                }
            });
    };
    return {
        require: 'ngModel',
        restrict: 'A',
        link: link
    }
});

Comments

2

I am using Angular JS 1.5.0 and Bootstrap 3 Datetimepicker from https://eonasdan.github.io/bootstrap-datetimepicker/

After some time and struggling, I finally found a solution how to make it work for me :)

JSFiddle: http://jsfiddle.net/aortega/k6ke9n2c/

HTML Code:

  <div class="form-group col-sm-4" >
     <label for="birthdate" class="col-sm-4">Birthday</label>
     <div class="col-sm-8">
       <div class="input-group date" id="birthdate"  ng-model="vm.Birthdate" date-picker>
         <input type="text" class="form-control netto-input"  ng-model="vm.Birthdate" date-picker-input>

         <span class="input-group-addon">
           <span class="glyphicon glyphicon-calendar"></span>
         </span>
       </div>
     </div>
  </div>
 <div class="form-group col-sm-4">
     <label for="birthdateText" class="col-sm-4">Model:</label>
     <div class="col-sm-8">
         <input type="text" class="form-control netto-input"  ng-model="vm.Birthdate">
     </div>
  </div>
</body>

App.js:

Simply a controller setting the viewmodels Birtdate attribute:

var app = angular.module('exampleApp',[]);

app.controller('ExampleCtrl',  ['$scope', function($scope) {
    var vm = this;
    vm.Birthdate = "1988-04-21T18:25:43-05:00";
}]);

The first directive is initializing the datetimepicker and listening to the dp.change event.

When changed - the ngModel is updated as well.

// DatePicker -> NgModel
app.directive('datePicker', function () {
    return {
        require: 'ngModel',
        link: function (scope, element, attr, ngModel) {
            $(element).datetimepicker({
                locale: 'DE',
                format: 'DD.MM.YYYY',
                parseInputDate: function (data) {
                    if (data instanceof Date) {
                        return moment(data);
                    } else {
                        return moment(new Date(data));
                    }
                },
                maxDate: new Date()
            });

            $(element).on("dp.change", function (e) {
                ngModel.$viewValue = e.date;
                ngModel.$commitViewValue();
            });
        }
    };
});

The second directive is watching the ngModel, and triggering the input onChange event when changed. This will also update the datetimepicker view value.

// DatePicker Input NgModel->DatePicker
app.directive('datePickerInput', function() {
    return {
        require: 'ngModel',
        link: function (scope, element, attr, ngModel) {
            // Trigger the Input Change Event, so the Datepicker gets refreshed
            scope.$watch(attr.ngModel, function (value) {
                if (value) {
                    element.trigger("change");
                }
            });
        }
    };
});

Comments

2

I have the same problem and resolve like this

added in html part

<input class="someting" id="datepicker" type="text" placeholder="Dae" ng-model=""/>

and simple in Controller call

$scope.btnPost = function () {

          var dateFromHTML = $('#datepicker').val();

Comments

1

Have you tried AngularUI bootstrap? It has all the bootstrap modules rewritten in angular(including datepicker): http://angular-ui.github.io/bootstrap/

2 Comments

This no longer works with AngularJS 1.3+, see: github.com/angular-ui/bootstrap/issues/2830
I don't know about the datepicker, but I'm using a few other ui-bootstrap modules together with Angular 1.3.15 and I haven't encountered any problems.
0

One of ways around: set the id field to the input, then call document.getElementById('input_name').value to get the value of the input field.

Comments

0

Using this datepicker I had the same problem. I solved it using a little trick.

In the inputs tag I added a new attribute (dp-model):

<input class="form-control dp" type="text" dp-model="0" />
<input class="form-control dp" type="text" dp-model="1" />
...

And then in the js file I forced the binding in this way:

$scope.formData.dp = []; // arrays of yours datepicker models
$('.dp').datepicker().on('changeDate', function(ev){
    $scope.formData.dp[$(ev.target).attr('dp-model')] = $(ev.target).val();
});

Comments

0

This worked for me:

set

ng-model="date"

on your angular controller:


    $scope.date = '';

    $('#check-out').datepicker().on('changeDate', function (ev) {
        $scope.date= $('#check-out').val();
        $scope.$digest();
        $scope.$watch('date', function (newValue, oldValue) {
             $scope.date= newValue;
        });
    });

My actual trouble was that the value of the model was not reflected till another component on the scope was changed.

Comments

0

im using this , and my code :

    this.todayNow = function () {
        var rightNow = new Date();
        return rightNow.toISOString().slice(0,10);
    };
    $scope.selecteddate = this.todayNow();

    $(function() {
        //for displaying datepicker
        $('.date').datepicker({
            format: 'yyyy-mm-dd',
            language:'fa'
        });
        //for getting input value
        $('.date').on("changeDate", function() {
            $scope.selecteddate = $(".date").val();
        });

    });

Comments

0

To solve this, I have my HTML looking like this:

<div class='input-group date' id='datetimepicker1'>
<input type='text' ng-model="date.arrival" name="arrival" id="arrival" 
     class="form-control" required />
     <span class="input-group-addon">
         <span class="glyphicon glyphicon-calendar"></span>
     </span>
</div>

My ng-model wouldn't update, so I used this to fix it:

$("#datetimepicker1").on("dp.change", function (e) {
    $scope.date.arrival = $("#arrival").val(); // pure magic
    $('#datetimepicker2').data("DateTimePicker").minDate(e.date); // this line is not relevant for this example
});

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.