Toggle Ionic list with sublist - angularjs

I have this html:
<div class="list">
<div ng-repeat="category in categories">
<div class="item item-icon-right">
{{category.name}}
<i class="icon icon-accessory ion-chevron-right pull-right"></i>
</div>
<div class="item" ng-repeat="sub_category in category.sub_categories">
{{sub_category.name}}
</div>
</div>
</div>
And this javascript:
var data = {};
data.categories = [];
data.categories[0] = {
id: 1
,name: "Computer"
,sub_categories: [
{id:1,name:"Mac"}
,{id:2,name:"PC"}
]
};
data.categories[1] = {
id: 2
,name: "Mobile"
,sub_categories: [
{id:3,name:"Iphone"}
,{id:4,name:"Samsung"}
]
}
$scope.categories = data.categories;
Right now a list with both cateogry and subcategories shows up.
I need the subcategories to be hidden by default. And only show when the parent is clicked.
I also need the icon for the parent to change from ion-chevron-right to ion-chevron-down.
How can you do this with pure angular code?
I could probably do this with jquery but I would prefer to have an angular approach.
Do I need to have the categories and subcategories to have their unique ID in order to access it?
Or there is another smarter way to do this?

See HTML
<div class="list">
<div ng-repeat="category in categories">
<div class="item item-icon-right">
{{category.name}}
<i class="icon icon-accessory ion-chevron-right pull-right" ng-click="showSubcategory($index)"></i>
</div>
</div>
<div ng-if="sub_categories.length">
<div ng-repeat="sub in sub_categories">{{sub.name}}</div>
</div>
</div>
See scripting controller
$scope.sub_categories=[];
$scope.showSubcategory=function(index){
$scope.sub_categories=[];
$scope.sub_categories=data.categories[index].sub_categories;
}
Actually there are many ways, you can find as many as go on.

Related

check if $index in ng-repeat is null

I have a grid view with two grids per row. This is the code:
<ion-content scroll="true" class="has-header">
<div class="row" style="padding-bottom: 40px;">
</div>
<div ng-repeat="i in products">
<div class="row" ng-if="$even">
<div class="col col-50">
<a class="item item-thumbnail-center" href="#">
<img src="http://{{host}}/{{
products[$index].prod_img
}}" class="img-thumbnail">
<h2>{{products[$index].prod_name}}</h2>
<p>Php {{products[$index].prod_price}}.00</p>
</a>
</div>
<div class="col col-50" ng-if="$index + 1">
<a class="item item-thumbnail-center" href="#">
<img src="http://{{host}}/{{
products[$index + 1].prod_img
}}" class="img-thumbnail">
<h2>{{products[$index + 1].prod_name}}</h2>
<p>Php {{products[$index + 1].prod_price}}.00</p>
</a>
</div>
</div>
</div>
</ion-content>
controller.js
$http.get("http://"+ $scope.host +"/mobile/get_products.php?cat_id=" + $stateParams.cat_id)
.then(function(response) {
$scope.products = response.data;
});
The problem is when the size of the array products is an odd, the second grid in the last row still shows up and certainly no item is displayed in there because the item is specified by the index is null. I've found some other solution on how to make this by configuring the array right from the controller but I want to ask if there is any way to check using an angular directive whether $index is null, and if true, the grid will be hidden.
you can use ng-class directive and put a css class which will get true when products[$index] === null | products[$index+1] === null. it will be like
ng-class={'hide-row': products[$index] === null | products[$index+1] === null}
where css
.hide-row{ display : none;}

Ionic / AngularJS key not accessible in ng-repeat

