Angular js - basic toggle of additional object values - angularjs

I would like to output a basic list of names, and below the list display some text. This text should only be displayed once you've clicked on an item and it should toggle when selecting another.
What I've got so far
<div ng-app>
<div ng-controller="contacts">
<ul>
<li ng-repeat="person in people | orderBy:'name'">
{{person.name}}
<span>{{person.age}}</span>
</li>
</ul>
<div class="desc">
<!-- I would like to output the descriptions here -->
</div>
</div>
</div>
<script>
var contacts = function($scope) {
$scope.people = [
{name:"paul", age:30, desc:"this is a description"},
{name:"jax", age:33, desc:"this is another description right here"},
{name:"yoda", age:33, desc:"final description goes here"},
{name:"steve", age:53, desc:"jsut kidding - one more."}
];
};
</script>
I'm pretty sure I should be using ng-click and possible the model etc but this simple task is doing my head in. I'm able to do a basic show and hide below the link (though not sure about toggling them).
Super new to angular, please excuse me if this seems like a retarded request.
Looking for a super clean, quick and easy way to do this. Any input would be great.

There are not silly questions; at some point we were all newbies :)
Controller
var contacts = function($scope) {
$scope.people = [
{name:"paul", age:30, desc:"this is a description"},
{name:"jax", age:33, desc:"this is another description right here"},
{name:"yoda", age:33, desc:"final description goes here"},
{name:"steve", age:53, desc:"jsut kidding - one more."}
];
$scope.selectedPersonDescription = null;
$scope.selectPerson = function(person) {
$scope.selectedPersonDescription = person.desc;
}
};
View
<div ng-app>
<div ng-controller="contacts">
<ul>
<li ng-repeat="person in people | orderBy:'name'", ng-click="selectPerson(person)">
{{person.name}}
<span>{{person.age}}</span>
</li>
</ul>
<div class="desc">
{{ selectedPersonDescription }}
</div>
</div>
</div>

Related

How to display the answer direction for a questionarie based on Direction

