How to handle selected/unselected ng-class to manage a tabbed popover - angularjs

My code is as follows (the fiddle):
<div ng-controller="myCtrl">
<div ng-model="currentTab" ng-init="currentTab='Tab1'"/>
<div ng-init="popovers = [
{ name: 'Popover1',
displayName: 'Pop over with two tabs',
tabs: [
{ name: 'Tab1',
displayName: 'First tab',
description: ['First tab description']
},
{ name: 'Tab2',
displayName: 'Second tab',
description: ['Second tab description']
}
]
}
]"/>
<b>Tabs in popover</b>
<div
class="popover"
ng-repeat="p in popovers"
>
Popover name: {{p.displayName}}
<div ng-repeat="t in p.tabs"
class="tab"
ng-class="currentTab==t.name?'selected':''"
ng-click="currentTab=t.name"
>
{{t.name}}
</div>
<div ng-repeat="t in p.tabs"
class="tabContent"
ng-class="currentTab==t.name?'selected':''"
>
<p>{{t.displayName}}</p>
</div>
</div>
</div>
There is something I don't get which make the code not working perfectly, as the selected class name is never removed as one click on the tab.

When you want to modify a variable of your parent scope from within a ng-repeat you need to use $parent.currentTab.
Updated Fiddle

Related

How to make expand and collapse manually child wise in angularjs

I have an accordion expand is working fine but collapse is not working,it should work like accordion,for ex when I click 'title 2' its content should expand and 'title 1' content should collapse.below is my code,I am new to angularjs.Anyone can help me.If its in jquery also fine.
HTML
<link rel='stylesheet prefetch' href='https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/css/bootstrap.css'>
<body ng-app="app">
<h1>Dynamic accordion: nested lists with html markup</h1>
<div ng-controller="AccordionDemoCtrl">
<div>
<div ng-repeat="group in groups">
<div class="parents" ng-click="item=1"><i class="glyphicon-plus"></i> {{ group.title }}
</div>
{{ group.content }}
<ul class="childs" ng-show="item==1">
<li ng-repeat="item in group.list">
<span ng-bind-html="item"></span>
</li>
</ul>
</div>
</div>
</div>
</body>
<script src='https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.1/angular.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/angular-filter/0.5.4/angular-filter.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.1/angular-sanitize.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/2.5.0/ui-bootstrap-tpls.js'></script>
<script src="js/index.js"></script>
index.js
angular.module('app', ['ui.bootstrap','ngSanitize','angular.filter']);
angular.module('app').controller('AccordionDemoCtrl', function ($scope) {
$scope.oneAtATime = true;
$scope.groups = [
{
title: 'title 1',
isOpen: true,
list: ['<i>item1a</i> blah blah',
'item2a',
'item3a']
},
{
title: 'title 2',
list: ['item1b',
'<b>item2b </b> blah ',
'item3b']
},
{
title: 'title 3',
},
{
title: 'title 4',
},
{
title: 'title 5',
}
];
});
I suggest you those functions :
$scope.open = function (index) {
$scope.groups[index].isOpen = !$scope.groups[index].isOpen;
$scope.closeOthers(index);
}
$scope.closeOthers = function (index) {
for(var i = 0; i < $scope.groups.length; i++) {
if (i !== index)
$scope.groups[i].isOpen = false;
}
}
open is fired when clicking on a parent, closeOthers is called in open. I init a visible boolean to parents. Each time user clicks on a parent, it set visible to true, and others to false.
<div ng-controller="AccordionDemoCtrl">
<div>
<div ng-repeat="group in groups track by $index">
<div class="parents" ng-click="open($index)"><i ng-class="{'glyphicon-minus': group.isOpen, 'glyphicon-plus': !group.isOpen}"></i> {{ group.title }}
</div>
{{ group.content }}
<ul class="childs" ng-show="group.isOpen">
<li ng-repeat="item in group.list">
<span ng-bind-html="item"></span>
</li>
</ul>
</div>
</div>
</div>
Working demo

how to populate select option in angular

