jQuery ui datepicker with Angularjs

JqueryJquery UiAngularjs

Jquery Problem Overview


I want to use jQuery UI datepicker with AngularJS.

I have a sample , but my code is not working.

Sample:

http://www.abequar.net/jquery-ui-datepicker-with-angularjs/

My Code:

<input id="sDate" name="programStartDate" type="text" datepicker required/>



angular.module('elnApp')
 .directive('datepicker', function () {
  return {
    restrict: 'A',
    require : 'ngModel',
    link : function (scope, element, attrs, ngModelCtrl) {
        $(function(){
            element.datepicker({
                dateFormat:'yy-mm-dd',
                onSelect:function (date) {
                    ngModelCtrl.$setViewValue(date);
                    scope.$apply();

                }
            });
        });
    }
} });

It shows an error TypeError: Object [object Object] has no method 'datepicker'.

Jquery Solutions


Solution 1 - Jquery

I have almost exactly the same code as you and mine works.

Do you have jQueryUI.js included in the page?

There's a fiddle here

<input type="text" ng-model="date" jqdatepicker />
<br/>
{{ date }}


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

datePicker.directive('jqdatepicker', function () {
    return {
        restrict: 'A',
        require: 'ngModel',
         link: function (scope, element, attrs, ngModelCtrl) {
            element.datepicker({
                dateFormat: 'DD, d  MM, yy',
                onSelect: function (date) {
                    scope.date = date;
                    scope.$apply();
                }
            });
        }
    };
});

You'll also need the ng-app="app" somewhere in your HTML

Solution 2 - Jquery

angular.module('elnApp')
.directive('jqdatepicker', function() {
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function(scope, element, attrs, ctrl) {
            $(element).datepicker({
                dateFormat: 'dd.mm.yy',
                onSelect: function(date) {
                    ctrl.$setViewValue(date);
                    ctrl.$render();
                    scope.$apply();
                }
            });
        }
    };
});

Solution 3 - Jquery

As a best practice, especially if you have multiple date pickers, you should not hardcode the element's scope variable name.

Instead, you should get the clicked input's ng-model and update its corresponding scope variable inside the onSelect method.

app.directive('jqdatepicker', function() {
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function(scope, element, attrs, ngModelCtrl) {
            $(element).datepicker({
                dateFormat: 'yy-mm-dd',

                onSelect: function(date) {
                    var ngModelName = this.attributes['ng-model'].value;

                    // if value for the specified ngModel is a property of 
                    // another object on the scope
                    if (ngModelName.indexOf(".") != -1) {
                        var objAttributes = ngModelName.split(".");
                        var lastAttribute = objAttributes.pop();
                        var partialObjString = objAttributes.join(".");
                        var partialObj = eval("scope." + partialObjString);
                    
                        partialObj[lastAttribute] = date;
                    }
                    // if value for the specified ngModel is directly on the scope
                    else {
                        scope[ngModelName] = date;
                    }
                    scope.$apply();
                }

            });
        }
    };
});

EDIT

To address the issue that @Romain raised up (Nested Elements), I have modified my answer

Solution 4 - Jquery

I finally was able to run datepicker directive in angular js , here are pointers

include following JS in order

  1. jquery.js
  2. jquery-ui.js
  3. angular-min.js

I added the following

<script src="http://code.jquery.com/jquery-1.10.2.js"></script>
<script src="http://code.jquery.com/ui/1.10.4/jquery-ui.js"></script> 
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"> </script>      

in html code

<body ng-app="myApp" ng-controller="myController">
// some other html code 
<input type="text" ng-model="date" mydatepicker />
<br/>
 {{ date }}
 //some other html code
 </body>

in the js , make sure you code for the directive first and after that add the code for controller , else it will cause issues.

date picker directive :

var app = angular.module('myApp',[]);
app.directive('mydatepicker', function () {
return {
    restrict: 'A',
    require: 'ngModel',
     link: function (scope, element, attrs, ngModelCtrl) {
        element.datepicker({
            dateFormat: 'DD, d  MM, yy',
            onSelect: function (date) {
                scope.date = date;
                scope.$apply();
            }
        });
    }
  };
});

