UI-bootstrap - Add a tab and select it by default - angularjs

I'm trying to make a tab system using ui-bootstrap.
It's nearly fine but I'm still having trouble with the last tab when I add one.
Adding one tab is OK, but if I want to select it automatically once it's created, I've got a weird behaviour :
One tab added : fine
One tab added : not selected
One tab added : fine
One tab added : not selected
and so on ...
I've made a plunkr to demonstrate my bug, just click multiple times on the "+" button and have a look to which tab is selected.
Here's the JS code :
angular.module('ui.bootstrap.demo', ['ngAnimate', 'ui.bootstrap']);
angular.module('ui.bootstrap.demo').controller('TabsDemoCtrl', function($scope) {
$scope.tabs = [{
title: 'Dynamic Title 1',
content: 'Dynamic content 1',
active: false
}, {
title: 'Dynamic Title 2',
content: 'Dynamic content 2',
active: false
}];
$scope.addTab = function() {
$scope.tabs.push({
title: 'Dynamic Title ' + ($scope.tabs.length + 1),
content: 'Dynamic content ' + ($scope.tabs.length + 1)
});
$scope.active = $scope.tabs.length - 1;
};
});
Here's the HTML code :
<div ng-controller="TabsDemoCtrl">
<p>Select a tab by setting active binding to true:</p>
<p>
<button type="button" class="btn btn-default btn-sm" ng-click="active = 1">Select second tab</button>
<button type="button" class="btn btn-default btn-sm" ng-click="active = 2">Select third tab</button>
</p>
<p>
<button type="button" class="btn btn-default btn-sm" ng-click="tabs[1].disabled = ! tabs[1].disabled">Enable / Disable third tab</button>
</p>
<hr />
<uib-tabset active="active">
<uib-tab index="$index" ng-repeat="tab in tabs" heading="{{tab.title}}">
{{tab.content}}
</uib-tab>
</uib-tabset>
<br /><br />
<button ng-click="addTab()">plus</button>
</div>
Any help on this would be nice,
Cheers

You have to use a timeout, uibootstrap doesn't technically support dynamically generated tabs.
$timeout(function() {
$scope.active = $scope.tabs.length - 1;
}, 0);
See this thread.
https://github.com/angular-ui/bootstrap/issues/5656

Related

AngularJS binding to Bootstrap Popover attribute