I have a dynamically created data. Based on this I am creating a form. But problem is option is not added to to the select. What is wrong in this.
customerB :
{
rows:3,
columns: 2,
name: 'customerB',
fields:
[
{type: "select", name:"teacher_id", label: "Teacher" , endpoint: "/teachers", required: true, check:[ { id : "1982", name : "Mr Bob"}, { id : "18273", name : "Mrs Katrine"} ]}
],
}
HTML
<div class="rows" ng-repeat="field in customerB">
<div class="columns" ng-repeat="newvalue in field">
<div class="controls" ng-switch="newvalue.type">
<div class="form-group">
<label class="control-label">{{newvalue.label}}</label>
<select class="form-control" ng-switch-when="select" ng-model="hiii" ng-required="newvalue.required" ng-options="item.id as item.name for item in newvalue.check">
</select>
</div>
</div>
</div>
</div>
You got an object which got an array, inside the array you got another array which is not correctly manipulating.
Try understanding the following code snippet:
HTML:
<select name="repeatSelect" id="repeatSelect">
<option ng-repeat="option in data.availableOptions" value="{{option.id}}">{{option.name}}</option>
</select>
JS
availableOptions: [
{id: '1', name: 'Option A'},
{id: '2', name: 'Option B'},
{id: '3', name: 'Option C'}
]
OR follow the link: https://docs.angularjs.org/api/ng/directive/select
This assumption might be wrong but I think in here ng-repeat="field in customerB" you are accessing object property directly without the scope variable. So you need to add whatever the scope variable name in front of the property name.
<div class="rows" ng-repeat="field in obj.customerB">
Other than that code you provided work perfectly.
Demo
angular.module("app",[])
.controller("ctrl",function($scope){
$scope.obj = { customerB :
{
rows:3,
columns: 2,
name: 'customerB',
fields:
[
{type: "select", name:"teacher_id", label: "Teacher" , endpoint: "/teachers", required: true, check:[ { id : "1982", name : "Mr Bob"}, { id : "18273", name : "Mrs Katrine"} ]}
],
}}
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
<div class="rows" ng-repeat="field in obj.customerB">
<div class="columns" ng-repeat="newvalue in field">
<div class="controls" ng-switch="newvalue.type">
<div class="form-group"> <label class="control-label">{{newvalue.label}}</label> <select class="form-control" ng-switch-when="select" ng-model="hiii" ng-required="newvalue.required" ng-options="item.id as item.name for item in newvalue.check"></select> </div>
</div>
</div>
</div>
</div>

AngularJs - UI Bootstrap Popover

Hello I'm using UI boostrap within Angular App
I would like to add Popover using UI boostrap, so this what I did so far:
<a popover popover-template="'tpl.html'" data-img="http://domain.com/img1.jpg" data-title="Link 1 title" data-content = "Link 1 content...">Link 1</a>
<a popover popover-template="'tpl.html'" data-img="http://domain.com/img2.jpg" data-title="Link 2 title" data-content = "Link 2 content...">Link 2</a>
...
<a popover popover-template="'tpl.html'" data-img="http://domain.com/imgn.jpg" data-title="Link n title" data-content = "Link n content...">Link n</a>
And then inject attributes : data-img, data-title, data-content in this template tpl.html:
<div class="popover-content">
<md-card>
<img ng-src="{{$img}}" class="md-card-image" >
<md-card-title>
<md-card-title-text>
<span class="md-headline">{{ $title}}</span>
</md-card-title-text>
</md-card-title>
<md-card-content>
{{ $content }}
</md-card-content>
</md-card>
</div>
Of course it doesn't work :)
My question is : how to inject element a attributes in the template tpl.html?
Please, any help is appreciated
Here's a plnkr showing how to use scope variable in the popover template.
Simplified markup & template:
<body ng-controller="MainCtrl">
<ul>
<li ng-repeat="link in links">
<a uib-popover popover-trigger="mouseenter" popover-placement="bottom" uib-popover-template="'tpl.html'" data-img="http://domain.com/img1.jpg" data-content = "Link 1 content...">{{link.label}}</a>
</li>
</ul>
<script type="text/ng-template" id="tpl.html">
<div class="popover-content">
<div>
<img ng-src="http://domain.com/{{link.img}}" class="md-card-image"/>
<div>
<span>{{link.title}}</span>
</div>
<div>{{ link.content }}</div>
</div>
</div>
</script>
Ctrl Code:
app.controller('MainCtrl', function($scope) {
$scope.links = [
{
label: 'Link 1',
title: 'Link 1 title',
content: 'Link 1 content',
img: 'img1.jpg'
},
{
label: 'Link 2',
title: 'Link 2 title',
content: 'Link 2 content',
img: 'img2.jpg'
},
{
label: 'Link 3',
title: 'Link 3 title',
content: 'Link 3 content',
img: 'img3.jpg'
}
];
});

How to escape an ng-Repeat loop?

I have the following ng-repeat loops that unpack JSON data into an Accordion:
<accordion close-others="oneAtATime">
<accordion-group ng-repeat="service in userPF.custom.services">
<accordion-heading><input type="checkbox" name="status" disabled>On <input type="checkbox" name="status" disabled checked>Off {{service.name}}</accordion-heading>
Related Items:<br>
<div class="secondary" ng-repeat="fields in userPF.custom.fields">
<span ng-show="checkForMatch(service.name, fields.services)">
<span ng-repeat="value in fields.values">
{{value.name}}<br>
</span>
</span>
</div>
</accordion-group>
</accordion>
The first trip through the loop {{service.name}} will always return data but the second value {{value.name}} might not. If it doesn't I don't want the div or span to render, just the heading. I've tried some variations on ng-if but haven't come close to being able to tell if I'm getting data back or not.
Refer this Link.
AS this code shows and its working fine you can have ng-show inside ng-repeat.
<div ng-app ng-controller="RepeatTestCtrl">
<ul ng-repeat="item in items">
<li ng-show="item.id.length == 0">{{item.name}} is even</li>
<li ng-show="item.id % 2 == 1">{{item.name}} is odd</li>
</ul>
</div>
function RepeatTestCtrl($scope) {
$scope.items = [
{ id: 1, name: 'test 1' },
{ id: 2, name: 'test 2' },
{ id: 3, name: 'test 3' },
{ id: 4, name: 'test 4' }
];
}
http://jsfiddle.net/b004t06z/41/

How to separate groups in ng-repeat

I have items I want to show, normally by using ng-repeat. I want to show the in some order (easy), but whenever the ordered attribute changes, I want some HTML in-between.
Example: (Fiddle):
<div ng-app ng-controller="Main">
<div ng-repeat="item in items | orderBy:'role'">
{{item.role}} - {{item.name}}
</div>
</div>
function Main($scope){
$scope.items = [{name: 'First', role: 1},
{name: 'Second', role:2},
{name: 'Third', role: 1},
{name: 'Fourth', role: 2}];
}
I want it to print:
1 - First
1 - Third
(some separator kode)
2 - Second
2 - Fourth
You will want to create a function in your scope.
$scope.currentRole = 'something';
$scope.CreateHeader = function(role) {
showHeader = (role!=$scope.currentRole);
$scope.currentRole = role;
return showHeader;
}
And then in your HTML:
<div ng-app ng-controller="Main">
<div ng-repeat="item in items | orderBy:'role'">
<div ng-show="CreateHeader(item.role)">
something here for the header
</div>
{{item.role}} - {{item.name}}
</div>
</div>
The solution by #lucuma only works on the first time through the loop. If Angular refreshes the list, the variable will still be set from the previous loop.
Instead, I added a new attribute to the list (say, header) during initialization:
function Main($scope){
$scope.items = [{name: 'First', role: 1, header: false},
{name: 'Second', role:2, header: false},
{name: 'Third', role: 1, header: true},
{name: 'Fourth', role: 2, header: false}];
}
Then the HTML by #lucuma works:
<div ng-app ng-controller="Main">
<div ng-repeat="item in items | orderBy:'role'">
<div ng-show="item.header"> // <== with this change
something here for the header
</div>
{{item.role}} - {{item.name}}
</div>
</div>
Oh, and you could sort the list once at initialization and remove the orderBy filter.

Resources