I have AngularJS (1.x) component - or actually directive to be precise,
and the elements inside this directive are get fired/worked/actioned only in the second click.
For example: a dropdown will not toggle unless you click twice.
After the second click the toggle will be on each next click.
It's like the elements are not digested in the DOM.
This is the component call:
<dropdown-custom-component-example></dropdown-custom-component-example>
This is the component html file:
<div class="dropdown">
<a class="btn pl-2" data-toggle="dropdown">
<i class="icon-options"></i>
</a>
<div class="dropdown-menu">
<a class="dropdown-item" data-toggle="modal" data-target=".create-supplier">
<i class="fa icon-plus text-primary"></i>
Action
</a>
</div>
</div>
you could try to digest by your own inside your directive, after you've checked if $digest isn't alreay in progress:
if(!$scope.$$phase) $scope.$digest();
// or $apply ..
hope this solves your issue :)
Most of the time AngularJS does not respond is because something is happening outside the Angular context, in those cases it's useful to try to replicate the functionality you want with built-in AngularJS directives.
It would be useful to have access to some of the implementation of your component. However, with all the information you have provided, you can use the ngClick built-in directive:
<div class="dropdown">
<a class="btn pl-2" data-toggle="dropdown">
<i class="icon-options"></i>
</a>
<div class="dropdown-menu">
<a class="dropdown-item" data-toggle="modal" data-target=".create-supplier" ng-click="yourFunctionHere(this)">
<i class="fa icon-plus text-primary"></i>
Action
</a>
</div>
</div>
AngularJS Docs - ngClick
Related
Here is the code:
<div ng-click="grid.appScope.navToPage(row)"class="ui-grid-cell" ui-grid-cell style="cursor: pointer">
<div class="ui-grid-cell-contents">
<a ng-href="/mywebpage/2" target="_blank">
<span class="glyphicon glyphicon-new-window"></span>
</a>
</div>'
</div>
I want to figure out some way to be able to click the a tag link without clicking the div with the ng-click. Is there a good way to do this?
You can prevent click propagation using the $event.stopPropagation() which is available on many angular directives such as ng-click. Please have a look at this question AngularJS ng-click stopPropagation
In your case, the anchor tag should look like this:
<a ng-href="/mywebpage/2" ng-click="$event.stopPropagation()" target="_blank">
<span class="glyphicon glyphicon-new-window"></span>
</a>
Try this
<a ng-href="/mywebpage/2" target="_blank" ng-click="$event.stopPropagation()"><span class="glyphicon glyphicon-new-window"></span></a>
I have a list item which toggles modal and sets a param using ng-click
the problem is when calling a function in any other place which logs Course.SelectedCourse it's undefined although Course.ID has a value.
<li class="facebook" style="width:33%;">
<a ng-click="Course.SelectedCourse = Course.ID" data-toggle="modal" data-target="#myModal">
<span class="glyphicon glyphicon-user"></span>
</a>
</li>
Use a function in the controller, this might look like this :
In the view :
<li class="facebook" style="width:33%;" >
<a ng-click="setSelectedCourse(Course.ID)" data-toggle="modal" data-target="#myModal">
<span class="glyphicon glyphicon-user"></span>
</a>
</li>
In the controller
function setSelectedCourse(course_id){
$scope.Course.SelectedCourse = course_id;
}
In AngularJS, directives have their own scope, your list is generated with ng-repeat, isn't it ? That's why
"Course.SelectedCourse = Course.ID"
doesn't work, because inside the div ng-repeat is looping $scope.Course is created locally and isn't the same that the one in your main controller. Besides, functions from main controller can be called by directives, That's why the previous answer works.
HTML code :
<ul class="dropdown-menu" role="menu">
<li>
<a href="#/profile">
<i class="fa fa-user"></i> My Profile </a>
</li>
<li>
<a href="#/source">
<i class="fa fa-user"></i> Source </a>
</li>
<li>
<a href="/user/logout">
<i class="fa fa-user"></i> Logout </a>
</li>
</ul>
My code :
element(by.cssContainingText('i.fa.fa-user', ' My Profile ')).click();
Problem : I am trying to click on element using class and cssContaingText but am not able to it. Please help me.
please help me
You may have solved it via the by.cssContainingText also. The problem with your current approach is that you are checking the text inside the i element, which is in your case empty:
<i class="fa fa-user"></i> My Profile
The text to check is located inside the a element:
element(by.cssContainingText('ul.dropdown-menu > li > a', 'My Profile')).click();
Alternatively, you may solve it without checking the text:
element(by.css("a[href*=profile]")).click();
Though, I would agree that "by partial link text" option is a better choice in this case.
I got the answer : I tried this code, it worked nicely.
element(by.partialLinkText('My Profile')).click();
I am running E2E on my angular application using Protractor. I am running into a very weird problem.
I am using the Bootstrap Dropdown which has some options. I need to click on one of the options.
I referred this answer which tries to do something similar, but doesn't work for me:
Protractor - how to select heavily nested dropdown element?
My structure looks like:
<div id="fc-more-btn" class="btn-group btn-group-sm dropdown" role="group" dropdown="" is-open="ctrl.fcDropdown">
<button type="button" class="btn btn-default dropdown-toggle filetree-btn" tooltip="More Actions" tooltip-trigger="mouseenter" tooltip-placement="bottom" ng-disabled="ctrl.sd.noSelections" dropdown-toggle="" aria-haspopup="true" aria-expanded="false">
<span class="fa fa-caret-down"></span>
</button>
<ul class="dropdown-menu filetree-dropdown" role="menu">
<li>
<a class="btn fc-dropdown-link" ng-disabled="ctrl.sd.noSelections||(ctrl.sd.multipleSelections||!ctrl.sd.dirSelected)" ng-click="ctrl.createNewFile()">
New File
</a>
</li>
<li>
<a class="btn fc-dropdown-link" ng-disabled="ctrl.sd.noSelections||(ctrl.sd.multipleSelections||!ctrl.sd.dirSelected)" ng-click="ctrl.createNewDir()">
New Folder
</a>
</li>
<li>
<a class="btn fc-dropdown-link" ng-disabled="ctrl.sd.noSelections" ng-click="ctrl.copyFiles()">
Copy
</a>
</li>
<li>
<a class="btn fc-dropdown-link" ng-disabled="ctrl.clipboardEmpty||ctrl.sd.noSelections||(ctrl.sd.multipleSelections||!ctrl.sd.dirSelected)" ng-click="ctrl.pasteFiles()" disabled="disabled">
Paste
</a>
</li>
<li>
<a class="btn fc-dropdown-link" ng-disabled="ctrl.sd.noSelections||ctrl.sd.multipleSelections" ng-click="ctrl.renameFile()">
Rename
</a>
</li>
</ul>
</div>
In my test, I am trying to click on the Rename link.
The code I have written is:
element(by.css('.dropdown-toggle')).click().then(function(){
//click on rename
});
On running the test, there is a small flicker over the dropdown toggle button, and it seems that the button is clicked. However, the dropdown that should be shown is not shown.
As a result of this, I am not able to simulate a click to rename. Am I doing something wrong?
Try selecting by cssContainingText, very helpful with dropdowns and nested elements!
element(by.cssContainingText('option', 'Rename')).click();
I have an Angular JS 1.3 app.
In it I have a table row repeater with an ng-click:
<tr ng-repeat-start="user in users.users" ng-click="showDetails = !showDetails">
<!-- main row, with the menu td shown below -->
<tr class="row-details" ng-show="showDetails" ng-class="{ 'active': showDetails }">
<td>this is the row that hows details</td>
</tr>
<tr ng-repeat-end></tr>
Which toggles opening a detail view. Works fine. But now I need to add another item in each of the tds, a Bootstrap button menu:
<td>
<div class="btn-group">
<div ng-switch on="user.status">
<button class="btn btn-link btn-gear dropdown-toggle" type="button" data-toggle="dropdown"><i class="fa fa-cog"></i></button>
<ul class="dropdown-menu dropdown-menu-right" role="menu" ng-switch-when="Inactive">
<li>Delete</li>
</ul>
<ul class="dropdown-menu dropdown-menu-right" role="menu" ng-switch-when="Invited">
<li>Resend invitation</li>
<li>Delete</li>
</ul>
<ul class="dropdown-menu dropdown-menu-right" role="menu" ng-switch-default>
<li>Reset password</li>
<li>Delete</li>
</ul>
</div>
</div>
</td>
Problem is, trying to click on this menu button instead triggers the ng-click on the row, toggling the row state but never opening my menu. How can I prevent this?
This is pretty tricky problem. The thing is that when you click menu button two things happens: the first is that it opens Bootstrap dropdown menu, and the second is that event propagates to the parent element and also triggers showDetails = !showDetails.
The obvious solution is to try to stop event propagation with $event.stopPropagation() on the td level, so that event doesn't bubble up the DOM tree and never triggers parent ngClick. Unfortunately, it will not work because Bootstrap sets up click event listener on the document element to benefit from bubbling, so you can't stop propagation.
The simplest solution I came up with in such cases is to set a flag on the original event object whether event occurred on the menu button. If this is the case ngClick on the tr won't do anything.
It will look like this for tr:
<tr ng-repeat-start="user in users.users" ng-click="$event.originalEvent.dropdown || (showDetails = !showDetails)">
ans for button:
<button ng-click="$event.originalEvent.dropdown = true" class="btn btn-link btn-gear dropdown-toggle" type="button" data-toggle="dropdown">
<i class="fa fa-cog"></i>
</button>
Demo: http://plnkr.co/edit/eIn6VW3Y2jHn0MtJQVcU?p=preview
With help of dfsq's answer I managed solve same kind of problem in Angular 2. Here is my sample code.
<td class="tablerowdata" (click)="$event.dropdown || onSelect(track)" >
<button (click)="$event.dropdown = true" type="button" class="btn btn-default dropdown-toggle trackbuttons" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">