Continue working with angularjs and now having problem with ng-show which on click it show me all hidden data. As I understand, I need to specify ID of clicked item which I want to show, from my example i'm using ng-model which had boolean value and on click it change on true, that's why it's showing all items. Tell me please, how can I show item which I had selected?
<div class="list-group" ng-click="SetItemVisible()" ng-repeat="q in feed">
<a href="" class="list-group-item">
<h4 ng-model="showItem" class="list-group-item-heading">{{q.title}}</h4>
<p ng-show="showItem" value="true" class="list-group-item-text">{{q.body}}</p>
</a>
</div>
And js:
$scope.SetItemVisible = function () {
if (!$scope.showItem) {
$scope.showItem = true;
} else {
$scope.showItem = false;
}
}
$scope.feed = [];
function getRssItems() {
rssFeedService.getFeed().then(function (results) {
$scope.feed = results.data;
}, function (error) {
//alert(error.data.message);
});
}
You can do dis by:
$scope.feed = [{
'title': "A",
'body': "testA body"
},
{
'title': "b",
'body': "testb body"
}
]
$scope.showItem = {};
$scope.SetItemVisible = function (index) {
$scope.showItem[ index] = true;
}
<div class="list-group" ng-click="SetItemVisible($index)" ng-repeat="q in feed track by $index">
<a href="" class="list-group-item">
<h4 ng-model="showItem[$index]" class="list-group-item-heading">{{q.title}}</h4>
<p ng-show="showItem[$index]" value="true" class="list-group-item-text">{{q.body}}</p>
</a>
For live demo click here: http://plnkr.co/edit/ApI9eb8eQlBdoMUkn8do?p=preview
<div class="list-group" ng-click="q.showItem != q.showItem" ng-repeat="q in feed">
<a href="" class="list-group-item">
<h4 ng-model="showItem" class="list-group-item-heading">{{q.title}}</h4>
<p ng-show="q.showItem" value="true" class="list-group-item-text">{{q.body}}</p>
</a>
</div>
Assuming following JSON for feed
[
{
"title":"test1",
"body":"test body 1",
"show":false
},
{
"title":"test2",
"body":"test body 2",
"show":false
}
]
HTML
<body ng-controller="MainCtrl">
<div class="list-group" ng-repeat="q in feed">
<a class="list-group-item">
<h4 ng-click="q.show=!q.show" class="list-group-item-heading">{{q.title}}</h4>
<p ng-show="q.show" value="true" class="list-group-item-text">{{q.body}}</p>
</a>
</div>
JS
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope, $http) {
$scope.feed = [];
$http.get('feed.json').then(function (results) {
$scope.feed = results.data;
}, function (error) {
//alert(error.data.message);
});
});
Check out here
Related
i have uikit dropdown template in which i am trying add ng-reapet but drop down not working.
guys please help .....
<div class="uk-button-dropdown" uk-dropdown="{mode:'click'}">
<button class="md-btn">Click me <i class="material-icons"></i></button>
<div class="uk-dropdown">
<ul class="uk-nav uk-nav-dropdown">
<li ng-repeat="item in locationName">
{{item}}
</li>
</ul>
</div>
</div>
module
var addlocationModule = angular.module('addLocationApp', ['ngDialog']);
addlocationModule.controller('addLocationController', function ($scope, $http, $window, ngDialog) {
$scope.initialize = function(alllocation,loggedInEmployee)
{
$scope.alllocations = alllocation;
$scope.loggedInEmployee = loggedInEmployee;
$scope.locationName = [];
$scope.alllocations.forEach(function(resource) {
$scope.locationName.push(resource.title);
});
}
$scope.addLocations = function() {
$http.post('/addLocationName',$scope.location).then(function successCallback(response) {
if(response.data.status){
$scope.alllocations.push(response.data.location);
$scope.location.name="";
$scope.location.description="";
}
}, function errorCallback(response) {
// called asynchronously if an error occurs
// or server returns response with an error status.
})
}
});
you should add ng-repeat in ul tag
<ul class="uk-nav uk-nav-dropdown" ng-repeat="item in locationName">
<li>
{{item}}
</li>
</ul>
i think it'll help you.
I would like to use two different divs one contains a form and other contains repeat for the $scope values. Those two divs needs to use the same controller. However I am not able to share data in between divs in a desired way. Although I use factory, it only helps for me to add data to scope. I also want to edit the scope values inside the form which has another instance of the same controller.
You can find what I did in this link.
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<link rel="stylesheet" href="http://www.w3schools.com/lib/w3.css">
<body>
<script>
var app = angular.module("myShoppingList", []);
app.factory('fact',function(){
products = ["milk","chese"];
tempItem = '';
tempIndex = undefined;
return {
getProducts : function() {
return products;
},
getProductByIndex : function(x){
return products[x];
},
saveProduct : function(x,item)
{
if(x==undefined)
{
products.push(item);
}
else
{
products[x] = item;
}
tempItem = '';
tempIndex = undefined;
},
editProduct : function(x)
{
tempItem = products[x];
tempIndex = x;
},
removeProduct : function(x)
{
products.splice(x, 1);
},
getTempItem : function()
{
return tempItem;
},
getTempIndex : function()
{
return tempIndex;
},
}
});
app.controller("myCtrl", function($scope, fact) {
$scope.products = fact.getProducts();
$scope.tempIndex = fact.getTempIndex();
$scope.tempItem = fact.getTempItem();
$scope.saveItem = function () {
fact.saveProduct($scope.tempIndex,$scope.tempItem);
}
$scope.editItem = function (x) {
fact.editProduct(x);
}
$scope.removeItem = function (x) {
fact.removeProduct(x);
}
});
</script>
<div ng-app="myShoppingList" ng-cloak class="w3-card-2 w3-margin" style="max-width:400px;">
<header class="w3-container w3-light-grey w3-padding-16">
<h3>My Shopping List</h3>
</header>
<div ng-controller="myCtrl">
<ul class="w3-ul">
<li ng-repeat="x in products" class="w3-padding-16">{{$index}} {{x}}
<span ng-click="editItem($index)" style="cursor:pointer;" class="w3-right w3-margin-right">||</span>
<span ng-click="removeItem($index)" style="cursor:pointer;" class="w3-right w3-margin-right">×</span>
</ul>
</div>
<div ng-controller="myCtrl" class="w3-container w3-light-grey w3-padding-16">
<form ng-submit="saveItem()">
<div class="w3-row w3-margin-top">
<div class="w3-col s10">
<input placeholder="Add shopping items here" ng-model="tempItem" class="w3-input w3-border w3-padding">
<input type="hidden" ng-model="tempIndex">
</div>
<div class="w3-col s2">
<button type="submit" class="w3-btn w3-padding w3-green">Save</button>
</div>
</div>
</form>
</div>
</div>
</body>
</html>
ISSUES
You have initialized controller twice.
You can do edit item inside controller itself.
After saving $scope values should be cleared along with clearing values in factory.
CONTROLLER and HTML
var app = angular.module("myShoppingList", []);
app.factory('fact',function(){
products = ["milk","chese"];
tempItem = '';
tempIndex = undefined;
return {
getProducts : function() {
return products;
},
getProductByIndex : function(x){
return products[x];
},
saveProduct : function(x,item)
{
if(!x)
{
products.push(item);
}
else
{
products[x] = item;
}
tempItem = '';
tempIndex = '';
},
editProduct : function(x)
{
tempItem = products[x];
tempIndex = x;
},
removeProduct : function(x)
{
products.splice(x, 1);
},
getTempItem : function()
{
return tempItem;
},
getTempIndex : function()
{
return tempIndex;
},
}
});
app.controller("myCtrl", function($scope, fact) {
$scope.products = fact.getProducts();
$scope.tempIndex = fact.getTempIndex();
$scope.tempItem = fact.getTempItem();
$scope.saveItem = function () {
fact.saveProduct($scope.tempIndex,$scope.tempItem);
$scope.tempItem = '';
$scope.tempIndex = '';
}
$scope.editItem = function (x) {
$scope.tempItem = fact.getProducts()[x];
$scope.tempIndex = x;
}
$scope.removeItem = function (x) {
fact.getProducts().splice(x, 1);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<link rel="stylesheet" href="http://www.w3schools.com/lib/w3.css">
<div ng-app="myShoppingList" ng-controller="myCtrl" ng-cloak class="w3-card-2 w3-margin" style="max-width:400px;">
<header class="w3-container w3-light-grey w3-padding-16">
<h3>My Shopping List</h3>
</header>
<div>
<ul class="w3-ul">
<li ng-repeat="x in products" class="w3-padding-16">{{$index}} {{x}}
<span ng-click="editItem($index)" style="cursor:pointer;" class="w3-right w3-margin-right">||</span>
<span ng-click="removeItem($index)" style="cursor:pointer;" class="w3-right w3-margin-right">×</span>
</ul>
</div>
<div class="w3-container w3-light-grey w3-padding-16">
<form ng-submit="saveItem()">
<div class="w3-row w3-margin-top">
<div class="w3-col s10">
<input placeholder="Add shopping items here" ng-model="tempItem" class="w3-input w3-border w3-padding">
<input type="hidden" ng-model="tempIndex">
</div>
<div class="w3-col s2">
<button type="submit" class="w3-btn w3-padding w3-green">Save</button>
</div>
</div>
</form>
</div>
</div>
I'm trying to send a DELETE request by using the angular-resource service, but I keep getting the following message in dev tools:
Error: message.$delete is not a function
$scope.deleteMessage#file:///Users/me/Desktop/angular/my-app/loyalty-program_messages-pointstransactions.js:37:13
anonymous/fn#file:///Users/me/Desktop/angular/my-app/angularjs/angular.js line 14605 > Function:2:329
expensiveCheckFn#file:///Users/me/Desktop/angular/my-app/angularjs/angular.js:15694:18
ngEventHandler/https://code.jquery.com/jquery-1.12.4.min.js:3:12392
n.event.add/r.handle#https://code.jquery.com/jquery-1.12.4.min.js:3:9156
I notice that the angular-resource is missing here. Is there a reason for this?
This is the module with the controller:
var myApp = angular.module('myApp', ['ngResource'])
.constant("baseUrl1", MY-TESTING-URL-1)
.config(function($httpProvider) {
$httpProvider.defaults.withCredentials = true;
})
myApp.controller("MessagesCtrl", function($scope, $http, $resource, baseUrl1){
$scope.displayMode = "list";
$scope.currentMessages = null;
$scope.messagesResource = $resource(MY-TESTING-URL-1 + ":id?projection=full", { id: "#id" });
$scope.listMessages = function () {
$scope.foo = $scope.messagesResource.get();
$scope.foo.$promise.then(function (data) {
$scope.messages = [];
for(var i = 0; i < $scope.foo._embedded.messages.length; i++) {
var obj = $scope.foo._embedded.messages[i];
$scope.messages.push(obj);
}
});
}
$scope.deleteMessage = function (message) {
message.$delete().then(function () {
$scope.messages.splice($scope.messages.indexOf(message), 1);
});
$scope.displayMode = "list";
}
$scope.createMessage = function (message) {
new $scope.messagesResource(message).$save().then(function(newMessage) {
$scope.messages.push(newMessage);
$scope.displayMode = "list";
});
}
$scope.updateMessage = function (message) {
message.$save();
$scope.displayMode = "list";
}
$scope.editOrCreateMessage = function (message) {
$scope.currentMessage = message ? message : {};
$scope.displayMode = "edit";
}
$scope.saveEdit = function (message) {
if (angular.isDefined(message.id)) {
$scope.updateMessage(message);
} else {
$scope.createMessage(message);
}
}
$scope.cancelEdit = function () {
if ($scope.currentMessage && $scope.currentMessage.$get) {
$scope.currentMessage.$get();
}
$scope.currentMessage = {};
$scope.displayMode = "list";
}
$scope.listMessages();
});
This is the view with the ng-click that SHOULD send a DELETE request:
<div ng-repeat="message in messages">
<div class="data-tables read-{{ message.read }}">
<div class="data-tables-rows">
<div class="data-tables-toggle" type="button" data-toggle="collapse" data-target="#collapse_disclaimer_data-table_message-center_{{ $index }}" aria-expanded="false" aria-controls="collapse_disclaimer_data-table_message-center_{{ $index }}" title="View Details">
<label></label>
</div>
<div class="data-table-message hidden-xs" type="button" data-toggle="collapse" data-target="#collapse_disclaimer_data-table_message-center_{{ $index }}" aria-expanded="false" aria-controls="collapse_disclaimer_data-table_message-center_{{ $index }}" title="View Details">
<p style="white-space: nowrap; width: inherit; overflow: hidden;text-overflow: ellipsis;"><b>message</b><br />
{{ message.message }}
</p>
</div>
<div class="data-table-date" type="button" data-toggle="collapse" data-target="#collapse_disclaimer_data-table_message-center_{{ $index }}" aria-expanded="false" aria-controls="collapse_disclaimer_data-table_message-center_{{ $index }}" title="View Details">
<p><b>date</b><br />
<date>{{ message.dateReceived | date }}</date>
</p>
</div>
<div class="data-table-points hidden-xs points-{{ message.metadata }}" type="button" data-toggle="collapse" data-target="#collapse_disclaimer_data-table_message-center_{{ $index }}" aria-expanded="false" aria-controls="collapse_disclaimer_data-table_message-center_{{ $index }}" title="View Details">
<p><b>Points</b><br />
{{ message.metadata }}</p>
</div>
<div class="data-table-delete">
<button ng-click="deleteMessage(message)">Delete</button>
</div>
</div>
<div class="collapse" id="collapse_disclaimer_data-table_message-center_{{ $index }}">
<div class="data-tables-rows">
<div class="data-tables-spacer" style="visibility:hidden;">
<input id="data-table-icon" type="checkbox" />
<label for="data-table-icon"></label>
</div>
<div class="well">
<div class="data-table-message">
<p><b>Message</b><br />
{{ message.message }}</p>
</div>
<div class="data-table-points visible-xs">
<p><b>Points</b><br />
{{ message.metadata }}</p>
</div>
</div>
<div class="data-tables-spacer">
</div>
</div>
</div>
</div>
The message comes from CDN served JSON:
{
"_embedded": {
"messages":
{
"id": 8,
"message": "You received points",
"dateReceived": "2016-08-01T00:00:00.000+0000",
"read": false,
"metadata": "50"
}
}
}
Firefox in debugger option 'Selection to watch expression' doesn't appear to reveal anything abnormal as the object data is listed. Please help!
Thank you Joaozito Polo, you helped us figure it out. var newMessage is the new object from resource. Here is the new listMessages function:
$scope.listMessages = function () {
$scope.foo = $scope.messagesResource.get();
$scope.foo.$promise.then(function (data) {
$scope.messages = [];
for(var i = 0; i < $scope.foo._embedded.messages.length; i++) {
var obj = $scope.foo._embedded.messages[i];
var newMessage = new $scope.messagesResource(obj)
$scope.messages.push(newMessage);
}
});
}
I'm working on adding some features to make my project app look better. It's an app that creates a chatroom in any building you are located nearby based on location. It is currently integrating foursquare to get the user's location, but also to get photos for the chatroom they entered (i.e. they enter a bar, it shows the first five photos that foursquare has on that bar). I want to make a background slider using angular, but I am beyond stuck on how to get it properly implemented.
Here is my code for the chatroom template:
<ng-include src="'/templates/navbar.html'"></ng-include>
<div ng-repeat="photo in photos" >
<img ng-src="{{photo.prefix}}300x300{{photo.suffix}}"></img>
</div>
<div class="container">
<div class="row " style="padding-top:40px;">
<h3 class="text-center">{{venue}} </h3>
<br />
<br />
<div class="col-md-8">
<div class="panel panel-info">
<div class="panel-heading">
RECENT CHAT HISTORY
</div>
<div scroll-glue class="panel-body" style="overflow-y: auto; height: 540px;">
<ul class="media-list">
<li class="media" ng-repeat="message in messages">
<div class="media-body">
<div class="media">
<a class="pull-left" href="#">
<img class="media-object img-circle" style="height: 57px; width: 88px; max-height: 57px; max-width: 88px;" ng-src="{{message.img}}" />
</a>
<div class="media-body">
<p class="chatText" ng-bind-html="message.message | emoji"></p>
<br />
<small class="text-muted">Posted by <b>{{message.username}}</b>, at {{message.createdAt}}</small>
<hr />
</div>
</div>
</div>
</li>
</ul>
</div>
<div class="panel-footer">
<form ng-submit="createMSG(message)">
<div class="input-group">
<input type="text" class="form-control" ng-model="message" placeholder="Enter Message" />
<span class="input-group-btn">
<span style="margin: 0 20px;" emoji-picker="message" placement="right" title="Emoji" recent-limit="12"></span>
<button class="btn btn-custom" type="submit">SEND</button>
</span>
</div>
</form>
</div>
</div>
</div>
<div class="col-md-4">
<div class="panel panel-primary">
<div class="panel-heading">
ONLINE USERS
</div>
<div class="panel-body">
<ul class="media-list">
<li class="media" ng-repeat="user in users">
<div class="media-body">
<div class="media">
<a class="pull-left" href="#">
<img class="media-object img-circle" style="height: 57px; width: 88px; max-height: 57px; max-width: 88px;" ng-src="{{user.img}}" />
</a>
<div class="media-body">
<h5>{{user.username}} | User </h5>
<small class="text-muted" style="color: green;"><b>Online</b></small>
</div>
</div>
</div>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
Here is my controller that allows you to check-in to the chatroom with the integrated foursquare:
angular.module('thesis.foursquare', ['ngRoute'])
.controller('CheckinController', ['$scope', '$location', '$window', '$cookies', '$rootScope', '$http', 'UserService',
function checkInCtrl($scope, $location, $window, $cookies, $rootScope, $http, UserService) {
if (!$cookies.get('id')) {
$location.path("/login");
} else {
// get users gps coords
navigator.geolocation.getCurrentPosition(function(position) {
$scope.lat = position.coords.latitude;
$scope.long = position.coords.longitude;
$http({
method: 'GET',
url: 'https://api.foursquare.com/v2/venues/explore/?client_id=AL4DDIM5HHXXYV1HKMQBGFLFIJRHJVPR4BI4CJ0VQIN4PHGZ&client_secret=VXRH3J0QWAJKGIPHMEIOWWR3YSADCO3S2IJQMS3BNVEDFYUE&v=20130815&ll=' + $scope.lat + ',' + $scope.long + '&radius=800'
}).then(function successCallback(response) {
$scope.venue = [];
$.map(response.data.response.groups[0].items, function(venues) {
$.map(venues, function(venue) {
if (venue.id) {
var aVenue = {};
aVenue.id = venue.id;
aVenue.name = venue.name;
aVenue.location = venue.location;
aVenue.contact = venue.contact;
$scope.venue.push(aVenue);
}
});
});
});
}, function error(msg) {
alert('Please enable your GPS position future.');
}, {
maximumAge: 600000,
timeout: 5000,
enableHighAccuracy: true
});
$scope.venue = [];
var checkin = function() {
};
// url: 'https://api.foursquare.com/v2/venues/explore/?client_id=AL4DDIM5HHXXYV1HKMQBGFLFIJRHJVPR4BI4CJ0VQIN4PHGZ&client_secret=VXRH3J0QWAJKGIPHMEIOWWR3YSADCO3S2IJQMS3BNVEDFYUE&v=20130815&ll=40.7,-74&query=' + search + '&near=' + currentLocation
// https://api.foursquare.com/v2/venues/explore/?client_id=AL4DDIM5HHXXYV1HKMQBGFLFIJRHJVPR4BI4CJ0VQIN4PHGZ&client_secret=VXRH3J0QWAJKGIPHMEIOWWR3YSADCO3S2IJQMS3BNVEDFYUE&v=20130815&ll=29.9407336,-90.0820647&radius=200
$scope.joinChat = function(id, name) {
if ($cookies.get('id')) {
$rootScope.venue = name;
$rootScope.id = id;
$http({
method: 'GET',
url: 'https://api.foursquare.com/v2/venues/' + id + '/photos?client_id=AL4DDIM5HHXXYV1HKMQBGFLFIJRHJVPR4BI4CJ0VQIN4PHGZ&client_secret=VXRH3J0QWAJKGIPHMEIOWWR3YSADCO3S2IJQMS3BNVEDFYUE&v=20130815&ll=40.7,-74&limit=5'
}).then(function successCallback(response) {
$rootScope.photos = response.data.response.photos.items;
});
UserService.joinchat(id).success(function(data) {
$location.path("/chatroom");
});
} else {
$location.path("/login");
}
};
}
}
]);
Here is the controller for the chatroom template:
angular.module('thesis.chatroom', ['luegg.directives', 'emoji', 'vkEmojiPicker', 'mgcrea.ngStrap'])
.controller('ChatroomController', ['$scope', '$location', '$window', '$cookies', '$rootScope', '$http', 'UserService', 'chatSocket',
function AdminUserCtrl($scope, $location, $window, $cookies, $rootScope, $http, UserService, chatSocket) {
if (!$cookies.get('id')) {
$location.path("/login");
} else {
$scope.users = [];
$scope.messages = [];
$scope.id = $rootScope.id;
var chatId = $scope.id;
$rootScope.id = null;
chatSocket.emit('joinedChat', {
chatId: $scope.id
});
chatSocket.on('message', function(data) {
console.log(data);
$scope.messages = data.messages;
$scope.users = data.users;
});
$scope.$on('$destroy', function() {
if ($scope.users.length === 1) {
chatSocket.emit('DestroyChat', {
idChatroom: chatId,
idUser: $cookies.get('id')
});
chatSocket.removeListener();
} else {
chatSocket.emit('leaveChat', {
idUser: $cookies.get('id')
});
chatSocket.removeListener();
}
});
$scope.createMSG = function(msg) {
if ($cookies.get('id')) {
UserService.createMSG(msg, chatId, $cookies.get('id')).then(function(data) {});
$scope.message = "";
} else {
$location.path("/login");
}
};
}
}
]);
current result:
All images show up, but cannot figure out the angular slider
Any suggestions/tips/criticisms are always appreciated. Thank you in advance!
I'm using the following code to try ng-repeat in angular. I need to show the list which I click. But when I click on the symbol ~, it is showing all the lists.
How can I specify such conditions when using ng-repeat?
HTML
<div ng-app='myapp' ng-controller='cntrl'>
<input ng-model="addy" />
<button ng-click="add()" class="w3-btn w3-padding w3-blue">Add</button>
<span ng-show='span' style='color:red'>The TeXt Is AlReAdY In ThE LiSt</span>
<ul class="w3-ul">
<li ng-repeat="x in names" class="w3-padding-hor-16">
<span ng-click="expand()">~{{x}}
<ul ng-show='show'>
<li ng-repeat="Y in features[$index]">{{Y}}</li>
</ul>
</span>
</li>
</ul>
</div>
Angular JS
<script>
var app = angular.module('myapp',[]);
app.controller('cntrl', function($scope){
$scope.names = ['Fruits', 'Veggies', 'Cars'];
$scope.show= false ;
$scope.features=[['Apple','Mango','Lemon','Grapes'], ['Tomato', 'Carrot', 'Cucumber'], ['Porsche', 'Aston', 'Dodge']];
$scope.expand=function(){
$scope.show = !$scope.show;
}
$scope.add = function(){
$scope.span = false
if($scope.names.indexOf($scope.addy) === -1)
$scope.names.push($scope.addy);
else
$scope.span = true;
}
});
</script>
Pls check it out
var app = angular.module('myapp',[]);
app.controller('cntrl', function($scope){
$scope.names = ['Fruits', 'Veggies', 'Cars'];
$scope.show= false ;
$scope.features=[['Apple','Mango','Lemon','Grapes'], ['Tomato', 'Carrot', 'Cucumber'], ['Porsche', 'Aston', 'Dodge']];
$scope.expand=function(index){
$scope.expanded = ($scope.expanded != index)?index:-1;
}
$scope.add = function(){
$scope.span = false
if($scope.names.indexOf($scope.addy) === -1)
$scope.names.push($scope.addy);
else
$scope.span = true;
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app='myapp' ng-controller='cntrl'>
<input ng-model="addy" />
<button ng-click="add()" class="w3-btn w3-padding w3-blue">Add</button>
<span ng-show='span' style='color:red'>The TeXt Is AlReAdY In ThE LiSt</span>
<ul class="w3-ul">
<li ng-repeat="x in names" class="w3-padding-hor-16">
<span ng-click="expand($index)">~{{x}}
<ul ng-show='expanded == $index'>
<li ng-repeat="Y in features[$index]">{{Y}}</li>
</ul>
</span>
</li>
</ul>
</div>