Martin Slezák Martin Slezák - 4 years ago 718
Javascript Question

Adding Angular UI Datepicker dynamically

In my project I need to add dynamic amount of datepickers to the page.
I tried to do it this way (Plunker):

Script:

var app = angular.module('plunker', ['ui.bootstrap']);
app.controller('MainCtrl', function($scope) {
$scope.openDatePicker = function($event) {
$event.preventDefault();
$event.stopPropagation();

$scope.opened = true;
};

$scope.dateOptions = {
formatYear: "yy",
startingDay: 1,
format: "shortDate"
};

$scope.details = [{
"parameterValue": "2015-08-12"
}, {
"parameterValue": "2015-08-12"
}, {
"parameterValue": "2015-08-12"
}, {
"parameterValue": "2015-08-12"
}];
});


HTML:

<!DOCTYPE html>
<html ng-app="plunker">

<head>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular-animate.js"></script>
<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.13.3.js"></script>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
<script src="script.js"></script>
</head>

<body>
<div ng-controller="MainCtrl">
<form name="detailsForm" novalidate ng-submit="submitForm(detailsForm.$valid)">
<div ng-repeat="item in details" class="input-group">
<input ng-model="item.parameterValue" type="text" class="form-control" id="datePickerItem" datepicker-popup="shortDate"
is-open="opened" datepicker-options="dateOptions" current-text="Today" clear-text="Clear" close-text="Close" ng-readonly="false" />
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="openDatePicker($event)"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</div>
</form>
</div>
</body>
</html>


The problem is that when I try to open one datepicker, all of them are opened (logically, as they share the same
$scope.opened
variable). Also when I close them and try to open them again, nothing happens.

Is there a elegant way to achieve this?

Thanks.

Answer Source

All of your datepickers have id="datePickerItem".

The id attribute must be unique in html. Try this instead:

id="datePickerItem_{{$index}}"

This will add the ng-repeat's current index to the id, so you can be relatively certain your id's are unique. This should also prevent all the datepickers from opening at the same time.

Also, you're using one and the same opened variable for all datepickers.

Try this instead:

<div ng-repeat="item in details" class="input-group">
    <input ng-model="item.parameterValue" type="text" class="form-control" 
        id="datePickerItem_{{$index}}" datepicker-popup="shortDate" 
        is-open="opened[$index]" datepicker-options="dateOptions" current-text="Today"
        clear-text="Clear" close-text="Close" ng-readonly="false" />
    <span class="input-group-btn">
        <button type="button" class="btn btn-default" ng-click="openDatePicker($event, $index)">
            <i class="glyphicon glyphicon-calendar"></i>
        </button>
    </span>
</div>

And:

$scope.opened = [];
$scope.openDatePicker = function($event, index) {
    $event.preventDefault();
    $event.stopPropagation();

    $scope.opened[index] = true;
};

Just make sure you set $scope.opened[index] to false, in case you close the datepicker.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download