Can't navigate through drop-down menu if using ng-repeat - angularjs

I have this drop-down menu that I populate using ng-repeat:
<div class="btn-group btn-xs" dropdown keyboard-nav>
<input id="simple-btn-keyboard-nav" ng-model="available_fields_query" id="single-button" dropdown-toggle ng-disabled="disabled" placeholder="Add New Field">
</input>
<ul class="dropdown-menu" role="menu" aria-labelledby="simple-btn-keyboard-nav">
<li ng-repeat="item in availableFields">
<a ng-click="addField(item)" role="menuitem">{{item}}</a>
</li>
</ul>
</div>
And I supposed to be able to navigate through it with kb arrows, but for some reason I can't focus it with tab or arrows.
But If I manually do something like this:
<div class="btn-group" dropdown dropdown-append-to-body>
<button id="btn-append-to-body" type="button" class="btn btn-primary" dropdown-toggle>
Dropdown on Body <span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu" aria-labelledby="btn-append-to-body">
<li role="menuitem">Action</li>
<li role="menuitem">Another action</li>
<li role="menuitem">Something else here</li>
<li class="divider"></li>
<li role="menuitem">Separated link</li>
</ul>
</div>
It works fine, and I can target fields in a dropdown with my keyboard.
Why this is happening and how can I fix it?
$scope.addField = function (value) {
$scope.state_from_editor.fields.push(value);
};

Well it wasn't working because <a> attribute was missing href parameter, as soon as I added href="#" it started to work.

Related

dropdown-toggle up and down keys in keyboard not working

I am unable to use up and down arrow buttons to focus on the drop down menu.
In my application, we are using angularjs.
Here is my code:
<div class="dropdown dropdown-eq2 form-group" dropdown>
<button class="btn dropdown-toggle" dropdown-toggle data-toggle="dropdown">
<span class="icon-e_icon_expand pull-right" style="margin-left: 5px;"> </span>{{personObj.type}}
</button>
<ul class="dropdown-menu num-of-views" role="menu" dropdown-menu>
<li role="presentation" ng-repeat="type in categoryArray">
<a role="menuitem" tabindex="-1" href="" ng-click="setSelectedType(type)"> {{type}}</a>
</li>
</ul>
</div>
Angular UI dropdown don't support UP/DOWN keyboard navigation's.
You can build custom directive on top of this will full fill your requirement.
You can refer this link Navigate the UI using keyboard

Angular UI dropdown z-index in modal

In this plunk I have an Angular UI modal with a dropdown. The dropdown has the uib-dropdown dropdown-append-to-body directives to show the complete list even though it's in a div with overflow:hidden.
If you click on the button, you will see that the dropdown list is behind the modal. How to fix the z-index?
HTML
<button ng-click="openModal()">Open modal</button>
<script type="text/ng-template" id="myModalContent.html">
<div class="modal-header">
<h4 class="modal-title">The Title</h4>
</div>
<div style="background-color:orange;overflow-y:hidden;height:30px">
<div class="btn-group" uib-dropdown dropdown-append-to-body>
<button id="btn-append-to-body" type="button" class="btn btn-primary" uib-dropdown-toggle="">
Dropdown on Body <span class="caret"></span>
</button>
<ul class="dropdown-menu" uib-dropdown-menu="" role="menu" aria-labelledby="btn-append-to-body">
<li role="menuitem">
Action
</li>
<li role="menuitem">
Another action
</li>
<li role="menuitem">
Something else here
</li>
<li class="divider"></li>
<li role="menuitem">
Separated link
</li>
</ul>
</div>
</div>
</script>
Javascript
var app = angular.module('app', ['ui.bootstrap']);
app.controller('ctl', function ($scope,$uibModal) {
$scope.openModal = function() {
$scope.modalInstance = $uibModal.open({
templateUrl: 'myModalContent.html',
scope: $scope
});
};
});
Add this class to your CSS file
.dropdown-menu.model-top{
z-index:39999;
}
HTML
<ul class="dropdown-menu model-top" uib-dropdown-menu="" role="menu" aria-labelledby="btn-append-to-body"></ul>
NB: inline CSS not work, the are replacing the style attribute with their own styles, like position, height
use z-index like this:
<div class="btn-group" uib-dropdown dropdown-append-to-body>
<button id="btn-append-to-body" type="button"
class="btn btn-primary" uib-dropdown-toggle>
Dropdown on Body <span class="caret"></span>
</button>
<ul class="dropdown-menu" uib-dropdown-menu role="menu"
aria-labelledby="btn-append-to-body"
style="z-index:39999">
<li role="menuitem">Action</li>
<li role="menuitem">Another action</li>
<li role="menuitem">Something else here</li>
<li class="divider"></li>
<li role="menuitem">Separated link</li>
</ul>
</div>

AngularJS partial view ng-scope class not being added

