controlling isOpen in angular ui bootstrap - angularjs

I would like use isOpen attributes in angualr ui bootstrap accordion directive so it would open the first element of the first ng-repeat in the accordion. I have tried few things with no luck. can anyone advise on this?
//html
<div ng-show="accordionCtrl.isNotString(value);" class="accordionContainer" ng-repeat="(key, value) in accordionCtrl.lessons">
<div class="accordionStepBox">
<h4 class="accordionStepTitle">Step {{$index+1}}: {{value.title}}</h4>
<span>Summary: {{value.summary}}</span>
</div>
<div class="accordionCoursesBox">
<div class="accordionCoursesText">Courses</div>
<!-- accordion for suffles -->
<uib-accordion close-others="accordionCtrl.oneAtATime">
<!-- only give accordion to object vals -->
<div class="accordion" ng-show="accordionCtrl.isNotString(value);" ng-repeat="(key, value) in value">
<!-- <uib-accordion-group heading="{{value.title}}" is-open="accordionCtrl.firstIndex($index)"> -->
<uib-accordion-group heading="{{value.title}}">
<div ng-repeat="(key, value) in value">
<div ng-show="accordionCtrl.isNotString(value);" class="accordionSuffleBox">
{{$index+1}}. {{value.title}}
</div>
</div>
<br/>
<button ui-sref="lesson" class="btn btn-default accordionbutton">Start</button>
</uib-accordion-group>
</div>
</uib-accordion>
</div>
</div>
//controller
angular
.module('neuralquestApp')
.controller('AccordionCtrl', AccordionCtrl);
function AccordionCtrl(FirebaseUrl, $firebaseObject, $firebaseArray) {
var accordionCtrl = this;
var getLessons = getLessons;
accordionCtrl.oneAtATime = true;
accordionCtrl.init = init;
accordionCtrl.init();
accordionCtrl.isNotString = isNotString;
accordionCtrl.firstIndex = firstIndex;
/*======================================
= IMPLEMENTATION =
======================================*/
function init() {
getLessons();
}
function firstIndex(index) {
if(index === 0){
return true;
} else {
return false;
}
}
function getLessons() {
var ref = new Firebase(FirebaseUrl);
accordionCtrl.lessons = $firebaseObject(ref.child('NeuralNetwork'));
}
function isNotString(val) {
// console.log('val', val);
if(typeof val === "string"){
console.log('is string', val);
return false;
} else {
return true;
}
}
}

The is-open attribute is setup for 2 way binding with the controller, so you could do something like so:
<div ng-controller="AccordionDemoCtrl">
<uib-accordion>
<div ng-repeat="group in groups">
<uib-accordion-group heading="{{group.title}}" is-open="openIndex[$index]">
{{group.content}}
</uib-accordion-group>
</div>
</uib-accordion>
</div>
angular.module('ui.bootstrap.demo').controller('AccordionDemoCtrl', function ($scope) {
$scope.openIndex = [true];
$scope.groups = [
{
title: 'Group Header - 1',
content: 'Group Body - 1'
},
{
title: 'Group Header - 2',
content: 'Group Body - 2'
},
{
title: 'Group Header - 3',
content: 'Group Body - 3'
},
{
title: 'Group Header - 4',
content: 'Group Body - 4'
}
];
});
Example plunk. Also, the close-others attribute default value is true, so you don't need to explicitly set that to true.

Related

Using the same ng-click in different classes

