Selecting group in accordion list - angularjs

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....).

Related

view detail in new page when click on button

I want to display the clicked row button details info in next view,I am displayin only code,nom in first page and remaining fields will view after clicking button. I used the option "filter" to do it, but sometimes it returns details of non concerned code , like for the two codes: 45 and 453 , it gaves the same detail because of the common number '45'.
First html page:
<ion-content class="padding" ng-controller="SuiviAdminCtrl" ng-init="load()">
<div class="row header">
<div class="col" >Code</div>
<div class="col">Client</div>
</div>
<div class="row" ng-repeat="x in namesC">
<div class="coll">
<a class="button" href="#/detail/{{x.Code}}">
{{x.Code}}</a>
</div>
<div class="col"> {{x.NomClient}} </div>
</div>
second html page (detail.html):
<ion-list ng-repeat="x in namesC| filter: {Code: thisX}|limitTo:1">
<ion-item>
<div class="item item-divider center-text"> {{x.Code}}</div>
</ion-item>
<ion-item>
<b>adresse</b> <span class="item-note"> {{x.adresse}} </span>
</ion-item>
</ion-list>
You just need to change the filter, so that it could match the code strictly.
<ion-list ng-repeat="x in namesC| filter: {Code: thisX}: strict|limitTo:1">
alternate syntax:
<ion-list ng-repeat="x in namesC| filter: {Code: thisX}: false|limitTo:1">
If you look at syntax of filter, you can specify filter. The default value of filter if false, which means comparison would not be strict.
fitler in angular

Listing the sub-items using ionic and angularjs

Im trying to display the car brand name and sub-list the car model names related to the car brand. But my car model names are displayed as an array and not as a list. Please help me to resolve it.
Link
<ion-list>
<ion-item ng-model="carBrand" ng-click="selectItem(carBrand)" ng-repeat="name in brandList">
<div class="item item-divider">
{{name.name}}
</div>
<div class="item">{{name.types}}</div>
</ion-item>
</ion-list>
Add ng-repeat for types as <div class="item" ng-repeat="type in name.types">{{type}}</div>
<ion-content ng-contorller="carBrand">
<h3> Add/Edit the Car Types </h3>
{{sample}}
Make:
<ion-list>
<ion-item ng-model="carBrand" ng-click="selectItem(carBrand)" ng-repeat="name in brandList">
<div class="item item-divider">
{{name.name}}
</div>
<div class="item" ng-repeat="type in name.types">{{type}}</div>
<br/>
</ion-item>
</ion-list>
</ion-content>

Toggle Ionic list with sublist

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.

Angular Directive to Prepend Group Header