The following is the partial view that I'm using. Somehow the 'ng-scope' class is not added automatically to every HTML tag. Could someone tell me what might be the cause of this? I know angular.js adds class conditionally but I don't know how to fix this.
<div class="my-photo-header">
<div class="container">
<a class="navbar-brand my-navbar-brand">
<span class="glyphicon glyphicon-pencil"></span>
</a>
<form class="navbar-form my-navbar-form navbar-left" role="search">
<div>
<input id="photo-title" type="text" class="form-control" placeholder="Untitled"
title="Edit your photo title here." value="TITLE">
</div>
</form>
<ul id="photo-title-header" class="nav nav-tabs">
<li role="presentation" class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
File <span class="caret"></span>
</a>
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
<li>
<a>Save</a>
</li>
<li>
<a ng-click="vm.haha()">Upload</a>
<input type="file" upload-image="uploadImage"/>
</li>
<li><a>Open</a></li>
<li><a>Invite</a></li>
<li role="separator" class="divider"></li>
<li><a>Export as<span class="caret"></span></a></li>
<li><a>Print</a></li>
</ul>
</li>
<!-- Please change TODO to display the number, and maybe change style to not be a tab -->
<li role="listitem"><a>{{TODO}} revisions</a></li>
<li>Logout</li>
</ul>
</div>
</div>

Can't add more than one Bootstrap dropdown

I have a SPA that implements modals. I'm trying to create dropdowns for certain elements that have modals attached to them. I want each dropdown to display a list of commands, and then a "link" to the modal. I can implement the modals just fine. The problem is with the dropdowns. The page works fine when I implement the first dropdown, but when I try to implement the second dropdown, neither of them work. I set the data-target attribute to see if that changed anything, but I am either not using it correctly or it's not part of the solution. Any ideas?
<div class="row cluster" ng-repeat="cluster in clusterCtrl.clusters">
<!-- this dropdown breaks the other one -->
<div class="btn-group" dropdown is-open="status.isopen" data-target="#cluster">
<h4 id="cluster" class="pointer dropdown-toggle" dropdown-toggle ng-disabled="disabled">
{{cluster.name}}
</h4>
<ul class="dropdown-menu" role="menu">
<li role="menuitem">Status</li>
<li role="menuitem">Start<li>
<li role="menuitem">Stop</li>
<li class="divider"></li>
<li role="menuitem"><a class="pointer" ng-click="openCluster()">Details</a></li>
</ul>
</div>
<!-- -->
<div class="col-lg-4">
<!-- START INSTANCE DISPLAY -->
<div class="row">
<div class="col-xs-1 instance" ng-repeat="instance in instanceCtrl.instances">
<div class="btn-group" dropdown is-open="status.isopen" data-target="#instance">
<h6 id="instance" class="pointer dropdown-toggle" dropdown-toggle ng-disabled="disabled">
{{instance.name}}
</h6>
<ul class="dropdown-menu" role="menu" aria-labelledby="single-button">
<li role="menuitem">Status</li>
<li role="menuitem">Start<li>
<li role="menuitem">Stop</li>
<li class="divider"></li>
<li role="menuitem"><a class="pointer" ng-click="openInstance()">Details</a></li>
</ul>
</div>
</div>
</div>
<!-- END INSTANCE DISPLAY -->
</div>
</div>
The data-target attribute is not needed. The problem lies in dropdown is-open="status.isopen". This is a unique attribute. To fix it, you need to write a new controller for your dropdown. Be sure not to name it DropdownController since that it an internal control to Bootstrap.
dropdown-controller.js
(function() {
angular
.module('MyApp')
.controller('DropdownCtrl', function($scope) {
$scope.status = {
isClusterOpen: false,
isInstanceOpen: false,
};
$scope.toggled = function(open) {
console.log('Dropdown is now: ', open);
};
$scope.toggleDropdown = function($event) {
$event.preventDefault();
$event.stopPropagation();
$scope.status.isClusterOpen = !$scope.status.isClusterOpen;
$scope.status.isInstanceOpen = !$scope.status.isInstanceOpen;
};
});
})();
index.html
<div class="row cluster" ng-repeat="cluster in clusterCtrl.clusters">
<!-- Changed -->
<div class="btn-group" dropdown is-cluster-open="status.isClusterOpen" >
<!-- -->
<h4 id="cluster" class="pointer dropdown-toggle" dropdown-toggle ng-disabled="disabled">
{{cluster.name}}
</h4>
<ul class="dropdown-menu" role="menu">
<li role="menuitem">Status</li>
<li role="menuitem">Start<li>
<li role="menuitem">Stop</li>
<li class="divider"></li>
<li role="menuitem"><a class="pointer" ng-click="openCluster()">Details</a></li>
</ul>
</div>
<div class="col-lg-4">
<!-- START INSTANCE DISPLAY -->
<div class="row">
<div class="col-xs-1 instance" ng-repeat="instance in instanceCtrl.instances">
<!-- Changed -->
<div class="btn-group" dropdown is-instance-open="status.isInstanceOpen">
<!-- -->
<h6 id="instance" class="pointer dropdown-toggle" dropdown-toggle ng-disabled="disabled">
{{instance.name}}
</h6>
<ul class="dropdown-menu" role="menu" aria-labelledby="single-button">
<li role="menuitem">Status</li>
<li role="menuitem">Start<li>
<li role="menuitem">Stop</li>
<li class="divider"></li>
<li role="menuitem"><a class="pointer" ng-click="openInstance()">Details</a></li>
</ul>
</div>
</div>
</div>
<!-- END INSTANCE DISPLAY -->
</div>
</div>