I'm trying to dynamically populate the data-title and the data-content of a Bootstrap popover from a JSON create in an AngularJS controller.
Controller Snippet:
$scope.popoverContent = {name: {title: "title", content: "content"}}
HTML Snippet:
<span class="glyphicon glyphicon-question-sign"
aria-hidden="true"
data-toggle="popover"
data-trigger="hover"
data-title="{{popoverContent.name.title}}"
data-placement="right"
data-content="{{popoverContent.name.content}}">
</span>
I'm getting the exact text between the double quotes in the HTML page, {{popoverContent.name.title}}.
I've tried with ng-attr-data-title="{{popoverContent.name.title}}" but in this case, the title does not get displayed at all.
Other variables set in the controller are getting displayed properly in the HTML page.
Is is possible to implement something like this?
Try this code
var demo = angular.module('demo', []);
demo.controller('loadData', function($scope){
$scope.uploadData = function() {
$scope.popoverContent = {name: {title: "title", content: "content"}};
};
});
demo.directive("popUps",function(){
return {
restrict:'E',
replace: true,
transclude: false,
template:'<span class="glyphicon glyphicon-question-sign" aria-hidden="true" data-toggle="popover" data-trigger="hover" data-title="{{popoverContent.name.title}}" data-placement="right" data-content="{{popoverContent.name.content}}">data-title:{{popoverContent.name.title}}</br>data-content:{{popoverContent.name.content}}</span>'
};
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.7/angular.min.js"></script>
<div ng-app='demo'>
<div ng-controller='loadData'>
<button ng-click='uploadData($event)' >show</button>
<div>
<pop-ups></pop-ups>
</div>
</div>
</div>

unable to close modal after submitting in angularjs

I am trying to do an update of a form and all is working fine but the modal does not close properly when the update is done. I mean the modal did disappear, but the screen is still dark like the modal is still there and I can't click on anything else. How do I get the page to refresh and the modal to close properly ?
My code is as shown:
$scope.updateStudentParticulars = function(item) {
var currentDate = $filter('date')(new Date(), 'dd/MM/yyyy'); //for lastchangepassword field
$scope.EditStudentForm = false;
//alert(item.User_Key + " USER KEY")
const rootRef = firebase.database().ref();
//zoom in to users table
const ref = rootRef.child('Users');
ref.child(item.User_Key).update({
name: item.Student_Name,
email: item.Student_Email,
role: "student",
accountStatus: "Activated",
yearJoined: item.Year_Joined,
password: item.Password,
passwordChangedDate: currentDate,
gpa: 0.00,
profile: {
address: item.Address,
citizenship: item.Citizenship,
gender: item.Gender,
nok: item.Nok,
nokPhone: item.Nok_Phone,
phone: item.Phone
}
});
alert("Update Successful !")
$route.reload();
}
The modal code is declared in a html file:
<div id="editModal" class="modal fade" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Edit Student Particulars</h4>
</div>
<div class="modal-body">
<div ng-include src="'templates/editStudentForm.html'"></div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
It looks like you are using bootstrap modals. Once you've included the bootstrap JS code, you can call:
$('#editModal').modal('hide');
See http://getbootstrap.com/javascript/

AngularJS + Bootstrap: dropdown list not populating correctly

I could sure use some guidance on this... I've got a simple Bootstrap dropdown list that doesn't seem to be populating properly, whether I use ng-repeat to retrieve the list from the model OR list the items manually.
<div class="row">
<div class="col-md-4 col-md-offset-4">
<div class="input-group-btn">
<button type="button" class="btn btn-info" ng-click="submit()"> {{selectedAction.name}}</button>
<button type="button" class="btn btn-default btn-primary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> <span class="caret"></span></button>
<ul class="dropdown-menu dropdown-menu-right">
<li ng-repeat="action in actions">
{{action.name}}
</li>
</ul>
</div><!-- /btn-group -->
</div><!-- /.col-lg-4 -->
</div><!-- /.row -->
Also, more importantly, the ng-click directive should change the DOM via normal binding, but this doesn't seem to work either.
var DropDownApp = angular.module('DropDownApp', []);
DropDownApp.controller('DropDownCtrl', ['$scope', function($scope) {
$scope.actions = [
{id: 'action1', name: 'Action 1'},
{id: 'action2', name: 'Action 2'},
{id: 'action3', name: 'Action 3'}
];
$scope.selectedAction = $scope.actions[0];
$scope.setAction = function(action) {
$scope.selectedAction = action;
console.log("selected==>", $scope.selectedAction);
$scope.submit();
};
$scope.submit = function() {
console.log($scope.selectedAction.id);
};
}]);
You can see the code behavior here: Plunker
Please note the points below:
Include ui.bootstrap dependancy in app.js to work with Angular ui-bootstrap.
This directive is composed by three parts:
uib-dropdown which transforms a node into a dropdown.
uib-dropdown-toggle which allows the dropdown to be toggled via click. This directive is optional.
uib-dropdown-menu which transforms a node into the popup menu.
Each of these parts need to be used as attribute directives.
Please find the working plunker here: http://plnkr.co/edit/v2uonllub3GsTFUxdFys?p=preview
Cheers!

AngularJS Accordion Expand All Collapse All

I am trying to get the accordions to toggle correctly through the directive ng-click. If I have Item one open how do I get it to expand all the accordions? Item two and Item three will continue to expand and collapse but Item one stays stagnant.
Plunker
alternately you can adjust your buttons so that they just loop through the children.
html:
<div ng-controller="AccordionDemo">
<div >
<div class="stuff_in_the_middle" >
<div ng-repeat="m in results" ng-click="m.open = !m.open" style="margin-bottom:20px">
<div heading="{{m.label}}" is-open="m.open" style="background-color:#d2d2d2; cursor:pointer" >
{{m.label}}
</div>
<div ng-show="m.open" style="padding:10px">
contents
</div>
</div>
<span class="btn btn-default" ng-click="toggle(false)">Collapse All</span>
<span class="btn btn-default" ng-click="toggle(true)">Expand All</span>
</div>
<hr />
</div>
</div>
JS:
var module = angular.module('plunker', []);
module.controller('AccordionDemo', ['$scope',
function ($scope) {
$scope.results = [
{label: 'Item 1', open: false},
{label: 'Item 2', open: false},
{label: 'Item 3', open: false}
];
$scope.toggle = function(state) {
$scope.results.forEach(function(e) {
e.open = state;
});
}
}
]);
see it working here: http://plnkr.co/edit/T6iv7mSoat9SQBwSIFJP
You have a problem with scopes. Simple rule is to never set variable value from ng-click or similar directives if you gonna use this variable outside - in parent.
It is caused by ng-repeat, which creates scope and if you will try to define new variable within it(you are doing it, because you have used name plunker, instead of opened), it will be defined only to current item in repeat.
You can use setter function to set it to right scope. So, here we go: http://plnkr.co/edit/h3MtKywiOaIQhpnAzWLT?p=preview

angular-ui-bootstrap accordion collapse/expand all

I would like to create a collpase/expand all button for a set of accordions. I am using angular.js v1.2.6 and angular-bootstrap-ui 0.9.0. I haven't been able to find an example of how to do a collpase/expand all. I'm an angular novice and any advice or suggestions is appreciated.
ALSO, I should add that the solution in this post doesn't work in the newer version of angular.js (v1.0.8 vs v1.2.6) that I am using (which is a latest version at the time of this posting). In the newer version it throws an error about trying to create two isolated scopes.
Markup:
<div ng-controller="myCtlr">
<accordion close-others="oneAtATime">
<button class="btn" ng-click="section.isCollapsed = !section.isCollapsed">Toggle Sections</button>
<accordion-group ng-repeat="section in sections" is-open="section.isOpen">
<accordion-heading>
<div class="accordion-heading-content" ng:class="{collapsed: section.isOpen}">
{{section.name}}
</div>
</accordion-heading>
Section content
</accordion-group>
</accordion>
</div>
JS:
var theapp = angular.module('myApp', [
'ui.bootstrap'
])
function myCtlr ($scope) {
$scope.isCollapsed = false;
$scope.sections = [
{'id': '353','otherid': '7','name': 'One','Sequence': '1'},
{'id': '354','otherid': '8','name': 'Two','Sequence': '1'},
{'id': '355','otherid': '9','name': 'Three','Sequence': '1'}
];
}
I've taken Blowsie's plunkr comment and built my own answer that solves the use case that I'm reading into here.
I've moved the close-others attribute to the accordion element where the docs say it goes. I've also added extra buttons to openAll, closeAll or toggleAll.
If you click the header for a single item, only that item opens. If you click a 'All' button, all are affected.
Thanks to Blowsie for the inspiration. I think using the item.open here was the ticket. After that, it's just a matter of affecting all item.open values.
http://plnkr.co/edit/WUKEfcBrSf3XrIQAik67?p=preview
HTML
<div ng-controller="AccordionDemoCtrl">
<accordion close-others="false">
<accordion-group ng-repeat="item in items" is-open="item.open" heading="{{item.name}}">
{{item.open}}
<p>The body of the accordion group grows to fit the contents</p>
</accordion-group>
</accordion>
<button ng-click="openItem(0)">Open 1</button>
<button ng-click="openItem(1)">Open 2</button>
<button ng-click="openItem(2)">Open 3</button>
<button ng-click="openAllItems()">Open All</button>
<button ng-click="closeAllItems()">Close All</button>
<button ng-click="toggleAllItems()">Toggle All</button>
<br/>
{{items |json}}
</div>
JS
angular.module('plunker', ['ui.bootstrap']);
function AccordionDemoCtrl($scope) {
$scope.oneAtATime = true;
$scope.items = [
{name: 'Item 1', open: false},
{name: 'Item 2', open: false},
{name: 'Item 3', open: false}
];
$scope.addItem = function() {
var newItemNo = $scope.items.length + 1;
$scope.items.push('Item ' + newItemNo);
};
$scope.openItem = function(idx) {
console.log(idx);
$scope.items[idx].open = true;
};
$scope.openAllItems = function(){
$scope.items.map(function(item){
item.open = true;
});
};
$scope.closeAllItems = function(){
$scope.items.map(function(item){
item.open = false;
});
}
$scope.toggleAllItems = function(){
$scope.items.map(function(item){
item.open = !item.open;
});
}
}
Here is a method using the is-open attribute.
http://plnkr.co/edit/MliW41xGJAF0Mnw4Rgu7?p=preview

Resources