So the thing is:
I have four cards and I have a ng-click on the first one with a function named OpenCard().
When I click, it shows its hidden content.
I wanna do the same for the rest of the cards, using the same call to OpenCard().
My four classes have the same name "rowCont" and the hidden content inside that "rowCont" is different:
<div class="rowCont" ng-click="OpenCard()" ng-class="{'active': isActive}">
<div class="hiddenContent">
<div class="animate-show" ng-show="cardVisible">
</div>
</div>
</div>
$scope.isActive = false;
$scope.OpenCard = function () {
if($scope.isActive == false) {
$scope.isActive = true;
$scope.cardVisible = true;
} else {
$scope.isActive = false;
$scope.cardVisible = false;
}
}
I'm using Angular 1.6.0
Do you have an idea how can I refer to one card in specific using the same function on ng-click? Cause when I click one in one closed card it shows the content of all cards.
<div class="row">
ng-repeat="x in current_tab
ng-class="{active1 : activeMenu === x}"
ng-click="setActive(x);"> {{x.userId}}
</div>
$scope.menuItems = $rootScope.current_tab;
$scope.activeMenu = $scope.menuItems[0];
$scope.setActive = function(menuItem) {
$scope.activeMenu = menuItem
}
var app = angular.module("ngClickApp", []);
app.controller('ngClickCtrl', ['$scope', function ($scope) {
$scope.cards = [{
isActive: false,
title: '1',
content: 'content 1'
}, {
isActive: false,
title: '2',
content: 'content 2'
}];
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<html ng-app="ngClickApp">
<head>
<title>Validation messages</title>
</head>
<body ng-controller="ngClickCtrl">
<div class="rowCont" ng-repeat="card in cards track by $index" ng-click="card.isActive=!card.isActive" ng-class="{'active': c.isActive}">
card {{$index}}
<div class="hiddenContent">
<div class="animate-show" ng-show="card.isActive">
{{card.content}}
</div>
</div>
</div>
</body>
</html>
You can store card's visibility in an array ($scope.cardsVisible = [];), and pass an index in each call to OpenCard(cardIndex).
Then, display it conditionnaly in your view:
var myApp = angular.module('myApp', []);
function MyCtrl($scope) {
$scope.cardsVisible = [];
$scope.OpenCard = function(cardIndex) {
$scope.cardsVisible[cardIndex] = true;
$scope.isActive = cardIndex;
}
}
.active {
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MyCtrl">
<div ng-click="OpenCard(1)" ng-class="{'active': isActive == 1}">
Card 1
<div ng-show="cardsVisible[1]">
This card is visible
</div>
</div>
<div ng-click="OpenCard(2)" ng-class="{'active': isActive == 2}">
Card 2
<div ng-show="cardsVisible[2]">
This card is visible
</div>
</div>
</div>

AngularJS - Go to previous/next modal

I am building an application with angular where I have a list of items (using ng-repeat), and by clicking on each item I can open a modal in order to see a more detailed description.
Right now in order to switch to another modal I have to close the previous one, go to the list, and click to open another modal. I would like to go directly to the previous/next modal when clicking the previous/next button. I have made an example of what I want to achieve.
Here is the html:
<div ng-app="myApp" ng-controller="myCtrl">
<ul>
<li ng-repeat="t in turtles">
{{t.name}} - {{t.weapon}}
<a ng-click="show = !show">Show more</a>
<div class="modal" ng-show="show">
<div class="close" ng-click="show = !show">X</div>
{{t.name}} likes to eat {{t.food}} with his {{t.weapon}}!
<div class="previous">Previous</div>
<div class="next">Next</div>
</div>
</li>
</ul>
</div>
And the controller:
var app = angular.module('myApp', []);
app.controller('myCtrl', function ($scope) {
$scope.turtles = [
{ name: "Michellangelo", weapon: "nunchaku", food:"pizza" },
{ name: "Donatello", weapon: "bo", food:"pizza" },
{ name: "Leonardo", weapon: "katana", food:"turtle soup" },
{ name: "Rafael", weapon: "sai", food:"pizza" }
];
$scope.show=false;
});
You can see a working Jsfiddle here
Here is a working solution: http://jsfiddle.net/s7gc81zz/5/
Instead of relying on a single variable to show or hide the modals, you can add a show attribute to each turtle, and use the $index variable of ngRepeat to reference your position in the array:
<div ng-app="myApp" ng-controller="myCtrl">
<ul>
<li ng-repeat="t in turtles">
{{t.name}} - {{t.weapon}}
<a ng-click="showMore(t)">Show more</a>
<div class="modal" ng-show="t.show">
<div class="close" ng-click="hideMore(t)">X</div>
{{t.name}} likes to eat {{t.food}} with his {{t.weapon}}!
<div class="previous" ng-click="showPrevious(t, $index)>Previous</div>
<div class="next" ng-click="showNext(t, $index)">Next</div>
</div>
</li>
</ul>
</div>
Now you use scope functions to handle the logic of the next button:
var app = angular.module('myApp', []);
app.controller('myCtrl', function ($scope) {
$scope.turtles = [
{ name: "Michellangelo", weapon: "nunchaku", food:"pizza" },
{ name: "Donatello", weapon: "bo", food:"pizza" },
{ name: "Leonardo", weapon: "katana", food:"turtle soup" },
{ name: "Rafael", weapon: "sai", food:"pizza" }
];
//$scope.show=false;
$scope.showMore = function(turtle) {
turtle.show = true;
};
$scope.hideMore = function(turtle) {
turtle.show = false;
};
$scope.showNext = function(turtle, index) {
if((index+1) > ($scope.turtles.length - 1)) {
return;
}
else {
turtle.show = false;
$scope.turtles[index+1].show = true;
}
};
$scope.showPrevious = function(turtle, index) {
if((index-1) < 0) {
return;
}
else {
turtle.show = false;
$scope.turtles[index-1].show = true;
}
};
});
If you want to create a navigation in the modal from next and previous buttons, then instead of having one show flag, you should have a flag on each object of the displaying array i.e turtles. And based on current looping object of ng-repeat you can then hide/ show appropriate item on next and previous buttons based on $index +1 & -1 respectively.
Here is the working Fiddle Code :
http://jsfiddle.net/ashwani121/4fa6a9pr/
var app = angular.module('myApp', []);
app.controller('myCtrl', function ($scope) {
$scope.turtles = [
{ name: "Michellangelo", weapon: "nunchaku", food:"pizza" },
{ name: "Donatello", weapon: "bo", food:"pizza" },
{ name: "Leonardo", weapon: "katana", food:"turtle soup" },
{ name: "Rafael", weapon: "sai", food:"pizza" }
];
$scope.show=false;
var prevObj = null;
$scope.showModal = function(obj){
if(prevObj && prevObj.selected)
{
prevObj.selected = false;
}
obj['selected'] = true;
prevObj = obj;
}
$scope.navModal = function(index){
if(index > 0 && index < $scope.turtles.length)
$scope.showModal($scope.turtles[index]);
}
});
<div ng-app="myApp" ng-controller="myCtrl">
<ul>
<li ng-repeat="t in turtles">
{{t.name}} - {{t.weapon}}
<a ng-click="showModal(t)">Show more</a>
<div class="modal" ng-show="t.selected">
<div class="close" ng-click="show = !show">X</div>
{{t.name}} likes to eat {{t.food}} with his {{t.weapon}}!
<div class="previous" ng-click="navModal($index-1)">Previous</div>
<div class="next" ng-click="navModal($index+1)">Next</div>
</div>
</li>
</ul>
</div>
You can use an index variable to keep track of the ninja turtle you have to show currently.
BTW you are creating unnecessary model/popup's because you only need one and you don't need a model for each of the ninja turtle :) so it is better to have only one model popup.
You can move to the next and previous ninja turtle by using the index variable you will be storing and updating it accordingly on the $scope object.
Check the code below, here the updated jsfiddle
<div ng-app="myApp" ng-controller="myCtrl">
<ul>
<li ng-repeat="t in turtles">
{{t.name}} - {{t.weapon}}
<a ng-click="showPopup($index)">Show more</a>
</li>
</ul>
<div class="modal" ng-show="show">
<div class="close" ng-click="closePopup()">X</div>
{{selectedTurtle.name}} likes to eat {{selectedTurtle.food}} with his {{selectedTurtle.weapon}}!
<div class="previous" ng-click="prev()">Previous</div>
<div class="next" ng-click="next()">Next</div>
</div>
</div>
angular
.module('myApp', [])
.controller('myCtrl', ['$scope', function ($scope) {
$scope.index = 0;
$scope.selectedTurtle = {};
$scope.turtles = [
{ name: "Michellangelo", weapon: "nunchaku", food:"pizza" },
{ name: "Donatello", weapon: "bo", food:"pizza" },
{ name: "Leonardo", weapon: "katana", food:"turtle soup" },
{ name: "Rafael", weapon: "sai", food:"pizza" }
];
$scope.show = false;
$scope.showPopup = showPopup;
$scope.closePopup = closePopup;
$scope.next = next;
$scope.prev = prev;
function setTurtle(index) {
$scope.selectedTurtle = $scope.turtles[index];
}
function showPopup(index) {
$scope.index = index;
setTurtle($scope.index);
$scope.show = true;
}
function closePopup() {
$scope.show = false;
}
function next() {
if ($scope.index !== $scope.turtles.length - 1) {
$scope.index++;
setTurtle($scope.index);
}
}
function prev() {
if ($scope.index !== 0) {
$scope.index--;
setTurtle($scope.index);
}
}
}]);
as you maybe already noticed ng-show just add/remove a css class. So based on this, you should give an ID to your DIVs, maybe using the internal var $index from the ng-repeat directive, for example id="card-{{$index}}". Having identified your DIVs and with a little jquery help (it also can be done with just plain js) you can identify the active card, check its ID, calculate the next or previous ID value, and add or remove any particular css class you need.
Or you can just look for an angular carousel ;)

Angular unselect item in all selected items

Below is my code. When user clicks on "select all" all items get selected.
what I want is when user click on any option that option should be disabled.
var app = angular.module('sampleApp', []);
app.controller('sampleController', ['$scope',
function($scope) {
$scope.selectAll = false;
}
])
.disabled {
opacity: 0.5
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="sampleApp">
<div ng-controller="sampleController">
<label ng-click="selectAll = !selectAll">Select all</label>
<div ng-class="selectAll ? 'enable' : 'disabled'">Option 1</div>
<div ng-class="selectAll ? 'enable' : 'disabled'">Option 2</div>
<div ng-class="selectAll ? 'enable' : 'disabled'">Option 3</div>
<div ng-class="selectAll ? 'enable' : 'disabled'">Option 4</div>
</div>
</div>
You need to wrap each item into a new object and place a field 'selected' on this object:
var app = angular.module('sampleApp', []);
app.controller('sampleController', ['$scope',
function($scope) {
$scope.options = [{
selected: false,
item: 'option 1'
}, {
selected: false,
item: 'option 2'
}, {
selected: false,
item: 'option 3'
}]
$scope.selectAll = function(select) {
angular.forEach($scope.options, function(o) {
o.selected = select;
});
};
}
])
.disabled {
opacity: 0.5
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="sampleApp">
<div ng-controller="sampleController">
<label ng-click="selectAll(true)">Select all</label>
<label ng-click="selectAll(false)">Deselect all</label>
<div ng-repeat="option in options" ng-class="{'disabled': !option.selected}" ng-click="option.selected = !option.selected">{{option.item}}</div>
</div>
</div>

angularjs - ng-show not working with ng-repeat

I have a variable set to true in ng-click but the div underneath is not displaying. I've followed this post but it looks like it doesnt work in maybe ng-repeat? Here's the plunker: http://plnkr.co/edit/90G1KAx9Fmf2SgRs5gYK?p=preview
angular.module('myAppApp', [])
.controller('MainCtrl', function ($scope) {
$scope.notes = [{
id: 1,
label: 'First Note',
done: false,
someRandom: 31431
}, {
id: 2,
label: 'Second Note',
done: false
}, {
id: 3,
label: 'Finished Third Note',
done: true
}];
$scope.reach= function (id) {
//the assignment below works
//$scope.flag = true;
alert("hello there");
};
});
<div ng-app="myAppApp">
<div ng-controller="MainCtrl">
<div ng-repeat="note in notes">
{{note.id}} - {{note.label}} -
click me
</div>
<div class="row" id="" ng-show="flag">I'm Here</div>
</div>
</div>
It should be ng-click="$parent.flag = true;reach(111);"
click me
Outside ng-repeat
You question is unclear, you could use ng-repeat inside ng-repeat, by maintaining variable in ng-repeat parent scope. and access parent scope using $parent. annotation inside ng-repeat
<div ng-repeat="note in notes">
{{note.id}} - {{note.label}} -
click me
<div class="row" id="" ng-show="$parent.selected == note.id">I'm Here</div>
</div>
</div>
Inside ng-repeat
I would advise you to use ng-init
<div ng-repeat="note in notes" ng-init="parent=$parent">
and after that
click me
Please see demo below
angular.module('myAppApp', [])
.controller('MainCtrl', function($scope) {
$scope.notes = [{
id: 1,
label: 'First Note',
done: false,
someRandom: 31431
}, {
id: 2,
label: 'Second Note',
done: false
}, {
id: 3,
label: 'Finished Third Note',
done: true
}];
$scope.reach = function(id) {
//$scope.flag = true;
alert("hello there");
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body>
<div ng-app="myAppApp">
<div ng-controller="MainCtrl">
<div ng-repeat="note in notes" ng-init="parent=$parent">
{{note.id}} - {{note.label}} -
click me
</div>
<div class="row" id="" ng-show="flag">I'm Here</div>
</div>
</div>
</body>

$first in ngRepeat

I have an array $scope.items.
I want if the item is the $first one of the ngRepeat to add the css class in.
Is it something that can be done with angular? Generally how can I handle the booleans in Ajs?
<div ng-repeat="item in items">
<div class='' > {{item.title}}</div>
</div>
It should be
<div ng-repeat="item in items">
<div ng-class='{in:$first}' > {{item.title}}</div>
</div>
Look at ng-class directive in http://docs.angularjs.org/api/ng.directive:ngClass and in this thread What is the best way to conditionally apply a class?
You can try approach with method invocation.
HTML
<div ng-controller = "fessCntrl">
<div ng-repeat="item in items">
<div ng-class='rowClass(item, $index)' > {{item.title}}</div>
</div>
</div>
JS
var fessmodule = angular.module('myModule', []);
fessmodule.controller('fessCntrl', function ($scope) {
$scope.items = [
{title: 'myTitle1', value: 'value1'},
{title: 'myTitle2', value: 'value2'},
{title: 'myTitle3', value: 'value1'},
{title: 'myTitle4', value: 'value2'},
{title: 'myTitle5', value: 'value1'}
];
$scope.rowClass = function(item, index){
if(index == 0){
return item.value;
}
return '';
};
});
fessmodule.$inject = ['$scope'];
Demo Fiddle

Resources