Adding strict search to multiple fields with a single textbox - javascript

Have a basic angular app,
HTML
<input type="text" ng-model="txt.name" />
<ul>
<li ng-repeat="d in data | filter: txt:strict">
<span>{{d.name}}</span>
<br />
<span>{{d.description}}</span>
<br />
<span>{{d.loremipsum}}</span>
<br />
</li>
</ul>
JS:
var app = angular.module('app', []);
app.controller("mc", function($scope){
$scope.data = [{
'name': 'asd',
'description': 'jiocioasdiasidjpoasdko',
'loremipsum': 'loremipsum'
}, {
'name': 'qwe',
'description': 'poqwpeqwpe',
'loremipsum': 'loremipsum'
}, {
'name': 'czxc',
'description': 'asdasdasd',
'loremipsum': 'loremipsum'
}]
});
I want to be able to search by both name and description, but not by loremipsum
How can I do this?
Example on JS BIN

You can create your custom filter please see demo below
var app = angular.module('app', []);
app.controller("mc", function($scope) {
$scope.data = [{
'name': 'asd',
'description': 'jiocioasdiasidjpoasdko',
'loremipsum': 'loremipsum'
}, {
'name': 'qwe',
'description': 'poqwpeqwpe',
'loremipsum': 'loremipsum'
}, {
'name': 'czxc',
'description': 'asdasdasd',
'loremipsum': 'loremipsum'
}];
});
app.filter('customFilter', function() {
return function(items, string) {
var filtered = [];
var stringMatch = new RegExp(string, 'i');
for (var i = 0; i < items.length; i++) {
var item = items[i];
if (stringMatch.test(item.name) || stringMatch.test(item.description)) {
filtered.push(item);
}
}
return filtered;
};
});
<html ng-app="app">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-controller="mc">
<input type="text" ng-model="txt.name" />
<ul>
<li ng-repeat="d in data | customFilter: txt.name">
<span>{{d.name}}</span>
<br />
<span>{{d.description}}</span>
<br />
<span>{{d.loremipsum}}</span>
<br />
</li>
</ul>
</body>
</html>

Here's an example using a custom function:
custom function solution
You will probably want to use match instead of === in the custom function.

Related

Uncheck all checkboxes based on another checkbox using Angularjs

