Search code examples
javascriptangularjsdatepickerangular-bootstrap

Using the angular datepicker with ng-repeat


I'm trying to write something that lets me edit records with dates in them, I have this inside my table:

        <tr ng-repeat="event in eventFixtures track by $index">
            <td>{{event.date | date: 'dd/MM/yyyy'}}</td>
            <td>
                <div class="row">
                    <div class="col-md-6">
                        <p class="input-group">
                            <input type="text"
                                   class="form-control"
                                   ng-model="event.date"
                                   is-open="fixture{{$index}}popup"
                                   ng-click="openFixturePopup($index)"/>
                        </p>
                    </div>
                </div>
            </td>
        </tr>

However when I go to click on one of the input boxes the datepicker doesn't show up.

The open function is here:

$scope.openFixturePopup = function(fixture) {
    $scope["fixture"+fixture+"popup"] = true;
};

The variables are delcared like so:

    for(var i = 0; i < data.length; i++) {
        $scope["fixture"+i+"popup"] = false;
    }

From having the values of the variables be printed out above the table, they are being changed and if I create an input that is linked to a specific fixture popup e.g. like this:

<div class="row">
    <div class="col-md-6">
        <p class="input-group">
            <input type="text"
                   class="form-control"
                   uib-datepicker-popup="{{format}}"
                   ng-model="testDate"
                   is-open="fixture0popup"
                   ng-click="openFixturePopup(0)"/>
        </p>
    </div>
</div>

It works fine.

Does anyone know what might be causing this?


Solution

  • I have a hunch that trying to use interpolation for a variable name is what is throwing this off. I tried numerous things like $scope[dynamicVarName], $scope.$eval([dynamicVarName]), and others to no avail. I can't say for certain that is your issue, but I think I found a solution that you can try.

    Set an isOpen flag on your event and look at that, rather than creating a bunch of scope variables for state. This is also advantageous because if the index changes, the open state moves with the array element, so there is less chance that you get invalid states.

    Here's what the code could look like:

    var app = angular.module("myApp", [])
    .controller("myCtrl", function ($scope) {
      $scope.eventFixtures = [
        {name: "1", date: "1-1-01"},
        {name: "2", date: "2-2-02"},
        {name: "3", date: "3-3-03"},
        {name: "4", date: "4-4-04"},
        {name: "5", date: "5-5-05"}
      ];
    });
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
    <div ng-app="myApp" ng-controller="myCtrl">
      <table>
        <tr ng-repeat="event in eventFixtures track by $index">
          <td>{{event.date | date: 'dd/MM/yyyy'}}</td>
          <td>
            <div class="row">
              <div class="col-md-6">
                <p class="input-group">
                  <input type="text"
                         class="form-control"
                         ng-model="event.date"
                         is-open="{{event.isOpen}}"
                         ng-blur="event.isOpen = false;"
                         ng-focus="event.isOpen = true;"/>
                  isOpen? {{event.isOpen || false}}
                </p>
              </div>
            </div>
          </td>
        </tr>
      </table>
    </div>