Question

I am using ui-bootstrap-tpls to render datepicker in my angular view. I have customized the template in this way :

customDatePicker.html

<script id="template/datepicker/day.html" type="text/ng-template">
<table role="grid" aria-labelledby="{{uniqueId}}-title" aria-activedescendant="{{activeDateId}}">
<thead>
    <tr>
        <th>
            <button type="button" class="btn btn-default btn-sm pull-left" ng-click="move(-1)" tabindex="-1">
                <i class="glyphicon glyphicon-chevron-left"></i>
            </button>
        </th>
        <th colspan="{{5 + showWeeks}}">
            <button id="{{uniqueId}}-title" role="heading" aria-live="assertive" aria-atomic="true" type="button" class="btn btn-default btn-sm" ng-click="toggleMode()" tabindex="-1" style="width:100%;">
                <strong>{{title}}</strong>
            </button>
        </th>
        <th>
            <button type="button" class="btn btn-default btn-sm pull-right" ng-click="move(1)" tabindex="-1">
                <i class="glyphicon glyphicon-chevron-right"></i>
            </button>
        </th>
    </tr>
    <tr>
        <th ng-show="showWeeks" class="text-center"></th>
        <th ng-repeat="label in labels track by $index" class="text-center">
            <small aria-label="{{label.full}}">{{label.abbr}}</small>
        </th>
    </tr>
</thead>
<tbody>
    <tr ng-repeat="row in rows track by $index">
        <td ng-repeat="dt in row track by dt.date" class="text-center" role="gridcell" id="{{dt.uid}}" aria-disabled="{{!!dt.disabled}}">
            <button type="button" style="width:100%;" class="btn btn-default btn-sm" ng-click="select(dt.date); openCustomDialog(dt.date)" ng-disabled="dt.disabled" tabindex="-1">
                <span>{{dt.label}}</span>
            </button>
        </td>
    </tr>
</tbody>
</table>
</script>
<datepicker ng-model="dt" min-date="minDate" show-weeks="true" class="well well-sm"></datepicker>

It's working fine. The problem I am facing is that I have to use custom data in the template in

<tbody>
    <tr ng-repeat="row in rows track by $index">
        <td ng-repeat="dt in row track by dt.date" class="text-center" role="gridcell" id="{{dt.uid}}" aria-disabled="{{!!dt.disabled}}">
            <button type="button" style="width:100%;" class="btn btn-default btn-sm" ng-click="select(dt.date); openCustomDialog(dt.date)" ng-disabled="dt.disabled" tabindex="-1">
                <span>{{dt.label}}</span>
            </button>
        </td>
    </tr>
</tbody>

For ex. I have to add class(to change color) for some kind of event.
enter image description here
Please help.

Was it helpful?

Solution

This is best solved using a directive inserted in the template. (Heres an updated plunker) Notice the highlight-day="dt" directive inserted here. This will bring each day into our custom directive to determine if we need to highlight the day. I prefer this method of highlight as opposed to performing surgery on third party javascript.

<button highlight-day="dt" ng-class="{selected: dt.highlighted}" type="button" style="width:100%;" class="btn btn-default btn-sm" ng-click="select(dt.date); openCustomDialog(dt.date)" ng-disabled="dt.disabled" tabindex="-1">
    <span>{{dt.label}}</span>
</button>

Once we have that, we can add a directive that looks like follows. Notice all the logic is done in the link function.

app.directive("highlightDay", ["myCustomObj", "monthMapper", function(myCustomObj, monthMapper){
  return {
    restrict: "A",
    //This brings the value of attribute into our current scope as an object, not just a DOM string
    scope: {
      highlightDay: "="
    },
    link: function(scope, element, attrs, ctrls) {
      //Make the native date object as a local variable
      var dt = scope.highlightDay.date;

      //Find out what the month name should be
      var monthName = monthMapper[dt.getMonth()];

      //Loop through all the possible selected dates
      for(var i in myCustomObj){
        var entry = myCustomObj[i];

        //If the month and day match
        var isMatch = entry.month === monthName && entry.day === dt.getDate();

        if(isMatch) {
          scope.highlightDate.highlighted = isMatch
          break;
        }
      }
    }
  };
}]);

You also notice the two other dependencies, myCustomObj and monthMapper. These are defined elsewhere angular and could be as I have done below.

app.constant("monthMapper", [
  "january",
  "february",
  "march",
  "april",
  "may", 
  "june",
  "july",
  "august",
  "september",
  "november",
  "december"
]);

app.value("myCustomObj", [{ 
      "month" : 'june',
      "day" : 19
    },
    { 
      "month" : 'june',
      "day" : 28
    }
]);

As a side note, you could speed up time determining if the day should be selected by reorganizing myCustomObj maybe something like this.

{
   june: [19, 28]
}

OTHER TIPS

I think that the best and fastest way to change the template is first copy the same template and make the adjustments on him as the template already has all the events and necessary classes binded.

The second solution for you is to take all the parts of ng-{{event}} (ng-class, ng-click, ng-...) and to connect them to your template in the same place.

Hope it make sense to you.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top