Applying Angular Bootstrap Drop Down Example

I want to bring drop downs into my project and I took the code from the example. The drop down appears as in the example but when I click it nothing happens.
<form class="form" name="form" novalidate>
<div class="btn-group" dropdown is-open="status.isopen">
<button type="button"
class="btn btn-primary dropdown-toggle"
dropdown-toggle
ng-disabled="disabled">
Button dropdown <span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">
<li>Action</li>
<li>Another action</li>
<li>Something else here</li>
<li class="divider"></li>
<li>Separated link</li>
</ul>
</div>
<div>
</form>
Now the controller for this html:
angular.module('startupApp').controller('DropdownCtrl', function ($scope, $log) {
$scope.items = [
'The first choice!',
'And another choice for you.',
'but wait! A third!'
];
$scope.status = {
isopen: false
};
$scope.toggled = function(open) {
$log.log('Dropdown is now: ', open);
};
$scope.toggleDropdown = function($event) {
$event.preventDefault();
$event.stopPropagation();
$scope.status.isopen = !$scope.status.isopen;
};
});
I had the same problem and I solved by deleting the line dropdown-toggle
I don't know what the problem is but it works well in this way
Here what I did:
This si the original example:
<!-- Single button -->
<div class="btn-group" dropdown is-open="status.isopen">
<button type="button" class="btn btn-primary dropdown-toggle" dropdown-toggle ng-disabled="disabled">
Button dropdown <span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">
<li>Action</li>
<li>Another action</li>
<li>Something else here</li>
<li class="divider"></li>
<li>Separated link</li>
</ul>
</div>
and this is the code without dropdown-toggle
<!-- Single button -->
<div class="btn-group" dropdown is-open="status.isopen">
<button type="button" class="btn btn-primary dropdown-toggle" ng-disabled="disabled">
Button dropdown <span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">
<li>Action</li>
<li>Another action</li>
<li>Something else here</li>
<li class="divider"></li>
<li>Separated link</li>
</ul>
</div>
Edit:
The above example works if you are using angular-ui-bootstrap Version: 0.10.0
Now I've changed the ui-bootstrap using this
<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.12.0.js"></script>
And now all work like a charm
There are a few problems in your code:
Your HTML is not valid, the last <div> tag shouldn't be there
<form class="form" name="form" novalidate>
<div class="btn-group" dropdown is-open="status.isopen">
<button type="button"
class="btn btn-primary dropdown-toggle"
dropdown-toggle
ng-disabled="disabled">
Button dropdown <span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">
<li>
Action
</li>
<li>
Another action
</li>
<li>
Something else here
</li>
<li class="divider"></li>
<li>
Separated link
</li>
</ul>
</div>
</form>
You did not reference ui.bootstrap as a module dependency
angular.module('startupApp', [
'ui.bootstrap'
])
Did you include the right files ?
AngularJS
Angular UI Bootstrap
Bootstrap CSS
You don't need anything special in your controller, the dropdown and dropdown-toggle directives are self-sufficient.
JsFiddle Demo
After much struggle I just found the answer that worked for my case. I only needed to add parse-angular to my angular.module('myapp'['parse-angular']).
First I want to say thank you to Jorge Casariego for his answer. His answer helped me to get much further.
There was one problem at the end though, that neither $scope.toggled = function(open) {...} nor $scope.toggleDropdown = function($event) {...} where called when someone interacted with the Dropdown (see example of them here). After looking into the ui-bootstrap-tpls-0.10.0.js code I had to further adjust the html-code:
the attribute dropdown should be a class-value not a attribute itself.
is-open=... is not needed, ui-bootstrap will take care of it
attach a ng-click to the <a> element in the list.
This did not work for me (dropdown as an attribute):
<!-- Single button -->
<div class="btn-group" dropdown is-open="status.isopen">
<button type="button" class="btn btn-primary dropdown-toggle"
ng-disabled="disabled">
Choose category <span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">
<li ng-repeat="category in interactions">
<a ng-click="toggleDropdown($event)" data-category="{{category.name}}">
{{category.displayName}}
</a>
</li>
</ul>
</div>
But this did (add dropdown as a class value):
<!-- Single button -->
<div class="btn-group dropdown">
<button type="button" class="btn btn-primary dropdown-toggle"
ng-disabled="disabled">
Choose category <span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">
<li ng-repeat="category in interactions">
<a ng-click="toggleDropdown($event)" data-category="{{category.name}}">
{{category.displayName}}
</a>
</li>
</ul>
</div>
The rest of my Angular App looks like this then:
$scope.toggleDropdown = function($event) {
$event.preventDefault();
console.log('This is your event now: ', $event);
};
I know there are newer versions available of angular-ui-bootstrap, but for the record I put it up here. It works with version 0.10.0.

Resources