Angular Bootstrap: How to show a popover based on a child elements' trigger? - angularjs

Demo Fiddle
I'd like to show some help text using a popover for the entire group of fields, not for each individual input.
In the fiddle, I'm simply using a mouseenter trigger to show how it should look like, but what I really want is to trigger it on focus for any input, but have the popover be positioned based on the parent element.
In non-angular land, I'd trigger a custom event (say groupenter) when any one of the fields is in focus, and have the popover listen to that event. I'd also debounce the corresponding groupleave event so the popover won't flicker as I tab around the inputs.
What's an angular-y way to accomplish that here?
(I think this patch helps, but it just got committed days ago)

Got it working!
I had to fork tooltip.js to add 'groupenter': 'groupleave' to triggerMap since there's no public api to add to the map.

Related

FocusListener on Tabs/ScaleImageLabel

I've added ScaleImageLabel to swipe Tabs. I want to calculate amount of time each tab remains in focus. I added focus listener to Tabs/ScaleImageLabel but it's not getting fired. It's working when added to the form. Any suggestions on how to achieve it?
If I understand correctly what you need is a tab selection listener. Focus listener will only work for focusable components and labels are by default non-focusable. I would recommend avoiding it since focus is used for key based navigation. It might produce different results than you would expect.

AngularJS ng-class Expression Not Updating Properly

So I'm trying to build a custom autocomplete dropdown for a text input. To do it, I am listening for the keydown event and if it's an up or down arrow press, I'm setting a $scope.arrowSelectedItem variable to the proper one in the list. (As a side note, all the functionality works as far as selecting an item from the list that pops up. All I'm trying to do is highlight the current one that they've marked with the up/down arrows).
On the markup side, the items in the autocomplete list are output with ng-repeat, with ng-repeat="item in itemList". The ng-class expression I'm using is ng-class="{highlighted: item === arrowSelectedItem}". I know that the $scope.arrowSelectedItem is being updated on each arrow press by using console.log, but for some reason the class isn't being updated to the list item properly.
What I've found is that after the first time of hitting an arrow key, if I make the text input box lose focus, then the class is added. Then if I click back in the box, move the arrow to select a different item, click out of the input box, then click back in, the class is added to the new one. I know that sounds weird, but that's what I've found.
What I'm not sure about is why the ng-class expression isn't being evaluated on every arrow key press. Does anyone have any ideas why?
The answer here is that "raw" DOM events which fire outside of one of angular's built in directives (such as click events via ng-click etc) will not trigger a $digest cycle update. Until this happens the $scope properties will not be updated.
If you are in a position where you are listening for DOM events by using another framework, or simply using addEventListener(), you will need to let angular know about any changes by using $scope.$apply(), or by wrapping the code in a $timeout().
If you do this in your event handler, angular will trigger a new $digest cycle update for every keypress and your new scope values will propagate to the view.

Need to $watch property from within an accordion (Angular-UI) but won't work

We're building a page with Angular, Angular-UI and UI-Bootstrap. The last one includes a directive for accordion, which simplifies a quite repetitive task of building up an accordion and an accordion group.
We, however, must watch for changes from an input inside that accordion. Problem is that the accordion has a child scope and it work work.
Here's a sample from Plunker (open the accordion by clicking on "Just a heading").
Is it possible to track changes into that input?
Try to $emit a custom event. It should bubble up to your scope. Worst case you should be able to listen to that event on the $rootScope
so something like :
$scope.$emit('input:change',{DATA});
on the accordion controller
and
$scope.$on('input:change'),function(data){
//do stuff with the change in input
})

Kendo UI button swith angular

I have the following example.
Two kendo UI buttons and two regular buttons. Both should enable/disable the button on bottom. Only the regular buttons do and I don't understand why. Probably has something to do with the scope...
EDIT:
From another example I have, it seems like the scope is updated correctly but the ui is not updated. In my example i have another control that when I click it the ui is suddenly being updated.
Found the answer:
When clicking the kendo button the scope does change but it doesn't go through angular so angular doesn't know that the scope was changed so the digest cycle doesn't run.
So adding $scope.$apply(); at the end of the function triggers the digest.
Took the explanation from here.

Trigger click event of another element in angular?

I have an input box and Its bound with datepicker. In my view, there is small calendar icon besides this input box. I want to trigger click event of an input box when user clicks on this calendar icon. I have done this using directive which I have applied to calendar icon. But its almost like jQuery. So is there any different way to achieve this? If my approach is wrong then please guide me to the right direction. I am new to angular and I have read some articles where I read that avoid use of jQuery. Thanks
My Directive
myApp.directive('openCal',function($compile,$filter) {
return {
link:function(scope,element,attrs) {
element.bind("click",function() {
element.siblings("input").trigger("click");
});
}
};
});
Its working fine. But I am not sure that is it right approach or not??
No, if I understand what you are trying to do you are over-complicating things a bit.
In your case it looks like you would have something like:
<img open-cal/>
<input ng-click="doSomething()">
Where click on the img triggers a click on the input, via the openCal directive. Instead considering doing something like this:
<div ng-click="doSomething()">
<img>
<input>
</div>
If doSomething() needs to get data from the input, use ng-model to bind data from your input to your scope.
ALTHOUGH!
If you ever need to do a directive, that is the right way to do it. Using element.bind is not a problem since that is included in Angular. What you want to avoid is using stuff like $('.calendar').click and such.
Another way to approach this would be to add a <label> element for your input field that contains the calendar. Then clicking the calendar would focus the input field. Then all you'd have to do is listen for the focus event on your input field to do your extra work. This has the added bonus of working if someone navigates to your input field via the keyboard by hitting the tab key.

Resources