Trigger click event of another element in angular? - angularjs

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.

Related

Customizing & Styling Angular X-Editable Popover Input

I'm using angular x-editable in my project for an editable popover. I've successfully made changes to the look of my confirmation button to an .svg I wanted to use and removed the Cancel button doing:
app.run(function(editableOptions, editableThemes) {
editableOptions.theme = 'default';
editableThemes[default].cancelTpl = '';
editableThemes[default].submitTpl = '<img class="popoverSubmitBtn"
src="images/confirmationBtn.svg" ng-click="$form.$submit()">';
});
However I am having issues when trying to change editableThemes[default].inputTpl. It seems like changes to inputTpl are not being registered for some reason. What I would like is for the input box that shows in the popover to have a circular 'x' button to clear the current input WITHIN the input text field.
This was actually default behavior in the original x-editable (see here at Twitter typeahead.js demo). While there is an equivalent to use editableOptions.displayClearButton=true, this creates an entire button next to the input box, much like the confirmation button, which is not what I want.
My plan was to use a directive here that provides the 'clear' button and use editableThemes[default].inputTpl = '<input type="text" reset-directive>'; but again, seems like its broken. Even this open issue here leads me to believe it was never working as intended.
Has anyone had any luck with this or knows of any workarounds that may help in my situation?
ALSO- a bit unrelated but on the topic of styling, how do I move the position of where the popover shows up? Currently it's smack-dab in the middle of where my cursor is when I click the text to activate popover, but I would like it a bit higher and to the right.
Got it working. For those with similar issues:
Styling for the popover can be controlled through xeditable.css found in the bower_components directory after installation
While inputTpl isn't functioning the way I expected, I added the
custom directive to the input field using e-* (i.e. e-my-directive) with no issues.

In AngularJS, how can I prevent a nested <button> from submitting the form that it's in?

I have a form (done in AngularJS) for entering records into a movie database. Within the form I have a dropdown of actors which the user can select from to add to the movie record that they are in the middle of creating. When the user clicks the button next to the dropdown to add the actor to the movie, it submits the entire form. I could, of course, take the easy way and use a div instead a but I feel that I shouldn't have to work around this like that. Is there a standard of way of dealing with this?
In these situations, as buttons in default are type="submit", Just set type="button" on all buttons that you do not want them to submit the form.
That would do the trick for you.
You can handle the click using ng-click.
In the Dom:
<button ng-click="handleClick()">I love Polka Dot Bow Ties.</button>
In the Controller:
$scope.handleClick= function handleClickFn($event) {
$event.stopPropagation();
}
Stopping the propagation of the event, prevents the event from bubbling up to its parent elements and triggering your submit.

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.

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

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.

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

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.

Resources