I am trying to access the {{key}} from an ng-repeat from a controller using Ionic 1. The {{key}} that is generated as text is different from the {{key}} I am receiving at the controller, not sure why this is.
What I want to do is find the div id which should be dynamically generated using the id = "historyHeader_{{key}}" and need to receive it using ng-click="loadInlineHistory({{key}})"
Controller:
$scope.loadInlineHistory = function (dateLoaded) {
var textS = $("#historyHeader_"+dateLoaded).text();
}
View
<ion-list>
<div ng-repeat="(key, value) in history | groupBy: 'date'"" style="background:#fff;padding:0.4em">
<div class="item item-divider">
<span style="min-height: 100%" id="historyHeader_{{key}}"> {{key}}</span>
</div>
<div style="width: 100%">
<div class="row" ng-repeat="hist in value">
<div ng-click="testRepeatx()">
<div class="row">
<div class="col col-50" align="left">3 laterals </div>
<div class="col col-50" align="left" style="color:#999">{{hist.reps}} calories</div>
</div>
</div>
</div>
<div class="row" >
<button class="button button-block button-balanced" ng-click="loadInlineHistory({{key}})"> <i class="ion-plus"></i></button>
</div>
</div>
</div>
</ion-list>
Just remove the curly brackets from the ng-click function call.
<div class="row" >
<button class="button button-block button-balanced"
ng-click="loadInlineHistory(key)"> <i class="ion-plus"></i></button>
</div>

Selecting group in accordion list

I just started with Angular and I got a code sample from codepen Accordion List
I'm trying to use my data in the html like this:
<div class="group">
<ion-item class="item-stable" ng-click="toggleGroup(group)" ng-class="{active: isGroupShown(group)}"></ion-item>
<ion-item class="item-accordion" ng-show="isGroupShown(group)">
<div class="form-group">
<label></label>
<input>
</div>
</ion-item>
</div>
<div class="group">
<ion-item class="item-stable" ng-click="toggleGroup(group)" ng-class="{active: isGroupShown(group)}"></ion-item>
<ion-item class="item-accordion" ng-show="isGroupShown(group)">
<div class="form-group">
<label></label>
<input>
</div>
</ion-item>
and the JS is set like this:
angular.module('my-app',['ionic'])
.controller('main', function($scope) {
$scope.groups = [{
name: "Basic Info",
items: [1,2,3]},
{
name: "Torso Measures",
items: [1,2,3]},
{
name: "Extra measures",
items: [1,2,3,4,5],
}
];
$scope.toggleGroup = function(group) {
if ($scope.isGroupShown(group)) {
$scope.shownGroup = null;
} else {
$scope.shownGroup = group;
}
};
$scope.isGroupShown = function(group) {
return $scope.shownGroup === group;
};
});
The problem is that whenever I click in 1 group, all of them expand / collapse. In JS / jQuery I'd pass an id but I think there is an "angular way" to do it. Could someone help me?
Demo without ng-repeat here.
Demo with ng-repeat here.
Why your code cant work:
Since you didn't use ng-repeat in your markup, group in these places
<ion-item class="item-stable" ng-click="toggleGroup(group)" ng-class="{active: isGroupShown(group)}"></ion-item>
<ion-item class="item-accordion" ng-show="isGroupShown(group)">
are both undefined.
You need init the group variable for toggleGroup(group),isGroupShown(group) and should be different name if used twice in same scope.Update your html:
<div class="group" ng-init="groupid1=1">
<ion-item class="item-stable" ng-click="toggleGroup(groupid1)" ng-class="{active: isGroupShown(groupid1)}"></ion-item>
<ion-item class="item-accordion" ng-show="isGroupShown(groupid1)">
<div class="form-group">
<label></label>
<input>
</div>
</ion-item>
</div>
<div class="group" ng-init="groupid2=2">
<ion-item class="item-stable" ng-click="toggleGroup(groupid2)" ng-class="{active: isGroupShown(groupid2)}"></ion-item>
<ion-item class="item-accordion" ng-show="isGroupShown(groupid2)">
<div class="form-group">
<label></label>
<input>
</div>
</ion-item>
</div>
However,By using ng-repeat, you can use your html with wrapped like this:
<div class="group" ng-repeat="group in groups track by $index">
<ion-item class="item-stable" ng-click="toggleGroup(group)" ng-class="{active: isGroupShown(group)}"></ion-item>
<ion-item class="item-accordion" ng-show="isGroupShown(group)">
<div class="form-group">
<label></label>
<input>
</div>
</ion-item>
</div>
It should works.
The fact that all your groups expand on click is probably because you have (in your snipet of code) two divs that uses the same group model.
I am talking about the group given in to your toggle function :
ng-click="toggleGroup(group)"
In the tutorial, the writter uses an ng-repeat directive to generate his divs
<div ng-repeat="group in groups">
this line goes in groups and take each item in groups member into a new group model. This could be why your accordions all expands,(and probably have the same content all of them). Could you give us a litle more co
If you want to use bootstrap accordion I can advise you to look at Angular-ui, an Angular module to replace bootstrap.js and make the same things in an Angular way (using directives, databinding....).

