Dropdown filter in angularjs - angularjs

I have an array of data which I need to bind it to dropdown list in angularjs.
$scope.offerFilter = [ {title :'Matching Ticket' , Status : '1'},
{title :'Non-matched Ticket',Status : '2'},
{title :'Rejected Ticket',Status : '3'},
{title: 'Not Sale', Status: '0'}]
I have binded the title to my dropdown list. When I select the option from dropdown list my page not getting filtered. I don't know where I am going wrong.
My View:
<select ng-model="SelectedStatus" ng-options="type.Status as type.title for type in offerFilter" style="float:right;width:40%;font-family:'Segoe UI';font-size:12px;">
<option value="">All {{type.title}}</option>
</select>
<md-list-item dir-paginate="ticket in ticketInventoryList.data.hits.hits | itemsPerPage:10 | filter : SelectedStatus">
<div style="width:15%">
<img alt="{{ ticket._source.SeriesName }}" ng-src="{{ ticket._source.ImagePath }}" class="md-avatar" style="width:90%" />
</div>
</md-list-item>
My controller:
I have declared the ng-model variabe as $scope.SelectedStatus='';
Thanks in advance.

Hope it will be work for you
<select ng-model="SelectedStatus" ng-change="changeValue(SelectedStatus)" ng-options="type.Status as type.title for type in offerFilter" style="float:right;width:40%;font-family:'Segoe UI';font-size:12px;">
<option value="">All {{type.title}}</option>
</select>
Please this all code in controller
$scope.isShow=false;
$scope.changeValue=function(selectedValue){
if(condtion you want){
$scope.isShow=false;
$timeout(function(){
$scope.isShow=true;
},500);
}
}
<md-list-item dir-paginate="ticket in ticketInventoryList.data.hits.hits | itemsPerPage:10 | filter : SelectedStatus" data-ng-if="isShow">
<div style="width:15%">
<img alt="{{ ticket._source.SeriesName }}" ng-src="{{ ticket._source.ImagePath }}" class="md-avatar" style="width:90%" />
</div>
</md-list-item>
Your change to refresh directive when select value is changed.

Related

