How fill dropdown menu - angularjs

I´m working with bootstrap and angularjs for the user interface and google appengine with java as a backend.
Just now I have a problem filling a dropdown menu, I see an empty list so I suspect that the problem is in the html code.
Front end:
<div class="dropdown" >
<select id="mySelPartido" class="form-control">
<option ng-repeat="partido in data.locations.partidos"
ng-selected="partido.selected" ng-model="partido.partido">{{partido.partido}}</option>
</select>
</div>
js in angular code (I debug this code and it works!):
$scope.status = 'loading...';
$scope.partido = "Select partidos";
$scope.data = {
"locations": {}
};
$http.get('https://myservice.appspot.com/_ah/api/partidoendpoint/v1/partido')
.then(function (res) {
$scope.data.locations.partidos = res.data.items;
$scope.status = "loaded "
+ $scope.data.locations.partidos.length
+ " partidos.";
});
My service response from app engine backend:
{
"items": [
{
"id": {
"kind": "Partido",
"appId": "s~myservice",
"id": "5066549580791808",
"parent": {
"kind": "Provincia",
"appId": "s~myservice",
"id": "5086253011697664",
"complete": true
},
"complete": true
},
"name": "Florencio Varela",
"kind": "partidoendpoint#resourcesItem"
},
{
"id": {
"kind": "Partido",
"appId": "s~myservice",
"id": "5094432508477440",
"parent": {
"kind": "Provincia",
"appId": "s~myservice",
"id": "5086253011697664",
"complete": true
},
"complete": true
},
"name": "La Matanza",
"kind": "partidoendpoint#resourcesItem"
}
],
"kind": "partidoendpoint#resources",
"etag": "\"PQS12KaO4-dKVfv_BcCoEkbIN9g/GvZKzZUnrHEP8TKWybTkd_fJbnc\""
}

