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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.