Clickable button inside of a clickable panel - angularjs

I have a button inside of an accordion, like this:
I made the entire accordion head clickable by doing this:
<accordion-heading ng-click="isopen=!isopen">
<div>
<span class="accordion-header">
<i class="pull-right glyphicon"
ng-class="{'glyphicon-chevron-down': accordionOpen,
'glyphicon-chevron-right': !accordionOpen}"></i>
</span>
<button class="delete-button" ng-click="remove()">Delete</button>
</div>
</accordion-heading>
The problem I have is when I click the delete button, remove() is called AND the accordion open/closes.
Is there a way to stop the accordion header from opening/closing when I click the delete button?

You can use $event.preventDefault(); $event.stopPropagation();:
<button class="delete-button" ng-click="
$event.preventDefault(); $event.stopPropagation(); remove()">Delete</button>
The click event object is accessible in ng-click as $event. preventDefault and stopPropagation will stop the event from reaching the accordion-heading click handler.

You need to stop the event from bubbling to the container
$scope.remove = function(event) {
event.preventDefault();
event.stopPropagation();
...
}
and
<button class="delete-button" ng-click="remove($event)">Delete</button>
Demo: plnkr

For me, if I use both functions
$event.preventDefault();
$event.stopPropagation();
nothing happened at all. So I use only
$event.stopPropagation();
It works good.

Related

Angular JS Restrict ng-click events in the same div

Both functions are triggered while I click on the inner a tag, how can I restrict this. I need to trigger onDelete() function only when is clicked
<div ng-click="ctrl.onEdit()">
{{content}}
<a href="" ng-click="ctrl.onDelete()" > Delete Me !</a>
</div>
Pass the $event in ctrl.onDelete($event) and then stop propagating it in the on delete function, you need this because events bubble towards parent elements
this.onDelete = function (event){
event.stopPropagation();
}
or simply write this after you ondelete function in html
ng-click="ctrl.onDelete(); $event.stopPropagation();"
You can achive that by passing $event and use stopPropagation:
<div ng-click="onEdit($event)" style="background-color:red;">
{{content}}
<a href="" ng-click="onDelete($event)" > Delete Me !</a>
</div>
JS
$scope.onEdit = function(event){
console.log("onEdit");
event.stopPropagation();
}
$scope.onDelete = function(){
console.log("onDelete");
event.stopPropagation();
}
Demo Plunkr
However its not good practice to use nested ng-click. Its hard to maintain and can lead to unexpected behaviour.
<div ng-click="ctrl.onEdit()">
{{content}}
</div>
<div>
<a href="" ng-click="ctrl.onDelete()" > Delete Me !</a>
</div>
I think it will work like this
It's called event bubbling. You can propagate the the event and cancel it like this
function onDelete($event){
if($event){
if ($event.stopPropagation) $event.stopPropagation();
if ($event.preventDefault) $event.preventDefault();
}
}
HTML
<div ng-click="ctrl.onEdit()">
{{content}}
<a href="" ng-click="ctrl.onDelete($event)" > Delete Me !</a>
</div>

Toggle buttons when click out of popover and button

Code here: https://plnkr.co/edit/ysD1JN0ELqu7ACgkkp79?p=preview
I have two buttons. One is "State1" and another is "State2".
In the beginning, it is in "State2" button. Then I click "State2" button, it toggle to "State1" button, also generate popover.
I want to click out of "State1" button and popover, then it will change from "State1" button to "State2" button. I use popover-trigger="outsideClick", but it does not work. Please advise. Thanks
<div ng-click="Ctrl.Check = !Ctrl.Check" popover-trigger="outsideClick">
<a ng-class="{'btn-danger': !Ctrl.Check, 'btn-default': Ctrl.Check }" confirm-link="Ctrl.deleteCurrent(Ctrl.A)" uib-popover="I appeared on focus! Click away and I'll vanish..." popover-trigger="outsideClick" popover-placement="right">
{{ Ctrl.Check ? 'State1' : 'State2' }}
</a>
</div>
here is the plunker
https://plnkr.co/edit/KXWzDN882fWEByUNzks6?p=preview
What I did
<a
ng-class="{'btn-danger': !isOpen, 'btn-default': isOpen }"
state-change-capture
confirm-link="Ctrl.deleteCurrent(Ctrl.A)"
uib-popover="I appeared on focus! Click away and I'll vanish..."
popover-trigger="'outsideClick'"
popover-is-open="isOpen"
ng-click="isOpen = !isOpen"
popover-placement="right">
{{ isOpen ? 'State1' : 'State2' }}
</a>
in the controller
$scope.isOpen = false;
$scope.$watch('isOpen', function (oldVal, newVal) {
//just for reference in case you need to know the status of popover
});
added a property for uib-popover known as popover-is-open="isOpen"
which tells if the popover is visible or not and based on that set the State 1 or 2
Also if you need to observe it then have added a watch to controller, just in case you need it.
You're missing the '' in the popover-trigger, and you don't need the first one on the div itself:
<div ng-click="Ctrl.Check = !Ctrl.Check">
<a ng-class="{'btn-danger': !Ctrl.Check, 'btn-default': Ctrl.Check }" confirm-link="Ctrl.deleteCurrent(Ctrl.A)" uib-popover="I appeared on focus! Click away and I'll vanish..." popover-trigger="'outsideClick'" popover-placement="right">
{{ Ctrl.Check ? 'State1' : 'State2' }}
</a>

