I'm having trouble with filtering JSON entries by defined categories with a select option element. Any help is much appreciated.
What my App should do:
Load JSON data from file by http.get (working)
The JSON data contains a job title and a job category (and other data) for each entry
Read each of these entries from JSON into a list-tag on html (working)
filter this list by a job category by a select option element (not working)
I guess the problem lies somewhere in my controller function. But I'm quite new to angularjs so I couldn't find out what the problem is... Any help is much appreciated.
first two entries of my JSON file with the tag "categories" in it:
[{
"jobtitle":"Multimedia Producer",
"name":"A. Text",
"shortname":"atext",
"shortdescription":"Werbeagentur",
"team":"XXX",
"lookingfor":"XXX",
"jobdescription":"XXX",
"portfolio":"XXX",
"contact":"XXX" ,
"categories":"none"
},
{
"jobtitle":"Kameraassistent",
"name":"Movie & Art",
"shortname":"movie_art",
"shortdescription":"Corporate Movies and more...",
"team":"XXX",
"lookingfor":"XXX",
"jobdescription":"XXX",
"portfolio":"XXX",
"contact":"XXX",
"categories":"photography"
}]
The controller.js:
var myApp = angular.module('myApp', []);
myApp.controller('MyController', ['$scope', '$http', function ($scope, $http){
$http.get('js/data.json').success(function(data){
$scope.jobs = data;
$scope.catchange = 'categories'
});
}]);
Part of the HTML-page setup with the select option element:
<div ng-controller="MyController">
<span class="input">
<select ng-model="catchange" class="cs-select cs-skin-underline">
<option value="none">Suche nach Kategorien</option>
<option value="photography">Fotografie</option>
<option value="text">Text</option>
<option value="digital">Digital</option>
<option value="print">Print</option>
<option value="consulting">Beratung</option>
<option value="advertising">Werbung</option>
<option value="socialmedia">Social Media</option>
<option value="strategy">Strategie</option>
<option value="conception">Konzeption</option>
<option value="film">Film</option>
<option value="tv">TV</option>
</select>
</span>
</div>
<div class="searchlisting" ng-controller="MyController">
<ul class="portfolio-grid">
<li class="grid-item" ng-repeat="item in jobs | filter: catchange" data-jkit="[show:delay=300;speed=500;animation=fade]">
<img ng-src="img/searchlist/{{item.shortname}}_tn.jpg" alt="Photo of {{item.name}}">
<a class="ajax-link" href="single.html">
<div class="grid-hover">
<h1>{{item.jobtitle}}</h1>
<p>{{item.name}}</p>
</div>
</a>
</li>
</ul>
</div>
Many thanks for any help.
Cheers
catchange will be a string, and when you filter, you are iterating over each object that is a job. So really, you need to be comparing each job.categories against catchange model.
Therefore, when you are doing filter:catchange, you are comparing each job object against the selected string in catchange, where you need to be comparing job.categories to catchange. You can tell angular what to track an iterator by to make sure it is comparing, or you can do the following:
Write a filter function that returns a boolean. This is just one way
this will be the filter in the view, angular passes each job as a param
filter: filterCategory
This will be a function in your controller that needs to compare the incoming job category with the categories that need to be filtered out. Just have it return a boolean.
$scope.filterCategory = function(job){
return $scope.catchange.filter(category){
job.categories === category
}
}
edit: Above assumes multi-select options, where catchange is an array of selected options stored via string. If it only ever going to be a single category select then
$scope.filterCategory = function(job){
if($scope.catchange){
return job.categories === $scope.catchange
}
else {
return true
}
}
Try specifying the property name that you want filter:
<li class="grid-item" ng-repeat="item in jobs | filter: {categories: catchange}" data-jkit="[show:delay=300;speed=500;animation=fade]">
Related
I need to select option in combobox from ajax loaded data. That data comes as list of objects. The problem is that ng-option compares objects by reference and thus setting model to objects element results in appearing new empty option in combobox instead of selecting correct option.
The known workaround is to use track by expression.
And here is example code:
var myApp = angular.module("myApp", []);
myApp.controller("myCtrl", function($scope) {
$scope.roles =[
{ key:"administrator", value:"ROLE_ADMIN" },
{ key:"operator", value:"ROLE_OPERATOR" },
];
// this emulates data from server
// won't work without 'track by'
$scope.role={ key:"administrator", value:"ROLE_ADMIN" };
});
Template:
<body ng-app="myApp" ng-controller="myCtrl">
0: <input ng-model="roles[0].key" />
<br>
1: <input ng-model="roles[1].key" />
<br>
select role: <select ng-model="role" ng-options="r.key for r in roles track by r.value">
</select>
<pre>selected role={{role|json}}</pre>
</body>
Here another problem arises. When one selects role in combobox and then
changes it's "key" property in textbox, then selected role stays unchanged. So it looks like binding is suddenly gets broken.
https://jsfiddle.net/xLqackxw/8/
from Angular documentation https://docs.angularjs.org/api/ng/directive/ngOptions
<select ng-options="item as item.label for item in items track by item.id" ng-model="selected"></select>
So:
<select ng-model="role" ng-options="r as r.key for r in roles track by r.value"></select>
'$scope.role' value will be object like { key:"administrator", value:"ROLE_ADMIN" } or { key:"operator", value:"ROLE_OPERATOR" }
I'm trying to display a JSON response in a drop down list in the HTMl using Angular JS.
I'm trying to call "short name" in the agency drop down list in html.
Any ideas. Thanks in advance.
My JSON code
[{"id":1,"agencyCode":"006","agencyDescription":"null","shortName":"NJTA","cscId":1,"iagAgencyTypeId":4,"comments":"null","whoCreated":"admin","createdDate":"2016-06-13","whoUpdated":"admin","updatedDate":"2016-06-13"}]
HTML CODE
<div class="dashboard_searcharea">
<div class="col-md-3" ng-repeat="shortname in agencies"> Agency :
<select class="text_field_style smallfield">
<option value="shortname"> agencies: {{agencies.shortname}} </option>
</select>
</div>
<div class="col-md-3"> Events :
<select class="text_field_style smallfield">
</select>
</div>
Angular JS
Dashboard.controller('homeController',homeController);
function homeController($scope,$location,$http) {
$scope.dt = new Date();
$scope.popup1 = {
opened: false
};
$scope.open1 = function() {
$scope.popup1.opened = true;
};
$http.get("http://localhost:8080/EtbosAdmin/agencies")
.success(function(response) {
$scope.metrics=response.series[0].shortname;
To achieve your expected result please follow below steps
1.In Iteration use different name then the key value to avoid confusion ..for testing i have used JSON and variable x in agencies.
2.Key value is shortName , so we need to get value by x.shortName.
I have used the JSON in $scope.agencies for testing
<div class="dashboard_searcharea">
<div class="col-md-3" ng-repeat="x in agencies"> Agency :
<select class="text_field_style smallfield">
<option value="shortname"> agencies: {{x.shortName}} </option>
</select>
Codepen URL -http://codepen.io/nagasai/pen/EyKqMB which i have created for reference
I am applying filters to get the data of a particular field through a dropdown, but when I select any option the filter applied elements get removed. How can I resolve it?
HTML code:
<body ng-controller="MyCtrl">
<div>
<label>Country filter</label>
<input type="text" ng-model="countryFilter" />
<label>Order by</label>
<select ng-model="selectedOrder">
<option ng-repeat="option in options">{{option}}</option>
</select>
</div>
<ul>
<li ng-repeat="detail in details | filter:{loc : selectedOrder}">{{ detail.country }}</li>
</ul>
</body>
JS code:
var app = angular.module('plunker', []);
app.controller('MyCtrl', function($scope) {
// order by options
$scope.options = ['1', '2', '3'];
// all countries
$scope.details = [{
id:1, country:'Finland', address:'Mainstreet 2',detail:[{
loc:'1'
}]
},{
id:2, country:'Mexico', address:'Some address',detail:[{
loc:'2'
}]
},{
id:3, country:'Canada', address:'Snowroad 45',detail:[{
loc:'3'
}]
}];
});
I want to filter through options and loc value. Where am I going wrong?
You don't need to write a custom filter.
Change your filter to: filter:{detail: {loc:selectedOrder}}
I added <option value=""></option> to the dropdown and set $scope.selectedOrder = ""; in order to show all countries by default.
Codepen
filter:{prop:value} returns objects which have property prop at first level, it does not watch in object deeper. (When usual filter without params does it)
Your objects in array details do not have 'loc' property. So nothing fits filter.
You can not filter by exact property of 2nd and deeper levels of object with standard angular filter. Implement your own or change data.
I have been working on this way too long trying to figure it out.
<select class="form-control"
ng-model="question.sel"
ng-change="updateDropDownQuestion(question,question.sel)">
<option ng-repeat="answer in question.answers" ng-disabled="answer.notAnOption" value="{{answer.acode}}">{{answer.name}}</option>
<option style="display:none" value="NONE">NONE</option>
</select>
Then in my js file:
$scope.updateDropDownQuestion = function(question, answer) {
reset(question.code)
$scope.formData["SOLE/SELECTED_QUESTION"] = question.code
$scope.formData["SOLE/SELECTED_ANSWER"] = answer
$scope.formData[question.code+"/"+answer] = true
var questions = $scope.product.questions
for(i=0; i <questions.length;i++){
if(questions[i].code == question.code){
questions[i].sel = answer
break;
}
}
$scope.refresh()
};
the $scope.refresh() is where it changes back. This renders the screen.
no matter what I do it seems to render the previous state and not the current state of the drop down. This is because I am repainting the screen after the drop down changes.
It seems as though the when the screen repaints it is taking the original value first.
Any thoughts on how I can get the value to "stick" once set?
Do I need to fire some event afterwards?
From Angular official site:
Note: ngModel compares by reference, not value. This is important when binding to an array of objects. You might find this helpful to set the default values of your drop down. See an example below.
angular.module('demoApp', []).controller('DemoController', function($scope) {
$scope.options = [
{ label: 'one', value: 1 },
{ label: 'two', value: 2 }
];
// Although this object has the same properties as the one in $scope.options,
// Angular considers them different because it compares based on reference
$scope.incorrectlySelected = { label: 'two', value: 2 };
// Here we are referencing the same object, so Angular inits the select box correctly
$scope.correctlySelected = $scope.options[1];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="demoApp">
<div ng-controller="DemoController">
<div>
<h2>Incorrect</h2>
<p>We might expect the select box to be initialized to "two," but it isn't because these are two different objects.</p>
<select ng-model="incorrectlySelected"
ng-options="opt as opt.label for opt in options">
</select>
The value selected is {{ incorrectlySelected.value }}.
</div>
<div>
<h2>Correct</h2>
<p>Here we are referencing the same object in <code>$scope.correctlySelected</code> as in <code>$scope.options</code>, so the select box is initialized correctly.</p>
<select ng-model="correctlySelected"
ng-options="opt as opt.label for opt in options">
</select>
The value selected is {{ correctlySelected.value }}.
</div>
</div>
</body>
Try using ng-options to render option elements.
Something along these lines:
<select class="form-control"
ng-model="question.sel"
ng-change="updateDropDownQuestion(question,question.sel)"
ng-options="answer.acode as answer.name in question.answers">
</select>
It also depends on what updateDropDownQuestion is doing, can you provide that?
use ng-repeat but can't get option value!
plz help!
html:
<ul ng-controller="app">
<li ng-repeat="mainlist in mainlists">
<p>{{mainlist.name}}</p>
<select ng-options="mainlist.list for mainlist.list in mainlists.list">
<option value="">{{mainlist.list.name}}</option>
</select>
</li>
</ul>
this demo
js: just get {{mainlists.name}} not get {{mainlists.list.name}}
function app($scope) {
$scope.mainlists = [
{
"name":"main001",
"list":[
{
"no":"1",
"name":"sub1"
},{
"no":"2",
"name":"sub2"
}]
},
{
"name":"main002",
"list":[
{
"no":"2-1",
"name":"sub1"
},{
"no":"2-2",
"name":"sub2"
}]
}]
};
this demo
ngOptions directive requires a ngModel directive to be defined on select element.
This is not a documented pitfall, but it is visible from the source code
So, your selects will work if you add ngModel to them:
<select
ng-model="mainlist.value"
ng-options="item as item.name for item in mainlists.list"
>
</select>
Or, if you were not planning to wire up the selects with a model (very unusual case), than you might want to use ng-repeat with your select options:
<select>
<option ng-repeat="item in mainlist.list">{{item.name}}</option>
</select>