We are creating a quiz using angularjs.
We want to show the radiobutton list direction vertically or horizontally.
If it is horizontally we want do show in 2 columns.
Help me to show horizontally or vertically
Have provided the code in
var app = angular.module("quizApp", []);
app.controller("quizCtrl", function ($scope) {
$scope.questions = [
{
question: "Which is the largest country in the world by population?",
options: ["India", "USA", "China", "Russia"],
answer: 2,
direction:0
},
{
question: "When did the second world war end?",
options: ["1945", "1939", "1944", "1942"],
answer: 0,
direction: 1
}
];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<body>
<div ng-app="quizApp" ng-controller="quizCtrl">
<div data-ng-repeat="quiz in questions track by $index" data-ng-init="quizIndex = $index" layout="column">
<div layout="row">
<span data-ng-bind="quiz.question"></span>
</div>
<div layout="row" data-ng-repeat="option in quiz.options track by $index" data-ng-init="optionIndex = $index">
<input type="radio" data-ng-value="{{option}}" style="margin-right: 5px;"
name="Options_{{quizIndex}}_Response_{{optionIndex}}" />
<span id="spnAnswer_{{quizIndex}}_{{optionIndex}}" data-ng-bind="option" />
</div>
</div>
</div>
</body>
You can use ng-class in the div of your repeater to show horizontal or vertical way.
Your HTML template might be look like following:
<div ng-class="'class-for-horizontal-display': !showVertical, 'class-for-vertical-display': showVertical" data-ng-repeat="quiz in questions track by $index" data-ng-init="quizIndex = $index" layout="column">
</div>
and in your controller you should have a $scope variable "showVertical" like:
$scope.showVertical = false

How to display states of a country if two specific countries are chosen from a list of countries in Angular ng-repeat

I have a list of countries, and the client has the option to choose two of these. When the client uses the checkbox tick to choose two countries (by clicking on the checkboxes of two countries), we need to display the states in those two countries using ng-repeat.
Can someone please help me with a small example of the unordered lists and how to use ng-repeat in this scenario?
I am new to Angular.
As far as the HTML, something like the below is a very simple example of what you may end up with. You could use two ng-repeats; one for each country selected, and another for each state within each country:
<div ng-repeat="country in countries">
<h1>country.name</h1>
<ul>
<li ng-repeat="state in country.states">
<p>state.name</p>
</li>
</ul>
</div>
You can create checkboxes which add a "checked" property to the countries. And then a repeat which repeats only checked ones.
View
<p>
Choose {{limit}} countries:
</p>
<p ng-repeat="country in countries">
<input type="checkbox" ng-model="country.checked" ng-disabled="(countries | filter:{checked:true}).length >= limit"> {{country.name}}
</p>
<p>
Result
</p>
<div ng-repeat="country in countries | filter:{checked:true}">
<h1>{{country.name}}</h1>
<ul>
<li ng-repeat="state in country.states">
<p>{{state}}</p>
</li>
</ul>
</div>
</div>
Controller
angular.module("app", [])
.controller("mainCtrl", function($scope) {
$scope.limit = 2;
$scope.countries = [{
"name": "Finland",
"states": [
"statename1",
"statename2"
]
}, {
"name": "Sweden",
"states": [
"statename3",
"statename4"
]
}, {
"name": "Norway",
"states": [
"statename5",
"statename6"
]
}];
});
Demo: https://jsfiddle.net/ptfg5xs0/1/

How to display div of related content from template when clicked in Angular

I have a question on how best to achieve a feature in Angular. I have tried a number of solutions from ng-click, ng-if, ng-show and combinations of those but no luck in my novice state.
Currently I ng-repeat through an array of json data as li.
What I want to achieve is when I click one of the looped li it opens and displays the 'info div' with the related info to the li clicked (preferably by use of template). If user clicks another li it simply switches out the data to display correctly again.
Any advice on how to proceed to this feature would be greatly appreciated. I have provided my existing code as well as a CodePen.
JS:
var phonecatApp = angular.module('myApp', [])
.controller('starWarsCtrl', function ($scope) {
$scope.data = [
{"name": "Obi-Wan Kenobi",
"index":88,
"cat": "Jedi"},
{"name": "Yoda",
"index":69,
"cat":"Jedi"},
{"name": "Lando",
"index":31},
{"name": "Han Solo",
"index":90},
{"name": "Darth Vader",
"index":98},
{"name": "Jar-Jar Binks",
"index":80},
{"name": "Mace Windu",
"index":45},
{"name": "Chewy",
"index":76}
];
})
HTML:
<div ng-app="myApp" ng-controller="starWarsCtrl">
<input type="text" id="query" ng-model="query"/>
<div class="bscroll">
<ul>
<li class="box" ng-repeat="i in data | filter:query | orderBy: orderList">
<h2>{{i.name}}</h2>
<p>{{i.index}}{{i.cat}}</p>
</li>
</ul>
</div>
<div class="info">The details would appear here</div>
</div>
Simplest solution is to add an ng-click to your <li> that calls a function to select the item:
<li class="box" ng-repeat="i in data | filter:query | orderBy: orderList" ng-click="select(i)">
<h2>{{i.name}}</h2>
<p>{{i.index}}{{i.cat}}</p>
</li>
and then your js:
$scope.select = function (item) {
$scope.selectedItem = item;
}
and your info div:
<div class="info" ng-if="selectedItem">
Name: <span ng-bind="selectedItem.name"></span><br>
Index: <span ng-bind="selectedItem.index"></span>
<div ng-if="selectedItem.cat">
Category: <span ng-bind="selectedItem.cat"></span>
</div>
</div>
This should at least be enough to get you started in the right direction.
Updated pen: http://codepen.io/anon/pen/WrqXJa

Hide and Display Subsections

I have menu with sections and subsections, like this:
Section 1
Sub 1.1
Sub 1.2
Section 2
Sub 2.1
Sub 2.2
I want to hide subsections and show one of them by clicking on section (click on Section 2):
Section 1
Section 2
Sub 2.1
Sub 2.2
Here is my code and JSFiddle:
<div ng-controller="MyCtrl">
<div ng-repeat="(meta, counts) in info">
{{ meta }}
<ul class="subsection">
<li ng-repeat="(group, cnt) in counts">
{{ group }}
</li>
</ul>
</div>
</div>
Controller:
var myApp = angular.module('myApp',[]);
//myApp.directive('myDirective', function() {});
//myApp.factory('myService', function() {});
function MyCtrl($scope) {
$scope.name = 'Superhero';
$scope.info = { "one": { "a": 1, "b": 2 },
"two" : { "c": 3, "d": 4 }};
$scope.display = function(meta) {
// ????
};
}
CSS:
ul.subsection {
display: none;
}
How can I fix this code to show one of the subsection by click on the section ?
Update: I fixed the link on JSFiddle
Since ng-repeat creates its own scope, you can simply toggle a variable within the loop, and use ng-show on that variable:
<div ng-repeat="(meta, counts) in info">
{{ meta }}
<ul class="subsection" ng-show="display">
<li ng-repeat="(group, cnt) in counts">
{{ group }}
</li>
</ul>
</div>
Edit: If you can only show one function at a time, then you can do what you were trying to do in your original code with a function:
<div ng-repeat="(meta, counts) in info">
{{ meta }}
<ul class="subsection" ng-show="sectionIndex == $index>
<li ng-repeat="(group, cnt) in counts">
{{ group }}
</li>
</ul>
</div>
$scope.display = function(index) {
$scope.sectionIndex = index;
}
You can simply do something like this:
<div ng-repeat="(meta, counts) in info">
{{meta}}
<ul class="subsection" ng-show="$parent.display == meta">
<li ng-repeat="(group, cnt) in counts">
{{ group }}
</li>
</ul>
</div>
Note, that you can refer $parent scope to avoid local scope display property.
In this case you don't need CSS rule. Bonus point is that you can set in controller $scope.display = 'two' and the second item will expand.
However cleaner way would be using a controller function as demonstrated by #tymeJV, this is the best approach.
Demo: http://plnkr.co/edit/zXeWjXLGHMv0BZZRZtud?p=preview

Angularjs directive to append to template

I am new to angularjs world and am trying to do something that I think should be achievable with a directive.
I have a template which has a list of articles listed using ng-repeat. These articles have a date on them. I want to group the articles by date in the template. So I am thinking of creating a directive that would append a new div before each group of articles in that day. The data in the model is already sorted by date desc.
Should I be using the compile function in the directive to do this ? Any code examples would be great.
If I understand you correctly you want the output to be something like:
<ul>
<li>
Show 3 articles for date 2012-12-07
</li>
<li>
Show 1 articles for date 2012-12-06
</li>
<li>
Show 2 articles for date 2012-12-05
</li>
</ul>
In that case, I would do the grouping before it renders:
function ArticlesController ($scope) {
var groupArticles = function (articles) {
var i,
art = {};
for (i = 0; i < articles.length; i += 1) {
if (!art.hasOwnProperty(articles[i].date)) {
art[articles[i].date] = [];
}
art[articles[i].date].push(articles[i]);
}
return art;
};
$scope.articles = [{ date: '2012-12-07', title: 'Marcus' },
{ date: '2012-12-07', title: 'Zero' },
{ date: '2012-12-06', title: 'Moxxi' },
{ date: '2012-12-05', title: 'Dr Zed' }];
$scope.groupedArticles = groupArticles($scope.articles);
}
And you view:
<ul data-ng-controller="ArticlesController">
<li data-ng-repeat="articles in groupedArticles">
<div data-ng-repeat="article in articles">
{{ articles.title }}
</div>
</li>
</ul>
<ul>
<li ng-repeat="article in articles">
<ng-switch on="$first || article.date != articles[$index-1].date">
<div ng-switch-when="true" class="group_heading">{{article.date}}</div>
</ng-switch>
{{article.title}}
</li>
</ul>
The above is modeled off an existing fiddle I had.
The above assumes (as you stated) that articles is already sorted. If not, the fiddle shows how to use the orderByFilter in a controller to create a sorted array based on any object property.

Resources