I'm currently working on my first Ionic app and with it my first exposure to Angular. My current hurdle is injecting group headers ("A", "B", "C", and so on) into a longish list (~600) of alphabetically sorted names. I've looked into solutions with filters, nested ngRepeats (which, specifically, didn't seem to play nice with Ionic's collection-repeat), but would like to accomplish this without the need for filtering or third-party dependencies like lodash or underscores.
My current target solution is to use a directive to prepend the header to the first element of each group of names.
The app is consuming content from Contentful's API and in the service I'm manually adding a group identifier based on the name's first letter. An example data set might be:
[
{"id":"1","name":"Carrie","group":"C"},
{"id":"2","name":"Gabe","group":"G"},
{"id":"3","name":"Gerry","group":"G"},
{"id":"4","name":"Hector","group":"H"},
{"id":"5","name":"Hilbert","group":"H"}
]
Here's the template:
<ion-content>
<ion-list>
<div collection-repeat="person in People" group-header>
<ion-item class="item-icon-right" type="item-text-wrap" href="#/app/people/{{ person.id }}" group="{{ person.group }}">
<h2>{{ person.name }}</h2>
<i class="icon ion-chevron-right icon-accessory"></i>
</ion-item>
</div>
</ion-list>
</ion-content>
Here's the directive:
.directive('groupHeader', function () {
return {
compile: function (element) {
element.prepend('<div class="item item-divider" is-divider>{{ person.group }}</div>');
}
}
})
And currently, as expected, the prepend occurs for each repeated item:
<div collection-repeat="name in Names" group-header>
<div class="item item-divider ng-binding">C</div>
<ion-item class="item-icon-right item item-complex" type="item-text-wrap" href="#/app/names/1" group="C">
<a class="item-content" ng-href="#/app/names/1" href="#/app/names/1">
<h2 class="ng-binding">Carrie</h2>
<i class="icon ion-chevron-right icon-accessory"></i>
</a>
</ion-item>
</div>
<div collection-repeat="name in Names" group-header>
<div class="item item-divider ng-binding">G</div>
<ion-item class="item-icon-right item item-complex" type="item-text-wrap" href="#/app/names/2" group="G">
<a class="item-content" ng-href="#/app/names/2" href="#/app/names/2">
<h2 class="ng-binding">Gabe</h2>
<i class="icon ion-chevron-right icon-accessory"></i>
</a>
</ion-item>
</div>
I'd like to know if there are any recommendations for updating the directive so that it only prepends on the first instance of name in a given group. I'm happy to be pointed to resources, rather than a longhand solution--but either will be much appreciated.
Thanks!
I was able to accomplish what I was after with an ng-switch in the template:
<ion-content>
<ion-list>
<div collection-repeat="person in People">
<ng-switch on="$first || person.group != People[$index-1].group">
<ion-item type="item-text-wrap" ng-switch-when="true">
{{ person.group }}
</ion-item>
</ng-switch>
<ion-item class="item-icon-right" type="item-text-wrap" href="#/app/people/{{ person.id }}" group="{{ person.group }}">
<h2>{{ person.name }}</h2>
<i class="icon ion-chevron-right icon-accessory"></i>
</ion-item>
</div>
</ion-list>
</ion-content>
Thanks to: https://stackoverflow.com/a/14076254/3426040.

Ionic pass from controller variable to page

Hello I'm doing an hybrid app using Ionic Framework, but I think my mistake it's more from angular.
I got this view:
<ion-view class="back" ng-controller="webCtrl" view-title="{{tipo[id].title}}">
<ion-content>
<ion-list>
<div ng-controller="WebminarsCtrl">
<div ng-repeat="group in groups">
<ion-item class="item-dark" ng-click="toggleGroup(group)" ng-class="{active: isGroupShown(group)}">
<i class="icon" ng-class="isGroupShown(group) ? 'ion-minus' : 'ion-plus'"></i>
{{group.name}}
</ion-item>
<ion-item menu-close class="item-accordion" ng-repeat="item in group.items" ng-show="isGroupShown(group)">
<p ng-bind-html="item.mapa"></p>
<p ng-bind-html="item.contenido"></p>
</ion-item>
</div>
</div>
</ion-list>
</ion-content>
</ion-view>
But the ng-bind-html isn't working, in my controller I had this:
.controller('WebminarsCtrl', function($scope, $state) {
$scope.id = $state.params.id;
$scope.groups = [];
$scope.groups[0] = {
name: 'Tec de Monterrey',
items: []
};
$scope.groups[0].items[0] = {
contenido:'Horarios',
mapa: '<iframe src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d3764.2253262010768!2d-99.26264758551588!3d19.359393748034964!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x85d200c0fa04d82b%3A0x5e726f97d5cf3c8b!2sTecnol%C3%B3gico+de+Monterrey+Campus+Santa+Fe!5e0!3m2!1sen!2smx!4v1459638056684" width="600" height="450" frameborder="0" style="border:0" allowfullscreen></iframe>'
};
})
And the the view doesn't display the map that the variable had, but the contenido variable it's working without problems.
Any help will be appreciated.
Add angular-sanitize.js Angular sanitize / ng-bind-html not working?
If that doesn't help then try using $sce.trustAsHtml as a filter $sce
Easy example how to use it with out making a filter https://stackoverflow.com/a/18342738/5136207

Resources