Does an ng-click trigger a $stateChangeStart?

I'm using Angular UI Router and I have a very simple:
<a href='#' ng-click="toggleCollapse()">
<i class="icon icon-triangle-down" ng-class="{'icon-triangle-down': !isCollapsed,
'icon-triangle-right': isCollapsed}"></i>
</a>
My function looks like:
$scope.toggleCollapse = ->
alert 'here'
console.log $scope.isCollapsed
$scope.isCollapsed = !$scope.isCollapsed
However, for some reason, my
$rootScope.$on '$stateChangeStart', (event, next, nextParams) ->
console.log event
gets triggered when I click the link. Is there any way to prevent it from triggering the $stateChangeStart?
this is because you have href='#' tag.
<a ng-click="toggleCollapse()">
<i class="icon icon-triangle-down" ng-class="{'icon-triangle-down': !isCollapsed,
'icon-triangle-right': isCollapsed}"></i>
</a>
remove href that and it wont trigger route change

AngularJS + Bootstrap-UI: tooltip not hidden when button is disabled

I'm creating a web app using AngularJS + Twitter Bootstrap and Bootstrap-UI. When I place a tooltip on a button, it shows as expected; but if the button gets disabled (by the underlying controller) after being clicked, and the tooltip was being shown, the tooltip is not hidden and stays there forever. Here's a repro:
Plunker: http://embed.plnkr.co/numlaAuLOxh3a03Z7O85/preview
Just hover the button to make the tooltip appear, and then click it. The button is disabled, and the tooltip stays there. How can I avoid this behavior and have my tips correctly hidden?
I found that using simply replacing buttons with anchor tags worked perfectly for me.
<a role="button" type="button" class="btn btn-danger"
ng-click="someAction()" tooltip="Tooltip" ng-disabled="isDisabled">
<span class="glyphicon glyphicon-minus"></span>
</a>
Searching through GitHub issues I found the suggestion (seems to be related to the issue opened by you?) to use wrapping element that has a tooltip around the element: http://jsfiddle.net/RWZmu/
<div style="display: inline-block;" tooltip="My Tooltip">
<button class="navbar-btn btn-danger" ng-click="test()" ng-disabled="isDisabled" tooltip="Here's the tip">
<i class="glyphicon glyphicon-forward"></i>
</button>
</div>
Use the following logic here
HTML
<div ng-app="someApp" ng-controller="MainCtrl"
class="likes" tooltip="show favorites" tooltip-trigger="mouseenter"
ng-click="doSomething()">{{likes}}</div>
JS
var app = angular.module('someApp', ['ui.bootstrap']);
app.config(['$tooltipProvider', function($tooltipProvider){
$tooltipProvider.setTriggers({
'mouseenter': 'mouseleave',
'click': 'click',
'focus': 'blur',
'hideonclick': 'click'
});
}]);
app.controller('MainCtrl', function ($scope) {
$scope.likes = 999;
$scope.doSomething = function(){
//hide the tooltip
$scope.tt_isOpen = false;
};
})
Souce
Hide angular-ui tooltip on custom event
http://jsfiddle.net/3ywMd/10/

is there a shortcut to get window.history.back()

AFAIK, the only way to get Angular mimick a back button behavior is via a call to $window.history.back.
Now, I have a form with two buttons: submit and cancel. When I submit, I have some custom logic, and in the end I can easily call the back() method. But how could I achieve the same without a custom method for the cancel button?
This is my current html
<div class="form-group">
<button class="btn btn-primary" ng-click="save(berlet)">Ok</button>
<a class="btn btn-warning" ui-sref="jogasok">Cancel</a>
</div>
I would like to have a back() behavior when clicking the <a> tag. Are there any recommendations for it? My preferred syntax would be something like: `Cancel :)
Make a simple directive, to keep your controller free from redundant $window pollution:
PLUNKER
app.directive('goBack', function($window){
return function($scope, $element){
$element.on('click', function(){
$window.history.back();
})
}
});
<a go-back>Cancel</a>
My best idea until now is to attach the $window service to my directive, and call the back button through the $scope.
<a class="btn btn-warning" ng-click="window.history.back()">Cancel</a>
and in my directive I have
$scope.window = $window;

Resources