Check the angular documentation for select.
Maybe try use the ngOptions directive in the select element. Example :
function demo($scope) {
$scope.items = [
{ name: 'foo' },
{ name: 'bar' },
{ name: 'baz' }
];
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app ng-controller="demo">
<select ng-options="item.name for item in items"
ng-model="selected">
</select>
<p>You have selected : {{ selected }}
</div>

Related

AngularJS Filed nested array of objects with array of objects

I'm trying to filter a nested array of objects with my own objects, by idSubject. But I'm not getting the right result.
I have articles (which have subjects)
And a array of objects (which are the subjects I want to filter the articles with)
Data looks like this:
So I'm trying to filter the array of articles by its subjects.
I tried the following:
<div class="panel panel-default"
ng-repeat="searchArticle in searchArticles | filter: {subjects: filterSubjects} as articleSearchResult">
So filterSubjects is the second screenshot and SearchArticles is the first screenshot.
Without much luck.
Hope you can help, please tell me if things are still unclear.
This custom filter will help you.
Example : http://plnkr.co/edit/jMizCLxPH6DtDA5wL15Q?p=preview
HTML:
<body ng-app="myApp">
<div ng-controller="MainCtrl">
<h2>Select Subjects</h2>
<div ng-repeat="subject in subjects">
<label>
<input type="checkbox" ng-model="filterSubjects[subject.id]" ng-true-value="'{{subject.id}}'" ng-false-value="''">{{subject.name}}</label>
</div>
<h2>Filtered Articles</h2>
<div ng-repeat="searchArticle in searchArticles | subjectFilter:filterSubjects">{{searchArticle.name}}</div>
</div>
</body>
JS:
var app = angular.module('myApp', []);
app.controller('MainCtrl', function($scope) {
$scope.searchArticles = [{
"name": "Article1",
"sid": "1"
}, {
"name": "Article2",
"sid": "1"
}, {
"name": "Article3",
"sid": "2"
}];
$scope.subjects = [{
"name": "Subject1",
"id": "1"
}, {
"name": "Subject2",
"id": "2"
}];
$scope.filterSubjects = [];
});
app.filter('subjectFilter', function() {
return function(articles, filterSubjects) {
filtered = articles.filter(function(e){return filterSubjects.indexOf(e.sid) >= 0},filterSubjects);
return filtered;
}
});
if you want to filter based on object :
var app = angular.module('myApp', []);
app.controller('MainCtrl', function($scope) {
$scope.searchArticles = [{
"name": "Article1",
"sid": "1"
}, {
"name": "Article2",
"sid": "1"
}, {
"name": "Article3",
"sid": "2"
}];
$scope.subjects = [{
"name": "Subject1",
"id": "1"
}, {
"name": "Subject2",
"id": "2"
}];
$scope.filterSubjects = [{
"name": "Subject1",
"id": "1"
}, {
"name": "Subject1",
"id": "2"
}];
});
app.filter('subjectFilter', function() {
return function(articles, filterSubjects) {
var sFiltered = [];
for (var i = 0; i < filterSubjects.length; i++) {
sFiltered.push(filterSubjects[i].id);
}
var filtered = articles.filter(function(e) {
return sFiltered.indexOf(e.sid) >= 0;
}, sFiltered);
return filtered;
}
});

How to extract data from json using angularjs?

Here in {{msg}} I can display all jason data with Selected:true or false..
but What I need is I don't want to display all the datas, when I click Save button I want to display questions.id,option.id and selected:true or false below the textbox
we will get all the json data from $scope.questions.
Home.html
<div ng-repeat="question in filteredQuestions">
<div class="label label-warning">Question {{currentPage}} of {{totalItems}}.</div>
<div class="row">
<div class="row">
<h3>{{currentPage}}. <span ng-bind-html="question.Name"></span></h3>
</div>
</div>
<div class="row text-left options">
<div class="col-md-6" ng-repeat="option in question.Options" style="float:right;">
<div class="option">
<label class="" for="{{option.Id}}">
<h4> <input id="{{option.Id}}" type="checkbox" ng-model="option.Selected" ng-change="onSelect(question, option);" />
{{option.Name}}</h4>
</label>
</div>
</div>
</div>
<div class="center"><button ng-click="save()">Save</button></div>
<div class="center"><textarea rows="5" cols="50">{{msg}}</textarea></div>
</div>
controllers.js
var HomeController = function ($scope, $http, helper) {
/*$scope.names = response.data;
$scope.detectChange=function(){
$scope.msg = 'Data sent: '+ JSON.stringify($scope.filteredQuestions);
}*/
$scope.save = function() {
$scope.msg = 'Data sent: '+ JSON.stringify($scope.questions);
}
$scope.quizName = 'data/csharp.js';
$scope.loadQuiz = function (file) {
$http.get(file)
.then(function (res) {
$scope.quiz = res.data.quiz;
$scope.config = helper.extend({}, $scope.defaultConfig, res.data.config);
$scope.questions = $scope.config.shuffleQuestions ? helper.shuffle(res.data.questions) : res.data.questions;
$scope.totalItems = $scope.questions.length;
$scope.itemsPerPage = $scope.config.pageSize;
$scope.currentPage = 1;
$scope.mode = 'quiz';
$scope.$watch('currentPage + itemsPerPage', function () {
var begin = (($scope.currentPage - 1) * $scope.itemsPerPage),
end = begin + $scope.itemsPerPage;
$scope.filteredQuestions = $scope.questions.slice(begin, end);
});
});
}
$scope.loadQuiz($scope.quizName);
}
HomeController.$inject = ['$scope', '$http', 'helperService'];
csharp.js
{
"quiz": {
"Id": 2,
"name": "C# and .Net Framework",
"description": "C# and .Net Quiz (contains C#, .Net Framework, Linq, etc.)",
"paragraph": "In 2015 Microsoft released ASP.NET 5.ASP.NET 5 is a significant redesign of ASP.NET.ASP.NET, MVC, and Web Pages are now merged into a single framework named MVC 6.It includes the following features:Linux support OSX support Node.js supportA ngularJS supportTag ,HelpersView, ComponentsWeb ,APIGruntJS ,supportBower, supportNo ,Visual BasicNo Web Forms"
},
"config": {
"shuffleQuestions": true,
"showPager": false,
"allowBack": true,
"autoMove": false
},
"questions": [{
"Id": 1010,
"Name": "Which of the following assemblies can be stored in Global Assembly Cache?",
"QuestionTypeId": 1,
"Options": [{
"Id": 1055,
"QuestionId": 1010,
"Name": "Private Assemblies"
}, {
"Id": 1056,
"QuestionId": 1010,
"Name": "Friend Assemblies"
}, {
"Id": 1057,
"QuestionId": 1010,
"Name": "Public Assemblies"
}, {
"Id": 1058,
"QuestionId": 1010,
"Name": "Shared Assemblies"
}]
}, {
"Id": 1019,
"Name": "Which of the following does NOT represent Integer?",
"QuestionTypeId": 1,
"Options": [{
"Id": 1055,
"QuestionId": 1010,
"Name": "Char"
}, {
"Id": 1056,
"QuestionId": 1010,
"Name": "Byte"
}, {
"Id": 1057,
"QuestionId": 1010,
"Name": "Short"
}, {
"Id": 1058,
"QuestionId": 1010,
"Name": "Long"
}]
}]
}
This is my answer of above code..here Displaying all the data
Data sent: [{"Id":1013,"Name":"Which of the following is NOT an Arithmetic operator in C#.NET?","QuestionTypeId":1,"Options":[{"Id":1055,"QuestionId":1010,"Name":"** (Double Star)","$$hashKey":"00X","Selected":false},{"Id":1057,"QuestionId":1010,"Name":"+ (Plus)","$$hashKey":"00Y","Selected":false},
"$$hashKey":"00C"}]
but I want to display the all the question id's and corresponding option id's and if it is selected,selected:true otherwise false in the format of above output
If you want to change what is presented to the user after saving you should change this function:
$scope.save = function() {
$scope.msg = 'Data sent: '+ JSON.stringify($scope.questions);
}
to something like:
$scope.save = function() {
$scope.msg = 'Question IDs:';
$scope.questions.forEach(function(el){
$scope.msg += el.Id + ',';
}
}
This for example will join all the ids of the array that conains all the questions.
To add options and selections you have to ng-model the value to some variable that you will use inside your controller.
I think you should check a little guide to angularjs two-way data binding

Get data from json but only for one record

I've this JSON:
{
"success": true,
"return": {
"totalItem": 7,
"totalPages": 1,
"pageSize": 7,
"items": {
"phones": [
"(48) 9999-9999"
],
"users": {
"manager": {
"id_user": "5819",
"name": "Síndico Ilhas Belas",
"user": "sindico.teste#domain.com",
"photo": "https://domain.amazonaws.com/files/upload/2015/07/25/5819.55b32d90e69ab3.05638898_873f970f8d259.jpg"
},
"employees": [
{
"id_user": "2",
"name": "José Perez",
"user": "pepe#domain.com",
"photo": "https://.amazonaws.com/files/upload/2013/10/07/2.52523a0451c3c5.59697102_7a4188d3.jpg",
"groups": [
{
"id_group": "33",
"name": "Portaria"
}
],
"work_details": {
"work_schedule": "8-12hs e 14-18hs",
"work_activities": "Supervisionar os trabalhos de conservação"
}
},
{
"id_user": "15142",
"name": "Marcos Rojas",
"user": "rojas#c.com",
"photo": "http://www.domain.com/themes/intra/img/sf_ele.gif",
"groups": [
{
"id_group": "589",
"name": "Zeladoria"
}
],
"work_details": {
"work_schedule": "8h 12h",
"work_activities": "Zeladoria"
}
},
{
"id_user": "18833",
"name": "Portaria",
"user": "teste#domain.com",
"photo": "http://www.domain.com/themes/intra/img/sf_ele.gif",
"groups": [
{
"id_group": "33",
"name": "Portaria"
}
],
"work_details": {
"work_schedule": "8hs por dia. 8-12hs e 14-18hs",
"work_activities": "Supervisionar os trabalhos de conservação"
}
}
],
"boardMembers": [
{
"id_user": "8189",
"name": "Ana Maria",
"user": "8189",
"photo": "http://www.domain.com/themes/intra/img/sf_ela.gif",
"groups": [
{
"id_group": "722",
"name": "Subsíndico"
}
]
},
{
"id_user": "11442",
"name": "Luciana Zath",
"user": "lzath#mail.com",
"photo": "http://www.domain.com/themes/intra/img/sf_ela.gif",
"groups": [
{
"id_group": "1456",
"name": "Conselho fiscal"
}
]
}
]
}
}
}
}
Because manager is only one record, i can't get it with ng-repeat in this code
<div class="card" ng-repeat="(manager, name) in items">
<pre>{{name}}</pre>
</div>
JSON returns all data, but i need return only manager data, for example:
Name, User (email) and photo
And controller:
// Controller of about.
appControllers.controller('aboutCtrl', function($scope, $mdBottomSheet, $mdToast, $mdDialog, About) {
About.get(function(data) {
$scope.items = data.return.items;
console.log(data);
})
}); // End of about controller.
employees and boardMembers works fine with ng-repeat, but single record for manager, not
appControllers.controller('aboutCtrl', function($scope, $mdBottomSheet, $mdToast,
$mdDialog, About) {
About.get(function(data) {
$scope.items = data.return.items;
$scope.manager = data.return.items.users.manager;
console.log(data);
})
}); // End of about controller.
in html:
<p>{{manager.name}}</p>
<p>{{manager.user}}</p>
If manager is always a single object just do:
Manager: {{items.users.manager.name}}
Then repeat over the employees array
<div ng-repeat="employee in items.users.employees">
Employee: {{employee.name}}
You can only iterate through a list of items using ng-repeat if items are an array. In your JSON, items are an object, so you will not get manager name. Just use {{items.users.manager.name}} to get manager name. On the other hand you could use ng-repeat to iterate over items.users.employees, because it's employees property is an array.
<div class="card" ng-repeat="employee in items.users.employees">
<pre>{{employee.name}}</pre>
</div>
You can access it with
{{items.users.manager}}

AngularJS - How do I filter an array of 'deep' objects given an array of values to filter by?

I am trying to filter my data which I am getting from a HTTP GET endpoint by an array of values
filters = ['Full Time', 'LinkedIn', ...]
The general structure of the response I am getting back is an array of objects where each object can look like this:
{
"preferences": {
"jobType": {
"type": "Full Time"
}
},
"profile": {
"additionalinfo": {
"organization": [
{
"name": "Google"
},
{
"name": "LinkedIn"
}
],
"university": [
{
"name": "UC Berkeley",
"degrees": [ {"name": "Computer Engineering"}]
}
}
}
}
So if I filter by ["Google", "Full Time"], the above object should be included.
Is there a built in filter to handle this?
I am having trouble writing the custom filter to handle such a heavily nested object.
Any ideas on how to implement this?
You can use built in filter like this jsfiddle
var myApp = angular.module("myApp", []);
myApp.controller("myCtrl", function($scope) {
$scope.data = [{
"preferences": {
"jobType": {
"type": "Full Time"
}
},
"profile": {
"additionalinfo": {
"organization": [{
"name": "Google"
}, {
"name": "LinkedIn"
}],
"university": [{
"name": "UC Berkeley",
"degrees": [{
"name": "Computer Engineering"
}]
}]
}
}
}, {
"preferences": {
"jobType": {
"type": "Remote"
}
},
"profile": {
"additionalinfo": {
"organization": [{
"name": "Yandex"
}, {
"name": "LinkedIn"
}],
"university": [{
"name": "UC Berkeley",
"degrees": [{
"name": "Computer Engineering"
}]
}]
}
}
}];
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular.min.js"></script>
<body ng-app="myApp" ng-controller="myCtrl">
<h3>Jobs</h3>
<input ng-model="filterModelJobType" placeholder="filter jobType">
<input ng-model="filterModelJob" placeholder="filter job">
<table class="table table-striped table-bordered">
<tbody>
<tr ng-repeat="x in data|filter:{profile: {additionalinfo:{organization:{name:filterModelJob}}},preferences: {jobType:{type:filterModelJobType}}}">
<td>{{ $index + 1 | number }}</td>
<td class="text-center">{{ x.preferences.jobType.type }}</td>
<td class="text-left">
<div ng-repeat="org in x.profile.additionalinfo.organization">
<hr> {{org.name}}
</div>
</td>
</tr>
</tbody>
</table>
</body>
In the latest version of AngularJS
If there is nested object then
var foo = $filter('filter')($scope.welcome, {
additionalinfo: { name: 'google' }
});
Reference: GitHub issue

angular predicate filter not returning element

I'm trying to use a predicate function to filter some items because the object structure might be a little too deep for straight template filtering. I have an array of items that I'm tring to filter based on user selected region and user selected country. When I filter the items in the template with the selected region the correct items are rendered. However, I need to filter deeper i.e., the user selects countries of the selected region. The predicate function appears to be filtering the items correctly i.e., printing to console, but the items are not rendering in the template.
{
"id": 2,
"name": "my test app",
"version": "1.0.0",
"regions": [
{
"id": 11,
"name": "LATIN_AMERICA",
"timeZone": "UTC+8",
"selected": true,
"countries": [
{
"id": 47,
"name": "Brazil",
"timeZone": "UTC+08:00",
"isoCode": "BR",
"selected": false
},
{
"id": 46,
"name": "Argentina",
"timeZone": "UTC+08:00",
"isoCode": "AR",
"selected": true
}
]
}
]
},
{
"id": 2,
"name": "my test app",
"version": "1.0.1",
"regions": [
{
"id": 11,
"name": "LATIN_AMERICA",
"timeZone": "UTC+8",
"selected": true,
"countries": [
{
"id": 47,
"name": "Brazil",
"timeZone": "UTC+08:00",
"isoCode": "BR",
"selected": true
},
{
"id": 46,
"name": "Argentina",
"timeZone": "UTC+08:00",
"isoCode": "AR",
"selected": false
}
]
}
]
}
function filterByRegionCountry(app) {
if(vm.selectedCountry !== undefined) {
angular.forEach(app.regions, function(appRegion, i) {
angular.forEach(appRegion.countries, function(appCountry, j) {
angular.forEach(vm.selectedCountry, function(selectedCountry, k) {
if((appCountry.name == selectedCountry.name) && appCountry.selected) {
console.log(app);
return true;
}
});
});
});
}
}
<select class="form-control" ng-model="vm.selectedRegion" ng-options="region.name for region in vm.filterRegions">
<option value="">--select region--</option>
</select>
<select class="form-control" ng-model="vm.selectedCountry" ng-options="country.name for country in vm.selectedRegion.countries" multiple>
<option value="">-- select country --</option>
</select>
<tr ng-repeat="app in vm.appVersions | filter:vm.filterByRegionCountry">
<td>
<label>{{ app.name }}</label>
</td>
<td>
<label>{{ app.version }}</label>
</td>
</tr>
// EDIT
Using .some (see answer below) or for loops with a break fixes the issue.
if(vm.selectedCountry !== undefined) {
for(var i = 0; i < app.regions.length; i++) {
for(var j = 0; j < app.regions[i].countries.length; j++) {
for(var k = 0; k < vm.selectedCountry.length; k++) {
if((app.regions[i].countries[j].name == vm.selectedCountry[k].name) && app.regions[i].countries[j].selected) {
console.log(app);
return true;
break;
}
}
}
}
}
Filter need either true or false to exevalue.
You are using angular forEach and there no break for forEach
Try javascript .some instead
like this
if (vm.selectedCountry) {
return app.regions.some(function (appRegion) {
return appRegion.countries.some(function (appCountry) {
return vm.selectedCountry.some(function (selectedCountry) {
if ((appCountry.name == selectedCountry.name) && appCountry.selected) {
console.log(app);
return true;
}
});
});
});
}
else
return false;

Resources