Convert ng-click to Blaze in meteoric

I used ng-click as below in ionic:
<div class="list">
<a class="item item-icon-right nav-clear" href="#/app/list1" ng-click="closeMenu()">
<i class="icon ion-ios7-paper"></i>
Item 1
</a> ....
</div>
know I want to use Meteor with Meteoric. I don't know how to convert ng-click to Blaze version. Please guide me.
I didn't find anything about this in Meteoric guide page.
Try to set up a template around your html:
<template name="myTemplate">
<div class="list">
<a id="myDiv" class="item item-icon-right nav-clear" href="#/app/list1">
<i class="icon ion-ios7-paper"></i>
Item 1
</a> ....
</div>
</template>
Then put this code into your js file:
Template.myTemplate.events({
"click #myDiv": function( event) {
// yourFunction
},
});

ng-repeat with nested json objects

I'm trying to create a nested ng-repeat that populates contacts names into buttons from the JSON objects. I cant seem to find the correct way to populate the info though. Can someone explain whats wrong with my ng-repeat?
http://plnkr.co/edit/B3g075?p=preview
<!-- Contacts List Section -->
<div class="col-md-3 contact-list">
<div class="list-group">
<a href="javascript:void(0);" ng-repeat="contact in groups.contacts" class="list-group-item" ng-click="selectContact(contact)">{{group.firstName}} {{group.lastName}}
<span ng-click="deleteContact()" class="onHover pull-right"><i class="fa fa-times"></i></span>
</a>
</div>
<button ng-click="isCreatingNewContact = true" class="btn btn-default"><i class="fa fa-plus"></i> New Contact</button>
</div>
$scope.groups has the following structure (shortened for brevity):
$scope.groups = [
{
name: "Personal",
contacts: [
{
"firstName": "Personal First Name",
"lastName": "last name",
// ...
},
{ /* another contact */ },
]
},
{
name: "Family",
contacts: [
// ...
]
},
];
Thanks
Notice how here:
<div class="col-md-3 group-list">
<!-- Groups Section -->
<h4>Contact Groups</h4>
<div class="list-group">
All Contacts
<a href="javascript:void(0);" ng-repeat="group in groups" class="list-group-item">{{group.name}}
<span ng-click="deleteGroup()" class="onHover pull-right"><i class="fa fa-times"></i></span>
</a>
</div>
<div class="col-bottom">
<button class="btn btn-default"><i class="fa fa-plus"></i> New Group</button>
</div>
</div>
You have an ng-repeat="group in groups" directive, iterating through the groups. The group you get while looping through groups is only active in the sub-scope of the <a> tag that you're calling the directive in.
You seem to want to get all of the contact objects of each object in groups. You'd have to iterate through the groups list again, and within that iteration, iterate through the objects in the group contacts. So something like:
<!-- Contacts List Section -->
<div class="col-md-3 contact-list">
<div class="list-group">
<div ng-repeat="group in groups">
<a href="javascript:void(0);" ng-repeat="contact in group.contacts" class="list-group-item" ng-click="selectContact(contact)">{{contact.firstName}} {{contact.lastName}}
<span ng-click="deleteContact()" class="onHover pull-right"><i class="fa fa-times"></i></span>
</a>
</div>
</div>
<button ng-click="isCreatingNewContact = true" class="btn btn-default"><i class="fa fa-plus"></i> New Contact</button>
</div>
Plunker: http://plnkr.co/edit/lqNd5yDC2QlrX0M9TjrP

Resources