3

When I click outside of an open datepicker box in IE, I get the following error:

'object doesn't support property or method 'contains' Bootstrap datepicker'

The datepicker does not close. I've come across many fixes which involve modifying the Bootstrap source, but I would prefer to not go this route. (IE doesn't have a contain method)

I was able to fix the issue by calling this function on the top parent div:

<div class="clearfix" ng-click="formClicked($event)">
  <div class="form-group required">
    <label for="shipTo">Ship-To #</label>
    <select id="shipTo" class="form-control input-sm" ng-model="model.orderInfo.accountId"></select>
  </div>
  <div class="col-md-6">
    <div class="form-group required">
      <label for="shipDate">Ship Date</label>
      <div class="input-group calendar-box">
        <input id="shipDate" ng-model="model.orderInfo.shipDate" min-date="model.shipDateMin" max-date="model.shipDateMax" class="form-control input-sm" ng-click="dateOpen($event, 'shipDateOpened')" type="text" datepicker-popup="{{model.datePickFormat}}" is-open="model.shipDateOpened" ng-change="setCancelDate()" ng-readonly="true" required>
        <div class="input-group-addon cursor-pointer calendar-icon" ng-click="dateOpen($event, 'shipDateOpened')"></div>
      </div>
    </div>
  </div>
  <div class="col-md-6">
    <div class="form-group required">
      <label for="cancelDate">Cancel Date</label>
      <div class="input-group calendar-box">
        <input id="cancelDate" ng-model="model.orderInfo.cancelDate" min-date="model.cancelDateMin" max-date="model.cancelDateMax" class="form-control input-sm" ng-click="dateOpen($event, 'cancelDateOpened')" type="text" datepicker-popup="{{model.datePickFormat}}" is-open="model.cancelDateOpened" ng-change="checkCancelDate()" ng-readonly="true" required>
        <div class="input-group-addon cursor-pointer calendar-icon" ng-click="dateOpen($event, 'cancelDateOpened')"></div>
      </div>
    </div>
  </div>
</div>

And the function looks like this:

$scope.formClicked = function($event){
    $log.debug('form clicked');
    $event.preventDefault();
    $event.stopPropagation();

    $scope.model.shipDateOpened = false;
    $scope.model.cancelDateOpened = false;
};

The problem is, now on my mobile view this formClicked($event) function is fired when I try to tap on the select dropdown and it will not open. Is there a better solution to this problem, or is there a way I can conditionally render an ng-click when I am in my desktop view?

developthewebz
  • 1,827
  • 3
  • 17
  • 43

1 Answers1

4

I believe it is this piece of code that causes the problem :

var documentClickBind = function(event) {
   var popup = $popup[0];
   var dpContainsTarget = element[0].contains(event.target);
   // The popup node may not be an element node
   // In some browsers (IE) only element nodes have the 'contains' function
   var popupContainsTarget = popup.contains !== undefined && popup.contains(event.target);
   if (scope.isOpen && !(dpContainsTarget || popupContainsTarget)) {
     scope.$apply(function() {
       scope.isOpen = false;
    });
  }
};

As the comment says, and as MDN states - neither IE nor Edge have a Node.contains() and apparently MS have no plans for implementing it (the problem is raised several times, this for example is simply just closed). So a polyfill would be the way to deal with this problem for good :

if (!Node.prototype.contains) {
  Node.prototype.contains = function contains(node) {
    if (!(0 in arguments)) {
        throw new TypeError('1 argument is required');
    }
    do {
        if (this === node) {
            return true;
        }
    } while (node = node && node.parentNode);
    return false;
  }
}  

A slightly modified version of this, originally based on this suggestion.

Community
  • 1
  • 1
davidkonrad
  • 83,997
  • 17
  • 205
  • 265