Angularjs ng-click first click not working on mobile - angularjs

I'm new to angularjs. Here is my code
<ul>
<li ng-if="book.account.Customer.HasWorkspaceAccess"><a href ng-click="book.setType('workspace')" class="clickable">Book a Workspace</a></li>
<li ng-if="book.account.Customer.HasMeetingRoomAccess"><a href ng-click="book.setType('meetingroom')" class="clickable">Book a Meeting Room</a></li>
<li ng-if="book.account.Customer.HasBoardRoomAccess"><a href ng-click="book.setType('boardroom')" class="clickable">Book a Boardroom</a></li>
<li>My Account</li>
</ul>
Somehow all a tags is not working for the first tap on mobile device. It's active after tapping and second tap will trigger the ng-click function.
Thanks in advance for any help.

Related

angularjs showing a tab if condition is met in ng-repeat

Is it possible to split this ng-repeat loop in angularjs? I have a set of tabs and the data is found in workspace in workspaces. I want to basically check a condition ng-if "savedSettings=='account'", show specific tab. ng-if"savedSettings=='shelf'" show tab. How can I work this conditional render in?
There are four tabs found in this workspace.
<li ng-repeat="workspace in workspaces" class="workspace.activeclass">
<a id="workspace.tabid" href="{{workspace.hrefid}}" data-toggle="tab"> {{workspace.name}}
</a>
</li>
Use the ng-show directive:
<li ng-repeat="workspace in workspaces"
class="workspace.activeclass"
ng-show="workspace.tabid == savedSetting">
<a id="workspace.tabid" href="{{workspace.hrefid}}" data-toggle="tab"> {{workspace.name}}
</a>
</li>
For more information, see
AngularJS ng-show Directive API Reference

Angular JS- testing with Protractor: how to get an element when element doesn't have a tag-name?

I am developing a test suite for my AngularJS app using Protractor as my testing framework.
The app's menu is displayed at a fixed location across all pages of the site- when the user hovers the cursor over any of the buttons on the menu, the cursor changes to a pointer, to indicate that that button can be clicked. Each button in the menu represents a particular page of the app- if there are sub-pages belonging to a page when the user hovers the cursor over the menu button for that page, a sub-menu is displayed, with text-buttons for each of the sub-pages.
I am currently working on a test that will test the functionality of the menu- hovering the cursor over one of the buttons on the menu, checking that the sub-menu is displayed, and then hidden again when the cursor is no longer hovering over that menu button, checking that clicking any of the menu buttons/ sub-menu buttons take you to the right page, etc.
The HTML for the menu is written as follows:
<ul id="nav"
class="nav"
data-slim-scroll
data-collapse-nav
data-highlight-active>
<li data-ng-mouseenter="setMenuTop($event)" ng-show="menu.pages.length > 0 || menu.upages.length > 0 || canCreatePage">
<i class="ti-layers"></i><span data-i18n="Pages"></span>
<ul class="text-capitalize">
<li ng-repeat="page in menu.pages"><i class="ti-angle-right"></i><span data-i18n="{{page.title}}"></span></li>
<li ng-repeat="upage in menu.upages">
<div class="nav-menu-divider" data-ng-if="$index === 0"></div>
<a href="#/{{upage.location}}" target="_self">
<i class="ti-angle-right"></i><span data-i18n="{{upage.title}}"></span>
</a>
</li>
<li data-ng-show="canCreatePage">
<div class="nav-menu-divider"></div>
<a href="#/pages/create" target="_self">
<i class="ti-angle-right"></i><span data-i18n="Create Page"></span>
</a>
</li>
</ul>
</li>
<li>...</li>
<li>...</li>
<li>...</li>
<li>...</li>
<li data-ng-mouseenter="setMenuTop($event)">
<i class="ti-settings"></i><span data-i18n="Config"></span>
<ul>
<li ng-repeat="page in menu.config"><i class="ti-angle-right"></i><span data-i18n="{{page.title}}"></span></li>
<li ng-show="platform._id"><a ng-href="#/config/platform/{{platform._id}}" target="_self"><i class="ti-angle-right"></i><span data-i18n="Platform"></span></a></li>
<li ng-show="system._id"><a ng-href="#/config/system/{{system._id}}" target="_self"><i class="ti-angle-right"></i><span data-i18n="System"></span></a></li>
<li><i class="ti-angle-right"></i><span data-i18n="Users"></span></li>
<li><i class="ti-angle-right"></i><span data-i18n="Backup / Restore"></span></li>
<li ng-show="systemActions.dateTime"><i class="ti-angle-right"></i><span data-i18n="Date / Time"></span></li>
</ul>
</li>
<li class="nav-footer">
<span>{{currentTime.localTDZFormat}}</span>
</li>
</ul>
As shown, there are two menu items which have 'sub-menus' associated with them.
I want to test that when the user hovers their cursor over one of the menu-items that have an associated sub-menu, the sub-menu is displayed correctly, and when the cursor leaves the menu-item, the sub-menu is no longer displayed: I have tried to do this with the following test:
it('should display the Pages menu', function() {
browser.waitForAngularEnabled(false);
browser.actions().mouseMove(pagesMenuBtn).perform();
expect(pageVarBrowserBtn.isDisplayed()).toBeTruthy();
browser.actions().mouseMove(userCircle).perform();
expect(pageVarBrowserBtn.isDisplayed()).toBeFalsy();
browser.waitForAngularEnabled(true);
});
The variables used in this test are defined with:
var pagesMenuBtn = element(by.id('pagesMenuBtn'));
var pageVarBrowserBtn = element.all(by.id('menu.pages')).get(0);
var userCircle = element(by.id('icon-user-circle'));
The pageVarBrowserBtn is the first menu-item in the sub-menu displayed when the user hovers their cursor over the pagesMenuBtn.
Currently, when I run the test, the browser opens, navigates to the root page of my app, and hovers the cursor over the pagesMenuBtn element, so that the sub-menu is displayed (I can see it displayed in the browser window that was opened up by the test).
But, I then get an error in the console that says:
Failed: Index out of bound. Trying to access element at index: 0, but there are only 0 elements that match locator By(CSS selector, *[id="menu.pages"])
I don't understand why I'm getting this error...? How can I get a single element from the sub-menu that's being displayed, in order to check that it is the correct item and that clicking it takes the user to the correct location? I can't specify the exact element's ID because it is being created by the ng-repeat, so that's why I'm trying to get it by its position/ array index - 0.
First of all, There may be two reasons why you are getting the above error.
1. Either the locator you are using is wrong.
2. Your script is not waiting until the element is displayed in DOM.
In your case, you have mentioned a wrong locator as element.all(by.id('menu.pages')) because there is no element with id menu.pages is present in your HTML.
Instead of using element.all(by.id('menu.pages')), change it to element.all(by.repeater('page in menu.pages')).get(0) to get the 1st element from the menu list. Also kindly refer Element locators in Protractor to find the list of all available locating strategies that is supported by protractor.
Hope this might help solve your problem!
Did you try using element.all(locator).first() to get the first element form the selector