directive code referred from above answers.

After this directive , write the controller

app.controller('myController',function($scope){
//controller code
};

TRY THIS INSTEAD in angular js

  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>  

along with jquery.js and jquery-ui.js

we can implement angular js datepicker as

<input type="date" ng-model="date" name="DOB">

This gives the built in datepicker and date is set in ng-model and can be used for further processing and validation.

Found this after lot of successful headbanging with previous approach. :)

Solution 5 - Jquery

I modified the code and wrapped view update inside $apply().

link: function (scope, elem, attrs, ngModelCtrl){	
var updateModel = function(dateText){
	// call $apply to update the model
	scope.$apply(function(){
		ngModelCtrl.$setViewValue(dateText);
	});
};
var options = {
	dateFormat: "dd/mm/yy",
	 // handle jquery date change
	onSelect: function(dateText){
		updateModel(dateText);
	}
};
 // jqueryfy the element
elem.datepicker(options);

}

working fiddle - http://jsfiddle.net/hsfid/SrDV2/1/embedded/result/

Solution 6 - Jquery

onSelect doesn't work well in ng-repeat, so I made another version using event bind

html

<tr ng-repeat="product in products">
<td>
    <input type="text" ng-model="product.startDate" class="form-control date-picker" data-date-format="yyyy-mm-dd" datepicker/>
</td>
</tr>

script

angular.module('app', []).directive('datepicker', function () {
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function (scope, element, attrs, ngModelCtrl) {
            element.datepicker();
            element.bind('blur keyup change', function(){
                var model = attrs.ngModel;
                if (model.indexOf(".") > -1) scope[model.replace(/\.[^.]*/, "")][model.replace(/[^.]*\./, "")] = element.val();
                else scope[model] = element.val();
            });
        }
    };
});

Solution 7 - Jquery

Unfortunately, vicont's answer did not work for me, so I searched for another solution which is as elegant and works for nested attributes in the ng-model as well. It uses $parse and accesses the ng-model through the attrs in the linking function instead of requiring it:

myApp.directive('myDatepicker', function ($parse) {
    return function (scope, element, attrs, controller) {
      var ngModel = $parse(attrs.ngModel);
      $(function(){
        element.datepicker({
            ...
            onSelect:function (dateText, inst) {
                scope.$apply(function(scope){
                    // Change binded variable
                    ngModel.assign(scope, dateText);
                });
            }
        });
     });
    } 
});

Source: ANGULAR.JS BINDING TO JQUERY UI (DATEPICKER EXAMPLE)

Solution 8 - Jquery

You main Index.html file for Angular can use the body tag as the ng-view. Then all you need to do is include a script tag at the bottom of whatever page is being pulled into Index.html by Angular like so:

<script type="text/javascript">
$( function() {
	$( "#mydatepickerid" ).datepicker({changeMonth: true, changeYear: true, 
		yearRange: '1930:'+new Date().getFullYear(), dateFormat: "yy-mm-dd"});
});
</script>

Why overcomplicate things??

Solution 9 - Jquery

Here is my code-

var datePicker = angular.module('appointmentApp', []);

datePicker.directive('datepicker', function () {
    return {
        restrict: 'A',
        require: 'ngModel',
         link: function (scope, element, attrs, ngModelCtrl) {
            $(element).datepicker({
                dateFormat: 'dd-mm-yy',
                onSelect: function (date) {
                    scope.appoitmentScheduleDate = date;
                    scope.$apply();
                }
            });
        }
    };
});

Solution 10 - Jquery

myModule.directive('jqdatepicker', function () {
    return {
        restrict: 'A',
        require: 'ngModel',
         link: function (scope, element, attrs, ngModelCtrl) {
        	element.datepicker({
                dateFormat: 'dd/mm/yy',
                onSelect: function (date) {   
                	var ar=date.split("/");
                	date=new Date(ar[2]+"-"+ar[1]+"-"+ar[0]);
                	ngModelCtrl.$setViewValue(date.getTime());
                //    scope.course.launchDate = date;
                    scope.$apply();
                }
            });
        	    	
        }
    };
});