I am trying to figure out that if the user checks N/A all the other boxes are unchecked (if they are checked). Below is what i have working, but I am not sure on how to uncheck those boxes and set them to false Any help is greatly appreciated.
var app = angular.module('MyApp', []);
app.controller('MyAppController', ['$scope',
function($scope) {
$scope.appliances = [{
Name: 'N/A'
},
{
Name: 'Computer',
ExcludedBy: 'N/A'
},
{
Name: 'TV',
ExcludedBy: 'N/A'
},
{
Name: 'Voice Assistant',
ExcludedBy: 'N/A'
}
];
$scope.myObj = {};
}
]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="MyApp">
<div ng-controller="MyAppController">
<div ng-repeat="app in appliances">
<input type="checkbox" value="{{ app.Name }}" ng-model="myObj[app.Name]" ng-disabled="myObj[app.ExcludedBy]"> {{ app.Name }}
</div>
</div>
</div>
You can use a ng-change to trigger a function to change the underlying content.
var app = angular.module('MyApp', []);
app.controller('MyAppController',['$scope',
function($scope) {
$scope.appliances = [
{
Name: 'N/A'
},
{
Name: 'Computer',
ExcludedBy: 'N/A'
},
{
Name: 'TV',
ExcludedBy: 'N/A'
},
{
Name: 'Voice Assistant',
ExcludedBy: 'N/A'
}
];
$scope.myObj = {};
$scope.checkForNA = function () {
if ($scope.myObj[$scope.appliances[0].Name]) {
$scope.myObj = {};
$scope.myObj[$scope.appliances[0].Name] = true;
}
}
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="MyApp">
<div ng-controller="MyAppController">
<div ng-repeat="app in appliances">
<input type="checkbox" value="{{ app.Name }}" ng-model="myObj[app.Name]" ng-disabled="myObj[app.ExcludedBy]" ng-change="checkForNA()">
{{ app.Name }}
</div>
</div>
</div>
Something like this
var app = angular.module('MyApp', []);
app.controller('MyAppController',['$scope',
function($scope) {
$scope.appliances = [
{
Name: 'N/A'
},
{
Name: 'Computer',
ExcludedBy: 'N/A',
IsSelected: false,
IsDisabled: false
},
{
Name: 'TV',
ExcludedBy: 'N/A',
IsSelected: false,
IsDisabled: false
},
{
Name: 'Voice Assistant',
ExcludedBy: 'N/A',
IsSelected: false,
IsDisabled: false
}
];
$scope.myObj = {};
$scope.checkAll = function(name, isSelected){
if(name === 'N/A'){
for(var i =0; i< $scope.appliances.length; i++){
if($scope.appliances[i].Name != name && $scope.appliances[i].ExcludedBy===name){
$scope.appliances[i].IsSelected = false;
$scope.appliances[i].IsDisabled = !isSelected;
}
}
}
};
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="MyApp">
<div ng-controller="MyAppController">
<div ng-repeat="app in appliances">
<input type="checkbox" ng-disabled="app.IsDisabled" ng-click="checkAll(app.Name, app.IsSelected)" ng-model="app.IsSelected">
{{ app.Name}}
</div>
</div>
</div>
In this case, DavidX's answer is correct. However, we can improve the way of verifying through the existence of the ExcludedBy attribute in a generic way using Array#find().
No necessarily, the first element of the array $scope.appliances will be N/A item.
var naItem = $scope.appliances.find(function(x) {
return x.ExcludedBy === undefined;
});
For this example I'm using the ng-change directive.
Something like this:
First example:
var app = angular.module('MyApp', []);
app.controller('MyAppController', ['$scope',
function($scope) {
$scope.appliances = [{
Name: 'N/A'
},
{
Name: 'Computer',
ExcludedBy: 'N/A'
},
{
Name: 'TV',
ExcludedBy: 'N/A'
},
{
Name: 'Voice Assistant',
ExcludedBy: 'N/A'
}
];
$scope.myObj = {};
$scope.check = function() {
var naItem = $scope.appliances.find(function(x) {
return x.ExcludedBy === undefined;
});
if ($scope.myObj[naItem.Name]) {
$scope.myObj = {};
$scope.myObj[naItem.Name] = true;
}
};
}
]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="MyApp">
<div ng-controller="MyAppController">
<div ng-repeat="app in appliances">
<input type="checkbox" value="{{ app.Name }}" ng-model="myObj[app.Name]" ng-disabled="myObj[app.ExcludedBy]" ng-change="check()"> {{ app.Name }}
</div>
</div>
</div>
Second example:
var app = angular.module('MyApp', []);
app.controller('MyAppController', ['$scope',
function($scope) {
$scope.appliances = [{
Name: 'Computer',
ExcludedBy: 'N/A'
},
{
Name: 'TV',
ExcludedBy: 'N/A'
},
{
Name: 'Voice Assistant',
ExcludedBy: 'N/A'
},
{
Name: 'N/A'
}
];
$scope.myObj = {};
$scope.check = function() {
var naItem = $scope.appliances.find(function(x) {
return x.ExcludedBy === undefined;
});
if ($scope.myObj[naItem.Name]) {
$scope.myObj = {};
$scope.myObj[naItem.Name] = true;
}
};
}
]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="MyApp">
<div ng-controller="MyAppController">
<div ng-repeat="app in appliances">
<input type="checkbox" value="{{ app.Name }}" ng-model="myObj[app.Name]" ng-disabled="myObj[app.ExcludedBy]" ng-change="check()"> {{ app.Name }}
</div>
</div>
</div>

AngularJS disable dropdown option which previously selected

var demoApp = angular.module('myApp', []);
demoApp.controller('QaController', function($scope, $http) {
$scope.loopData = [{}, {}];
$scope.questions = {
model: null,
availableOptions: [
{id: '1', name: 'What is your childhood name?'},
{id: '2', name: "What is your first school?"},
{id: '3', name: "What is your first job place?"},
{id: '4', name: "What is your pet name?"}
]
};
$scope.submit = function() {
$scope.result = $scope.loopData;
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="myApp">
<div class="wrapper wrapper-content middlealigen col-sm-12" ng-controller="QaController">
<form ng-submit="submit();">
<div ng-repeat="x in loopData">
<h5>Q. {{$index + 1}}</h5>
<select class="form-control" name="question-drop" id="question_dropdown" ng-model="x.question" ng-options="option.id as option.name for option in questions.availableOptions">
<option value="">Select Question</option>
</select>
<input type="text" placeholder="Enter Answer" name="answer" class="form-control" ng-model="x.answer" />
<div class="m-b"></div>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
<div ng-if="result">
<pre>{{result | json}}</pre>
</div>
</div>
</body>
Can you please check my code snippet. Here is two dropdown.
If I select What is your childhood name? from Q. 1 dropdown then this option should be disabled in the Q. 2 dropdown. How can I do that?
var demoApp = angular.module('myApp', []);
demoApp.controller('QaController', function($scope, $http) {
$scope.loopData = [];
$scope.loopData = [{
model: null,
question : "",
availableOptions: [
{id: '1', name: 'What is your childhood name?',disable : false},
{id: '2', name: "What is your first school?",disable : false},
{id: '3', name: "What is your first job place?",disable : false},
{id: '4', name: "What is your pet name?",disable : false}
]
},{
model: null,
question : "",
availableOptions: [
{id: '1', name: 'What is your childhood name?',disable : false},
{id: '2', name: "What is your first school?",disable : false},
{id: '3', name: "What is your first job place?",disable : false},
{id: '4', name: "What is your pet name?",disable : false}
]
}]
$scope.changItem = function(index,_id){
$scope.loopData = $scope.loopData.map(function(obj,i){
debugger
if(i > index){
obj.availableOptions.map(function(item){
if(item.id == _id ){
item.disable = true
}else{
item.disable = false
}
return item
})
}else{ debugger
obj.availableOptions.map(function(item){
debugger
if(item.id == _id ){
item.disable = true
}else{
item.disable = false
}
return item
})
}
return obj
});
}
$scope.submit = function() {
$scope.result = $scope.loopData;
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="myApp">
<div class="wrapper wrapper-content middlealigen col-sm-12" ng-controller="QaController">
<form ng-submit="submit();">
<div ng-repeat="x in loopData track by $index">
<h5>Q. {{$index + 1}}</h5>{{x.modelVal}}
<select
ng-change="changItem($index,x.question)" ng-model="x.question" >
<option value="">Select Question</option>
<option ng-disabled="option.disable" ng-repeat="option in x.availableOptions" value="{{option.id}}">{{option.name}}</option>
</select>
<input type="text" placeholder="Enter Answer" name="answer" class="form-control" ng-model="x.answer" />
<div class="m-b"></div>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
<div ng-if="result">
<pre>{{result | json}}</pre>
</div>
</div>
</body>
You might create a custom filter to be more generic (for more select inputs).
The filter could be:
.filter('excludeEqualAnswers', function() {
return function(input, index, selectedQuestions) {
if (!selectedQuestions[index].question) {
function notExistInSelectedQuestions(output) {
return !selectedQuestions.map(val => val.question).includes(output.id);
}
return input.filter(notExistInSelectedQuestions);
} else {
return input
}
}
})
Then you can filter the options of your select input based upon your custom filter like this:
<select class="form-control" name="question-drop" id="question_dropdown" ng-model="x.question" ng-options="option.id as option.name for option in questions.availableOptions | excludeEqualAnswers:$index:loopData">
<option value="">Select Question</option>
</select>
Here's a working fiddle

How to filter values in ng-repeat by partial string property?

I have this controller with products and filterStr variables:
app.controller('FooCtrl', function($scope) {
$scope.products = [
{ id: 1, name: 'Michael', data: 'Berlin' },
{ id: 2, name: 'Maria', data: 'Moscow'}
{ id: 3, name: 'Alex', data: 'Aragon'},
{ id: 4, name: 'Mara', data:'Paris' }
/*... etc... */
];
$scope.filterStr = 'ar';
});
Here ng-repeat:
<div ng-repeat="product in products | filter: { name: filterStr }">
In ng-repeat above I want to display objects only that has inside name property this combination of letters ar:
id: 2, name: 'Maria', data: 'Berlin'
id: 4, name: 'Mara', data:'Paris'
What is the best way to implement the desired filter in angularjs?
You can try custom filter
<div ng-repeat="product in products | search:'name':'ar' ">
{{product.name}}
</div>
app.filter('search', function() {
return function(input,key,searchText) {
var out = [];
angular.forEach(input, function(obj) {
if(obj[key]){
var text = obj[key].search(searchText)
if(text > 0) {
out.push(obj);
}
}
});
return out;
}
});
First: Many thanks to #vignesh for a great answer! The code #vignesh provided encourage me to make such an implementation in my own project!
Second: While trying to implement this filter myself, I've noticed that this solution can be improved a little bit more...
app.filter('search', function()
{
return function(list, field, partialString)
{
// if the search string is invalid or empty - return the entire list
if (!angular.isString(partialString) || partialString.length == 0) return list;
var results = [];
angular.forEach(list, function(item)
{
if (angular.isString(item[field]))
{
if (item[field].search(new RegExp(partialString, "i")) > -1)
{
results.push(item);
}
}
});
return results;
}
});
I then used it with a search input and a repeater
<input ng-model="myPartialSearchString" />
<div ng-repeat="item in items | search:'name':myPartialSearchString ">
{{item.name}}
</div>
you can use the filter function from angular:
<input type="text" placeholder="Search" ng-model="search.$">
<input type="checkbox" ng-model="strict"> Exact match only
<div ng-repeat="product in products | filter: filter:search:strict">

Filtering array based on selected checkboxes and select fields

How can I store the selected values of checkboxes and select elements and use a combination of these to filter a results array? e.g. think filtering by category Id, or displaying all results in the last X months.
After much research and trial and error I've got as far as this:
View Plunker or see the code below:
HTML within the 'refine' directive
<div class="filters">
<div class="filter">
<label for="maxage">Show results from</label>
<select name="maxage" id="maxage"
ng-options="option.name for option in refine.maxAge.options track by option.id"
ng-model="refine.maxAge.selected"
ng-change="filterResults()">
</select>
</div>
<div class="filter">
<div class="status-filter" ng-repeat="status in refine.statuses">
<label for="statusId{{ status.id }}">{{ status.name }}</label>
<input type="checkbox" name="status" value="{{ status.id }}" ng-change="filterResults()">
</div>
</div>
</div>
HTML of main page
<body ng-app="app">
<div ng-controller="ListCtrl" data-county-parish-id="1478">
...
<main class="page-content columns medium-9 medium-push-3">
...
<spinner name="planningSpinner" show="true">
<div class="loadingPanel block"></div>
</spinner>
<div class="planning">
<div class="no-results ng-hide" ng-show="filteredResults.length === 0">
<p>No results.</p>
</div>
<h4>Number of records: {{ filteredResults.length }}</h4>
<div ng-repeat="appl in filteredResults">
<hf-application info="appl"></hf-application>
</div>
</div>
...
</main>
<aside class="sidebar columns medium-3 medium-pull-9">
...
<div hf-refine-results info="refine"></div>
</aside>
...
</div>
</body>
JS
var app = angular.module('app', []);
// results filter
angular.module('app').filter('results', ['$filter', function($filter) {
return function (input, refine) {
var filterParams = {};
// start off filtering with the outsideBoundary parameter
filterParams.outsideBoundary = refine.outsideBoundary;
// add 'show results from' filter
//var adjustedDate = new Date();
//adjustedDate.setMonth(adjustedDate.getMonth() - refine.maxAge.selected.id);
//filterParams.receivedDate = $filter('date')(adjustedDate, 'yyyy/MM/dd');
return $filter('filter')(input, filterParams);
}
}]);
// Controller
angular.module('app').controller('ListCtrl',
['$scope', '$filter', '$attrs', 'appService', 'resultsFilter', function ($scope, $filter, $attrs, appService, resultsFilter) {
$scope.applications = [];
$scope.refine = {
statuses: {
options: [
{ id: 1, name: 'Unknown' },
...
{ id: 6, name: 'Appealed' }
],
selected: [2, 3]
},
maxAge: {
options: [
{ id: '1', name: 'Last month' },
... // 1 to 12 months
{ id: '12', name: 'Last 12 months' }
],
selected: { id: '6', name: 'Last 6 months' }
},
...
};
$scope.filterResults = function () {
$scope.filteredResults = resultsFilter($scope.applications, $scope.refine);
};
/* get data from appService */
appService.getApplications({
status: 3,
countyparish: parseInt($attrs.countyParishId),
postcode: '',
distance: 5,
pagesize: 100
})
.then(function (data) {
$scope.applications = data;
$scope.filteredResults = resultsFilter(data, $scope.refine);
});
}]);
I appreciate this question has been asked many times, however I haven't found an answer for my question(s) since most examples are very simple expressions within ng-repeat.
This example work with multi checkbox. For filtering with outher select use same logic. Look
'use strict';
var App = angular.module('clientApp', ['ngResource', 'App.filters']);
App.controller('ClientCtrl', ['$scope', function ($scope) {
$scope.selectedCompany = [];
$scope.companyList = [{
id: 1,
name: 'Apple'
}, {
id: 2,
name: 'Facebook'
}, {
id: 3,
name: 'Google'
}];
$scope.clients = [{
name: 'Brett',
designation: 'Software Engineer',
company: {
id: 1,
name: 'Apple'
}
}, {
name: 'Steven',
designation: 'Database Administrator',
company: {
id: 3,
name: 'Google'
}
}, {
name: 'Jim',
designation: 'Designer',
company: {
id: 2,
name: 'Facebook'
}
}, {
name: 'Michael',
designation: 'Front-End Developer',
company: {
id: 1,
name: 'Apple'
}
}, {
name: 'Josh',
designation: 'Network Engineer',
company: {
id: 3,
name: 'Google'
}
}, {
name: 'Ellie',
designation: 'Internet Marketing Engineer',
company: {
id: 1,
name: 'Apple'
}
}];
$scope.setSelectedClient = function () {
var id = this.company.id;
if (_.contains($scope.selectedCompany, id)) {
$scope.selectedCompany = _.without($scope.selectedCompany, id);
} else {
$scope.selectedCompany.push(id);
}
return false;
};
$scope.isChecked = function (id) {
if (_.contains($scope.selectedCompany, id)) {
return 'icon-ok pull-right';
}
return false;
};
$scope.checkAll = function () {
$scope.selectedCompany = _.pluck($scope.companyList, 'id');
};
}]);
angular.module('App.filters', []).filter('companyFilter', [function () {
return function (clients, selectedCompany) {
if (!angular.isUndefined(clients) && !angular.isUndefined(selectedCompany) && selectedCompany.length > 0) {
var tempClients = [];
angular.forEach(selectedCompany, function (id) {
angular.forEach(clients, function (client) {
if (angular.equals(client.company.id, id)) {
tempClients.push(client);
}
});
});
return tempClients;
} else {
return clients;
}
};
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular-resource.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.4/underscore-min.js"></script>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<link rel="stylesheet" type="text/css" href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.0/css/bootstrap-combined.min.css">
<div ng-app="clientApp" data-ng-controller="ClientCtrl">
<ul class="inline">
<li>
<div class="alert alert-info">
<h4>Total Filtered Client: {{filtered.length}}</h4>
</div>
</li>
<li>
<div class="btn-group" data-ng-class="{open: open}">
<button class="btn">Filter by Company</button>
<button class="btn dropdown-toggle" data-ng-click="open=!open"><span class="caret"></span>
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenu">
<li><a data-ng-click="checkAll()"><i class="icon-ok-sign"></i> Check All</a>
</li>
<li><a data-ng-click="selectedCompany=[];"><i class="icon-remove-sign"></i> Uncheck All</a>
</li>
<li class="divider"></li>
<li data-ng-repeat="company in companyList"> <a data-ng-click="setSelectedClient()">{{company.name}}<span data-ng-class="isChecked(company.id)"></span></a>
</li>
</ul>
</div>
</li>
</ul>
<hr/>
<h3>Clients Table:</h3>
<table class="table table-hover table-striped">
<thead>
<tr>
<th style="width:10%">#</th>
<th style="width:20%">Name</th>
<th style="width:40%">Designation</th>
<th style="width:30%">Company</th>
</tr>
</thead>
<tbody>
<tr data-ng-repeat="client in filtered = (clients | companyFilter:selectedCompany)">
<td>{{$index + 1}}</td>
<td><em>{{client.name}}</em>
</td>
<td>{{client.designation}}</td>
<td>{{client.company.name}}</td>
</tr>
</tbody>
</table>
</div>

Angular Js: How do I select an expression in an array based on ID?

How do I print an expression of an array based on it's assigned id? I have two arrays, one with the id of 11 and the other with 12. How do I get the name expression of the array with the property of 12?
Below is the services module, controller and HTML
http://jsfiddle.net/ADukg/4705/
var myApp = angular.module('myApp',[]);
function MyCtrl($scope, myProperties) {
$scope.name = 'StackOverflow';
$scope.myProperties = myProperties;
};
myApp.factory('myProperties', function() {
var myProperties = [
{
'name': '3 Bedroom Fixer Upper',
'city': 'Santa Rosa',
'id': 11,
'state': 'CA',
'date_added': '2/3/14',
'completion_status': '80%',
'imgURL': 'http://dfon12yb6dcdf.cloudfront.net/product/kr4f0uv5tkd6slvmn7r9j4h4jj/w1024x683.jpg?v=4',
},
{
'name': '2 Bedroom Condo',
'city': 'Vallejo',
'id': 12,
'state': 'CA',
'date_added': '4/10/20',
'completion_status': '50%',
'imgURL': 'http://dfon12yb6dcdf.cloudfront.net/product/kr4f0uv5tkd6slvmn7r9j4h4jj/w1024x683.jpg?v=4',
},
]
//return the array here
return myProperties
});
<div ng-controller="MyCtrl">
<h1>Hello, {{name}}!</h1>
<br>
<ul ng-repeat="property in myProperties">
<li>{{property.name}}</li>
</ul>
<br>
<h3>{{property.id[12]}}</h3>
</div>
You can use angular's forEach function to compare an ID with each object in an array. Here's the relevant bit.
$scope.findObj = function(searchId)
{
var resultObj;
angular.forEach(myProperties, function(obj)
{
if ( obj.id == searchId)
{
resultObj = obj;
}
});
return resultObj;
};
Demo Plunkr is here

Categories

Resources