Vue v-for: Dynamicly fill HTML with event handler (#change) from an array into a component template

This is my current setup:
HTML
<question
v-for="question in questions"
v-bind:id="question.id"
v-bind:title="question.title"
v-bind:statement="question.statement"
v-bind:interaction="question.interaction"
#onchange-vg="onChangeVg"/>
</question>
Definition of <question>
var questionComponent = Vue.component('question', {
props: ['id', 'title', 'statement', 'interaction', 'currentQuestion'],
template: `
<div :id="'question-' + id">
<div class="flex my-3">
<div class="py-0"><span>{{ id }}</span></div>
<div>
<p>{{ title }}</p>
<div :class="{'hidden':(id !== this.$parent.currentQuestion), 'block':(id === this.$parent.currentQuestion)}">
<p>{{ statement }}</p>
<span v-html="interaction"></span>
</div>
</div>
</div>
</div>
`
});
Vue
var app = new Vue({
el: '#app',
data() {
return {
vg: null,
currentQuestion: 1,
questions: [
{
id: 1,
title: 'Question 1',
statement: 'Details for question 1',
interaction: `
<select ref="vb-art" #change="$emit('onchange-vg')">
<option disabled value="" selected>Make a choice</option>
<option value="red">Red</option>
<option value="blue">Blue</option>
</select>
`
},
{
title: 'Question 2',
statement: 'Details for question 2',
interaction: `
<select ref="vb-art" #change="$emit('onchange-vg')">
<option disabled value="" selected>Make a choice</option>
<option value="black">Black</option>
<option value="white">White</option>
</select>
`
},
],
}
},
methods: {
onChangeVerguetungsart() {
console.log("Value: " + event.target.value);
currentQuestion++;
},
},
});
Everything is rendered fine. My problem is, that the event handler #change in <select ref="vb-art" #change="$emit('onchange-vg')"> does not fire.
Whe I replace <span v-html="interaction"></span> whit the whole <select ref="vb-art" #change="$emit('onchange-vg')">...</select> code from interaction every thing works fine.
The interactions may be different from question to question. It could be an , a or just a simple link. That's why i try to put the code into the array and not to the component definition.
How can I solve this issue, so that <span v-html="interaction"></span> accepts the event handler from a code snippet that is delivered by an array value?
You should avoid v-html. v-html bind just plain HTML, not Vue directives.
For you case v-html is not necessary. Make array of options from interaction property and generate your markup by vue template.
interaction: [
{value: 'red', label: 'Red'},
{value: 'blue', label: 'Blue'}
]
and in your component
<select ref="vb-art" #change="$emit('onchange-vg')">
<option disabled value="" selected>Make a choice</option>
<option v-for="{value, label} in interaction" :key="value" :value="value">{{ label }}</option>
</select>
update:
IF you have dynamic content, then slot is your friend. (Refer docs
https://v2.vuejs.org/v2/guide/components-slots.html for more examples)
Your component:
<div>
<p>{{ title }}</p>
<div>
<p>{{ statement }}</p>
<slot />
</div>
</div>
And usage
<question
v-for="question in questions"
v-bind:id="question.id"
v-bind:title="question.title"
v-bind:statement="question.statement"
v-bind:interaction="question.interaction"
>
<select ref="vb-art" #change="onChangeVg">
<option disabled value="" selected>Make a choice</option>
<option value="red">Red</option>
<option value="blue">Blue</option>
</select>
</question>
Bonus is, that you don't need to emit anything.
Btw using this.$parent is also not qood idea. Your component is coupled with parent. Use props instead.

Anuglar js filter deep objects

I am stuck in a situation where i have to find the data using filter in ng-repeat
Situation :
Data is an array of objects with name and status and status has property a
now want to filter objects having property status.a as started and in progress
I have tried multiple solution
Sol1:
ng-repeat="item in items | filter: {status :{a:'Not Started'},status: {a:'In Progress'}}
returns result : status.a of In Progress only
Sol2:
<p ng-repeat="item in items | filter: {status :{a:'Not Started' , a:'In Progress'}}">
{{ item.name }}
</p>
returns same result : status.a of In Progress only
html
<div ng-controller="mainCtrl">
<h1>List 1</h1>
<ul>
<li class="clearfix">
<label>
<input ng-model="tracks.ns"
ng-true-value="'Not Started'"
ng-false-value="''"
type="checkbox">
Not started
</label>
</li>
<li class="clearfix">
<label> <input ng-model="tracks.ip" ng-true-value="'In Progress'" ng-false-value="''" type="checkbox">In-progress </label>
</li>
<li class="clearfix">
<label> <input ng-model="tracks.do" ng-true-value="'Done'" ng-false-value="''" type="checkbox">Done </label>
</li>
</ul>
{{tracks.ns}}
<p ng-repeat="item in filteredItems">{{ item.name }}</p>
<h1>List 2</h1>
<p ng-repeat="item in items | filter: {status :{a:'Not Started' , a:'In Progress'}}">{{ item.name }}</p>
</div>
js
$scope.items = [{
name: "Alvi",
status: {
a: 'Not Started'
}
}, {
name: "Krane",
status: {
a: 'Done'
}
}, {
name: "Tate",
status: {
a: 'In Progress'
}
}, {
name: "Lorus",
status: {
a: 'In Progress'
}
}];
$scope.tracks = {ns: '',ip: '',done : ''}
Questions:
Can I achieve the desire result without custom filter ?
If yes than how without custom filter?
plunker: http://plnkr.co/edit/njsoPu1LHLmNmEx6lCew?p=preview
Use a function in the filter expression:
<p ng-repeat="item in items | filter : customFn">
{{ item.name }} {{ item.status }}
</p>
JS
$scope.customFn = function(value, index, array) {
console.log(value, index, array);
if (!value) return true;
if (value.status.a == 'Not Started') return true;
if (value.status.a == 'In Progress') return true;
//else
return false;
}
For more information, see AngularJS Filter Component Reference - filter
The DEMO on PLNKR

My Bootstrap Multiselect is empty

I have installed the bower component in my angularjs application,
I have a multiselect
<select class="multiselect" id="mdf.modifier.id" multiple="multiple" >
<option disabled selected value> -- select {{mdf.modifier.max == 1 ? 'one' : 'multiple' }} -- </option>
<option ng-repeat="option in mdf.options" value="option.id" track by option.id>
{{ option.name | highlight:for_user }}, +{{ option.price }}
</option>
</select>
And calling the javascript method from my controller
$('.multiselect').multiselect();
My multiselect is getting out as an empty multiselect.
The ng-repeat does print some options I have checked.
Switch to angular-ui bootstrap and you will be fine. Throw jQuery out of your application. Finaly it should work like in this simple fiddle. Please check this "Thinking in AngularJS way" to learn more about not mixing jQuery with AngularJS.
View
<div ng-app="app" ng-controller="myCtrl">
<ui-select multiple ng-model="selected" theme="bootstrap" close-on-select="false" title="Choose a person">
<ui-select-match placeholder="Pick some ..">{{$item.value}}</ui-select-match>
<ui-select-choices repeat="val in values track by val.value">
<div ng-bind="val.value | highlight: $select.search"></div>
</ui-select-choices>
</ui-select>
</div>
AnuglarJS Application
var app = angular.module('app', ['ui.select']);
app.controller("myCtrl", function ($scope) {
$scope.values = [{
'key': 22,
'value': 'Kevin'
}, {
'key': 24,
'value': 'Fiona'
}];
$scope.selected = null;
});

Angular filter results when user clicks on repeat

I am trying to create an Angular filter that allows users to click on a record and have the filter then show only that one record within the same repeater.
For example, when a person searches for last name "knight," they see some results. Then, when the user clicks on the specific record they want, they should see only that one record displaying in the repeater.
My html is this:
<md-list-item class="md-3-line" ng-repeat="value in ctrl.results" ng-click="ctrl.showRecord(value)">
<div class="md-list-item-text" layout="column">
<h4>Employee Id: <b>{{ value.employeeId }}</b></h4>
<h4>NetId: <b>{{ value.netId }}</b></h4>
<p>Name: {{ value.preferredFirstName }} {{ value.preferredLastName }}</p>
</div>
</md-list-item>
and it passes the selected record to my controller in this function:
vm.showRecord = function (selectedRecord, ev) {
//need my filter here
};
I have looked over a number of the examples on filters, but I don't quite see how to make the filter update the very same repeat that the user clicked on.
** Edit to show answer based on Tom Chen's work **
For anyone doing this with controller as syntax, here is the answer.
html:
<md-list-item class="md-3-line" ng-repeat="value in ctrl.results | filter:ctrl.selectedId" ng-click="ctrl.showRecord(value.employeeId)">
<div class="md-list-item-text" layout="column">
<h4>Employee Id: <b>{{ value.employeeId }}</b></h4>
<h4>NetId: <b>{{ value.netId }}</b></h4>
<p>Name: {{ value.preferredFirstName }} {{ value.preferredLastName }}</p>
</div>
</md-list-item>
controller:
vm.showRecord = function (selectedRecord) {
vm.selectedId = selectedRecord;
};
You can achieve this simply by using angular filter expression like this:
<md-list-item class="md-3-line" ng-repeat="value in ctrl.results | filter:vm.selectedId" ng-click="ctrl.showRecord(value.employeeId)">
<div class="md-list-item-text" layout="column">
<h4>Employee Id: <b>{{ value.employeeId }}</b></h4>
<h4>NetId: <b>{{ value.netId }}</b></h4>
<p>Name: {{ value.preferredFirstName }} {{ value.preferredLastName }}</p>
</div>
</md-list-item>
and in your controller :
vm.showRecord = function (id) {
vm.selectedId = id;
};
UPDATED ANSWER WITH WORKING EXAMPLE
Here is an example in Plunker
You could do it with an ng-if
<md-list-item ng-if="!ctrl.selectedRecord || ctrl.selectedRecord === value" ng-repeat="value in ctrl.results" ng-click="ctrl.showRecord(value)">
...
</md-list-item>
JS
vm.showRecord = function (selectedRecord, ev) {
//if the record is already selected toggel it off
if(vm.selectedRecord === selectedRecord) {
vm.selectedRecord = undefined;
} else {
vm.selectedRecord = selectedRecord
}
};

Angularjs filter not null for an object in Select ng-options:

I am trying to filter out items which are objects & not null in angular 1.5.6.
I tried all options from this post.
Still cannot make it to work.
Only 'Sally' should be shown in the select
Here is the fiddle
HTML :
<div ng-app="myApp" ng-controller="myCtrl">
<br>
<select ng-model="a" ng-options="detail.name for detail in details | filter:{shortDescription:'!null'} track by detail.name">
</select>
<br>
New
<select ng-model="b" ng-options="detail.name for detail in details | filter:{shortDescription: ''} track by detail.name">
</select>
<br>
All
<select ng-model="c" ng-options="detail.name for detail in details | filter:{shortDescription: '!!'} track by detail.name">
</select>
<br>
Without any filter
<select ng-model="d" ng-options="detail.name for detail in details track by detail.name">
</select>
<!-- -->
</div>
Script :
function myCtrl($scope) {
$scope.details = [{
name: 'Bill',
shortDescription: null
}, {
name: 'Sally',
shortDescription: {'MyName':'A girl'}
}];
}
angular.module("myApp",[]).controller("myCtrl", myCtrl);
The problem is that filter:{shortDescription: ''} matches only primitives but not complex objects and shortDescription in your case is a nested object.
Therefore instead use filter:{shortDescription:{$:''}} like so:
<select ng-model="a"
ng-options="detail.name for detail in details | filter:{shortDescription:{$:''}} track by detail.name">
</select>
Please run this snippet to achieve your goal
function myCtrl($scope) {
$scope.details = [{
name: 'Bill',
shortDescription: null
}, {
name: 'Sally',
shortDescription: {'MyName':'A girl'}
}];
}
angular.module("myApp",[]).controller("myCtrl", myCtrl).filter('descFilter',descFilter);
function descFilter(){
return function(array,key){
var newArr = [];
for(var i = 0; i < array.length; i++){
if (array[i][key] != null){
newArr.push(array[i]);
}
}
return newArr;
};
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
<br>
With Filter:
<select ng-model="a" ng-options="detail.name for detail in details | descFilter:'shortDescription'">
</select>
<br>
Without any filter
<select ng-model="d" ng-options="detail.name for detail in details track by detail.name">
</select>
<!-- -->
</div>
In ngOptions the not null check is know to not work. Instead you can create a custom filter and use that.
Here is an example with a custom filter function.
http://jsfiddle.net/ivankovachev/bue59Loj/
The custom filter function:
$scope.isDescriptionNull = function(item) {
if (item.shortDescription === null) return false;
return true;
}
And how to use it:
<select ng-model="a" ng-options="detail.name for detail in (details | filter:isDescriptionNull) track by detail.name">
You have a little bug in your markup.
The filter expects to get a object property, expression, or comparator.
Official documentation:
{{ filter_expression | filter : expression : comparator : anyPropertyKey}}
So, what you are doing isn't a valid filter
<select ng-model="a"
ng-options="detail.name for detail in details | filter:{shortDescription:'!!'}} track by detail.name">
</select>

Resources