HTML Code :

<input type="text" jqdatepicker  ng-model="course.launchDate" required readonly />

Solution 11 - Jquery

var selectDate = element.datepicker({
    dateFormat:'dd/mm/yy',
    onSelect:function (date) {
        ngModelCtrl.$setViewValue(date);
        scope.$apply();
    }
}).on('changeDate', function(ev) {
    selectDate.hide();
    ngModelCtrl.$setViewValue(element.val());
    scope.$apply();
});                            

Solution 12 - Jquery

I had the same problem and it was solved by putting the references and includes in that order:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.9.1/jquery-ui.min.js"></script>
<link href="http://code.jquery.com/ui/1.10.3/themes/redmond/jquery-ui.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>

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

datePicker.directive('jqdatepicker', function () {
    return {
        restrict: 'A',
        require: 'ngModel',
         link: function (scope, element, attrs, ngModelCtrl) {
            element.datepicker({
                dateFormat: 'dd/mm/yy',
                onSelect: function (date) {
                    scope.date = date;
                    scope.$apply();
                }
            });
        }
    };
});

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.9.1/jquery-ui.min.js"></script>
<link href="http://code.jquery.com/ui/1.10.3/themes/redmond/jquery-ui.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>

<body ng-app="app">
<input type="text" ng-model="date" jqdatepicker />
<br/>
{{ date }}
</body>

Solution 13 - Jquery

i struggled alot and found a solution that is working as of 22 nov 2021!

things you have to use js/css

  1. <script type="text/javascript" src="https://cdn.jsdelivr.net/jquery/latest/jquery.min.js"></script>
    
  2. <script type="text/javascript" src="https://cdn.jsdelivr.net/momentjs/latest/moment.min.js"></script>
    
  3. <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/daterangepicker/daterangepicker.min.js"></script>
    
  4. <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/daterangepicker/daterangepicker.css" />
    

your html code in your view

<p>Date <input type="text" name="dateRange" id="dateRange" value="01/01/2018 - 01/15/2018" /></p>

jquery function handle should be inside the body of a controller for example:

app.controller('homeController', ['$location','$scope','$rootScope','$http','$cookies','$interval', function($location,$scope,$rootScope,$http,$cookies,$interval){

// your $scope.fun=async function(){} etc all comes here

//then

//jquery function call
$('#dateRange').daterangepicker({
        startDate: moment().subtract(365,'days'),
        endDate:moment(),
        opens: 'left'
    }, function(start, end, label) {
        console.log("A new date selection was made: " + start.format('YYYY-MM-DD') + ' to ' + end.format('YYYY-MM-DD'));
        $scope.fromDateData=start.format('YYYY-MM-DD');
        $scope.toDateData=end.format('YYYY-MM-DD');
    });
}]);

Solution 14 - Jquery

I think you are missing the Angular ui bootstrap dependency in your module declaration, like this:

angular.module('elnApp', ['ui.bootstrap'])

See the doc for Angular-ui-bootstrap.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser2473037View Question on Stackoverflow
Solution 1 - JqueryKevin JonesView Answer on Stackoverflow
Solution 2 - JqueryvicontView Answer on Stackoverflow
Solution 3 - JqueryNahnView Answer on Stackoverflow
Solution 4 - Jqueryrohit gargView Answer on Stackoverflow
Solution 5 - JqueryhS4View Answer on Stackoverflow
Solution 6 - JqueryJonghee ParkView Answer on Stackoverflow
Solution 7 - JqueryzeillahView Answer on Stackoverflow
Solution 8 - JqueryCiaran WhyteView Answer on Stackoverflow
Solution 9 - JqueryFahim IqbalView Answer on Stackoverflow
Solution 10 - JqueryAmit BhandariView Answer on Stackoverflow
Solution 11 - Jqueryuser8237545View Answer on Stackoverflow
Solution 12 - JqueryAlexandre NascimentoView Answer on Stackoverflow
Solution 13 - JquerySaud AhmedView Answer on Stackoverflow
Solution 14 - JqueryRaibazView Answer on Stackoverflow