need inner action list supported angular js dropdown

Can any one provide me reference to angularjs dropdown with action links as shown in the image? From the action list if we mouse over on any lable separate action list should be shown out. Please see the attached screen shot for reference. I should be able to have part2 also as shown in the image. The official Angularjs UI Bootstrap dropdown menu (ui.bootstrap.dropdown) provides only one list of actions (part1 from the image)
As of now I have used the following normal code which is working fine :
<div class="btn-group" dropdown is-open="status.isopen">
<button type="button" class="btn dropdown-toggle" dropdown-toggle>
Save Options <span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">
<li><a href ng-click="saveFilter(ui3DataSet)">Save Filter</a></li>
<li><a href ng-click="saveAsFilter(ui3DataSet)">Save Filter As</a></li>
</ul>
</div>
But now when I mouse over saveFilter(ui3DataSet), another list should be shown on the right side. I am looking for any Angularjs plugin provides this feature readily.
As per #Dmitri Zaitsev, the following solves the issue:
<li class="dropdown-submenu">
<a href ng-click="saveAsFilter(ui3DataSet)">Others</a>
<ul class="dropdown-menu">
<li> One </li>
<li> two </li>
</ul>
</li>
Here is a pure Bootstrap implementation:
http://bootsnipp.com/snippets/featured/multi-level-dropdown-menu-bs3#comments
You could wrap it into Angular directive if you want to (see e.g. the implementation of jQuery Passthrough by UI Utils).
Also other threads that might be of help/related:
Dynamically creating nested navigation menu item using Bootstrap and Angularjs
AngularJS multilevel dropdown menu for a menu structure generated from a recursive directive
Angular UI multi-level Dropdown Toggle

UI-Router ui-sref-active throws error when using ui-sref params

I've got a Bootstrap navbar dropdown menu, where clicking the parent link produces the dropdown list (default behaviour). The dropdown list of the parent is built using ngRepeat from an array of navigation data, and each has a ui-router state parameter, so it looks like:
<li class="dropdown">
<a href class="dropdown-toggle" data-toggle="dropdown">
Parent Link
</a>
<ul class="dropdown-menu" role="menu">
<li ng-repeat="item in navCtrl.items()"
ui-sref-active="active">
<a ui-sref="some.state({ paramKey: paramValue })">
{{item.link}}
</a>
</li>
</ul>
</li>
But, even though it does seem to drop the active class on my link it throws this error in the console:
TypeError: Cannot read property 'name' of undefined
I am not entirely sure about the answer, but, as far as I know, why would you use navCtrl.items() using brackets? I have never seen it used like that before. Wouldn't the old item in items ng-repeat work? Sorry if it does not help at all.

Stagger (transition-delay) children to an element with ng-show

I'm creating a sitemap in a custom CMS powered by Angular.
I hide the lower levels of pages and toggle their visibility with a button. I add ng-animate to animate the "opening" of the lower levels of the sitemap.
This works fine for the <ul>, but I would rather have its child <li> enter with a longer transition-delay for every item for a nice waterfall effect and this is where I get stuck.
At first I figured simply adding a transition-delay to the <li> would be sufficient, but for whatever reason I'm even unable to add a regular transition to the <li>. I read about the -stagger class, but it never gets applied.
Markup:
<ul>
<li ng-repeat="page in data"
ng-class="{'children-visible': isVisible}"
ng-init="isVisible = false">
{{page.pagename}}
<button ng-if="page.sub"
ng-click="$parent.isVisible = !isVisible">
</button>
<ul ng-if="page.sub"
ng-show="isVisible"
ng-animate="'animate'">
<li ng-repeat="page in page.sub">
{{page.pagename}}
</li>
</ul>
</li>
</ul>
Here's a picture of the markup if it helps you, er, picture it:
If relevant, I use version 1.2.16 of both angular.js and angular-animate.js.
So, in short: How do I add a stagger/transition delay to children of an element with ng-show?

Resources