Differentiating arrow clicks between multiple UI-Select controls on one page - angularjs

Hi I would like to customize behavior of the ui-select little bit. I use two bootstap themed ui-select controls on my page with the help of templatecaches. In the template, I wired up arrow button click event using ng-click tag. That way I can easily catch the click event on the arrow button, and in my controller I can open a popup using function, for instance:
<button ng-click = "someFunctionInTheScope()">
For instance if I have two of those ui-select elements in my view, I need to differentiate which arrow button is clicked to display the correct popup. Since I am using the same template for two ui-select controls and since theoretically I can have any number of these controls on my page, I can not easily add a parameter to the method in the template to differentiate which arrow image of which ui-select control is clicked:
<button ng-click= "someFunctionInTheScope(1)">
Because both ui-select control would be using the same template code and 1 would be passed to the controller function for both of them.
Therefore I need to find a more clever way of changing the template dynamically once and for each control.
So I thought about having something like
<button ng-click= "someFunctionInTheScope($select.id)">
but when I debug it I see that functions parameter is undefined, every time it is clicked.
Can somebody please show me how to hack this?

There is no id property on the $select object. You're best bet is to pass something through the scope of the element containing the ui-select boxes. In other words, your code needs to generate a unique identifier for each ui-select box you have. This could be the $index property of an ng-repeat block, a timestamp, or something dependent on other context.
A little more context and I can provide a more specific answer.

Related

AngularJS using ngRequired without using ngModel

I'm currently maintaining an AngularJS application and need to have html inputs use the ngRequired directive. However these inputs do not use ngModel-- just straight up value to display the value dynamically and ngClick to popup a modal window that will eventually set the value in an object that is not bounded to a model. Seems like ngRequired only works when paired with ngModel in order for the submit button to reflect changes appropriately (like enable/disable).
I tried to work around not using ngRequired by manipulating the ngInvalid CSS which works great for showing the required fields-- however it does not bubble up to the submit button (disabling it if one or more required fields have no input). Is there a way to emulate ngRequired without using it explicitly in AngularJS?

Invoking a callback before or after showing a popover using angular-ui-bootstrap

I have a very simple code snipper in my page where I have a span. Hovering over this span displays a popover for which I am using angular-ui-bootstrap.
<span uib-popover="This is a popover from Akhilesh"
ng-mouseenter="vm.logToConsole('I am trying hard...')"
popover-trigger="mouseenter">Hover over me to see a popup..!!</span>
Basically I have written a function which makes and API call when the user hovers over this span. The problem here is that let's say I have 10 span tags one below the other and the user quickly moves from 1st span to 10th span (in the process hovering over all 8 spans in between), the API call will get triggered for all the spans. This is what I do not intend to have.
Any idea how can I implement the debounce functionality here?
Use a delay, like one second, after the mouse enters the region, then if the mouse hasn't entered another area, make the API call.
The popover-is-open attribute was added under the 0.13.4 release that can be used to watch the state of your popover like so:
<span uib-popover="This is a popover from Akhilesh"
popover-is-open="vm.isOpen"
popover-trigger="mouseenter">Hover over me to see a popup..!!</span>
Then in your controller:
$scope.$watch('isOpen', function() { });
But if you are just trying to keep the popovers from opening so quickly, consider using the popover-open-delay attribute.
Depending on your use, I found the best method is to simply add ng-mouseover, ng-click etc to the element and define a function to be called.
You can even create a variable and attach it to that objects scope on the fly to keep track of the state (open close).
Kind of hacky, but there is currently no way to define a function that is called on open and on close within ui-bootstrap popover.

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.

Directive that shows a sample depending on what value the user is highlighting

I'm stuck with Angular. I have a directive that shows a list and when the user hovers over an item, I want to show a preview of the item, with the preview being given by the directive user.
Some tricks though... I want the user to be able to filter the list using an input [which is easy on it's own] and there is some basic styling surrounding the list that I would like the directive to handle, like adding the checkboxes that well be watched to create the model for the directive.
I want the directive user to simply be able to write:
<preview-list list='unfilteredlist'>
<div>
<h1><blink>{{title}}</blink></h1>
<h2><marquee>{{html extrodinaire}}</marquee></h2>
</div>
</preview-list>
I tried using ng-transclude, but it uses a sibling scope and I've been looking for work arounds and I can't find any. The only ones I found involved writing the entire template in javascript, which honestly I can't believe people think that's an acceptable solution.
Any solutions, or is this actually completely impossible in Angular?
As i see it you have two options :
Create a preview box for each member in your list and toggle visibility on hover. This is great if you have only a few values and the preview box is heavy.
Create a transcluded directive in which - the main scope will hold the list and the currently hover element. The sibling scope will hold the preview container. Once the selected value changes the preview box will update (according to your bindings) and only thing left to do is position it.
transclude is hard at first but it pays off.
Hope this helps.

binding a css class to a element via angular directive

I want to attach a directive to a element. The directive will be responsible for the following:
1. Attach a click event to the element
2. Upon click.. show a drop-down
In order to perform the first activity I have added directive called "sortDirective" to my element below:
<span class="glyphicon glyphicon-arrow-down" style="font-size:0.6em" sort-directive></span>
This is done in the file layout.html
I am facing two issues:
1. the click event is not working
2. the drop-down should be shown only on click event. Right now you will notice that the drop-down (blue in color) is being shown at all the times.
I believe i am missing something here since my directive sort-directive is falling within another directive custom-table.
Am I thinking in the right direction or am I totally off ?
Plnkr Here
I wouldn't call the click event with the directive. My advice would be just to put ng-click to the span that you want to call the function from (and move the function to the controller).
You might want to look at this thread:
trigger click event from angularjs directive
Also a quick css tip - add these rules
cursor:pointer;
padding:0 0 0 5px;
to the class .header-cells.
Finally, don't you think that the arrow is too small to click it? Try binding the click event to the whole container.
i finally managed to lay this out. Those interested in seeing how it is done ..here is a plnkr
http://plnkr.co/edit/TG6aCEu2TgPq28Jcj0nM?p=info
just click on any of the headers (in orange) and you should see the results.

Resources