1

I am trying to get a datepicker from UI Bootstrap to open when I click an icon. Here is my html:

<p class="input-group">
    <input type="text" class="form-control" datepicker-popup ng-model="dt" is-open="opened"/>
<span class="input-group-btn">
  <button type="button" class="btn btn-default" ng-click="open()"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</p>

And here is my js:

scope.open = function() {
    scope.opened = true;
};

scope.opened = false;

When I click the button, I hit open(), opened is changed and nothing happens. The datepicker does not appear. The strange thing is, if I put the ng-click on the input:

<input type="text" class="form-control" datepicker-popup ng-model="dt" is-open="opened" ng-click="open()"/>

Then the datepicker works and opens like it should. I am missing something somewhere. Does anyone understand what the issue it?

2 Answers 2

1
  1. Declare the opened variable in an object.
  2. Pass the $event object into the open event of your controller and call $event.stopPropagation(); prior to setting scope.status.opened = true.

Markup

<button type="button" class="btn btn-default" ng-click="open($event)"><i class="glyphicon glyphicon-calendar"></i></button>

Controller

scope.open = function ($event) {
    $event.stopPropagation();
    scope.status.opened = true;
};

Explanation As I Understand It.

The datepicker directive generates html to render the datepicker popup. stopPropagation() prevents the javascript click event from cascading\bubbling out of the element that you clicked on. The reason that you weren't seeing the popup is because the click event was bubbling down into that generated html, being handled a second time, and effectively closing the popup (similar behavior to opening the popup and then clicking again inside of the popup to close it).

Sign up to request clarification or add additional context in comments.

2 Comments

Why would I need to stopPropagation?
Updated answer to provide an explanation.
0

This is a scope issue, as you are setting a model variable to a primitive.

Try declaring the opened variable in an object, e.g. status.opened:

<p class="input-group">
    <input type="text" class="form-control" datepicker-popup ng-model="dt" is-open="status.opened"/>
    <span class="input-group-btn">
        <button type="button" class="btn btn-default" ng-click="open()"><i class="glyphicon glyphicon-calendar"></i></button>
    </span>
</p>

Controller

scope.status = {
    opened: false
}

scope.open = function () {
    scope.status.opened = true;
};

3 Comments

I tried that earlier. It still doesn't open. Again, I can put the exact code above on the input and it works fine.
I just logged the status.opened to my page and status.opened is not being updated in the html, so it is definitely some kind of scope issue.
Maybe a bugged version of ui-bootstrap? Could you reproduce the problem in this plunker?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.