Filter and auto selected dropdown angularjs - angularjs

I am new to angularjs and still learning things. I have this code below. What I am aiming here is to load the data into the dropdown from the database. For example the data from the database is New Construction I want to load all data from LoadDropdown function and the New Construction is selected as default.
HTML
<select name="ScopeofWork" class="form-control" ng-model="drpScopeWork" ng-options="SoW as SoW.label for SoW in ScopeOfWorkList">
<option value="" selected hidden></option>
</select>
JS
function LoadDropdown() {
$scope.ScopeOfWorkList = [{ value: 'New Construction', label: 'New Construction' },
{ value: 'Erection', label: 'Erection' },
{ value: 'Addition', label: 'Addition' },
{ value: 'Renovation', label: 'Renovation' },
{ value: 'Repair', label: 'Repair' }];
}
fnLoadDropdown();
function fnLoadDropdown() {
var url = '/AccessoryGroundPreparation/LoadScopeofWork';
$http({
method: "post",
url: url,
//data: { "ScopeOfWork": ScopeOfWork, "projectID": projectID }
}).then(function (res) {
var data = res.data;
if (data.data == null)
LoadDropdown();
else {
// $scope.drpScopeWork = $scope.ScopeOfWorkList[0];
$scope.drpScopeWork = data.data;
}
});
}

Use ng-init to assign a value to your model drpScopeWork form 0 index of your array like ng-init="drpScopeWork = ScopeOfWorkList[0].value"
Here is working code snippet:
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.ScopeOfWorkList = [{
value: 'New Construction',
label: 'New Construction'
},
{
value: 'Erection',
label: 'Erection'
},
{
value: 'Addition',
label: 'Addition'
},
{
value: 'Renovation',
label: 'Renovation'
},
{
value: 'Repair',
label: 'Repair'
}
];
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.9/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
<div>
<select name="ScopeofWork" class="form-control" ng-model="drpScopeWork" ng-options="SoW.value as SoW.label for SoW in ScopeOfWorkList" ng-init="drpScopeWork = ScopeOfWorkList[0].value">
</select>
</div>
</div>

Related

AngularJS ng-repeat unique is NOT working

I'm trying to print just the unique values of names but i'm unable to do that.
html code:
<div ng-controller="MyCtrl">
<div><input type="text" ng-model="nameFilter" placeholder="Search..." /></div>
<p ng-repeat="contact in contacts | orderBy: 'customer.name'| unique:'customer.name'">{{ contact.customer.name }}</p>
</div>
JS code:
var myApp = angular.module('myApp',[]);
function MyCtrl($scope) {
$scope.nameFilter = '';
$scope.contacts = [
{ id:1, customer: { name: 'foo', id: 10 } },
{ id:2, customer: { name: 'bar', id: 20 } },
{ id:3, customer: { name: 'foo', id: 10 } },
{ id:4, customer: { name: 'bar', id: 20 } },
{ id:5, customer: { name: 'baz', id: 30 } },
{ id:5, customer: { name: 'tar', id: 30 } },
{ id:5, customer: { name: 'got', id: 30 } },
{ id:5, customer: { name: 'man', id: 30 } },
{ id:5, customer: { name: 'baz', id: 30 } },
];
}
the jsfiddle is here: http://jsfiddle.net/nvarun123/0tgL7u6e/73/
This code is working if i remove unique from the ng-repeat.
Here you go, I used the unique filter in angular UI directives, link in the bottom. I have made a small change in the directive for implementing deep finding using string. The details are inside the references.
Here is a demo of the filter.
JSFiddle Demo
Change made inside unique filter.
var extractValueToCompare = function (item) {
if (angular.isObject(item) && angular.isString(filterOn)) {
return deepFind(item,filterOn);
} else {
return item;
}
};
As seen above I am implementing the deepFind function. The function is also provided below.
function deepFind(obj, path) {
var paths = path.split('.')
, current = obj
, i;
for (i = 0; i < paths.length; ++i) {
if (current[paths[i]] == undefined) {
return undefined;
} else {
current = current[paths[i]];
}
}
return current;
}
References:
Angular-UI unique filter
Javascript get deep value by passing path
Here's a simple custom filter that should meet your needs:
app.filter("unique", function thisFilter() {
return function(input){
var seen = { objectNames: [] };
return input.filter(function(obj){
return !seen.objectNames.includes(obj.customer.name)
&& seen.objectNames.push(obj.customer.name)
})
}
});

How to make first option selected in chosen select

I have chosen select, and my options gets by ng-model and ng-options. How I can make 1-st option selected when page is loaded?
<select chosen data-placeholder="Choose a project..."
ng-model="workflow.ProjectID"
ng-model-options="{ updateOn: 'blur' }"
ng-change="addActionButtons()"
ng-options="item.Id as item.Name for item in projectList">
<option value=""></option>
</select>
This is controller:
$scope.bindModel = function(data) {
$scope.model = data;
$scope.projectList = Global.projectList;
$scope.Task.push($scope.newTask());
};
$scope.Task = [];
$scope.newTask = function() {
return {
ProjectId: $scope.workflow.ProjectID = $scope.projectList[0].Id,
Date: getDate(),
TaskDescription: '',
TimeWorked: '1',
Note: '',
isSaved: false
};
};
You can use ng-init
Use
ng-init="workflow.ProjectID = projectList[0]['Id']"
On your controller, you have to put something like this :
//If workflow is never use in your controller, you have to declare it before
$scope.workflow = {};
$scope.workflow.ProjectID = $scope.projectList[0].Id;
You can try something like this :
//init list select
$scope.values = [{ id: 1, label: '1' }, { id: 2, label: '2' }, { id: 3, label: '3' }, { id: 10, label: '10' }, { id: 20, label: '20' }];
// in your html ng-init select the first items in values
<select ng-options="item.label for item in values track by item.id" ng-model="selected" ng-change="changeNumPerPage(selected)" ng-init="selected = values[0]"></select>

Angular checkbox filtering

Im trying to write a custom filter to filter by some checkboxes but havent had any luck, Ive found a solutions here but do not but none fit - would there be a alternative way of writing this checkbox functionality - have I structured this this Angular app incorrectly??
I recreated my little angular app in jsfiddle here (http://jsfiddle.net/samstimpson/vorg019v/):
var someApp = angular.module('someApp', []);
someApp.factory('searchFactory', function(){
return { query: "" }
});
someApp.factory('checkboxFactory', function() {
var checkboxFactory = [
{ name: 'item 1', item: 1 },
{ name: 'item 2', item: 2 },
{ name: 'item 3', item: 3 }
];
return checkboxFactory;
});
someApp.factory('listFactory', function() {
var listFactory = [
{ name: 'list item 01', item: 1 },
{ name: 'list item 02', item: 2 },
{ name: 'list item 03', item: 3 },
{ name: 'list item 04', item: 1 },
{ name: 'list item 05', item: 2 },
{ name: 'list item 06', item: 3 },
{ name: 'list item 07', item: 1 },
{ name: 'list item 08', item: 2 },
{ name: 'list item 09', item: 3 },
{ name: 'list item 10', item: 1 }
];
return listFactory;
});
someApp.filter('filterByCategory', function($filter) {
return function(listItems) {
console.log(listItems);
};
});
someApp.controller('checkboxCtrl', ['$scope','checkboxFactory', 'searchFactory', function($scope, checkboxFactory, searchFactory) {
$scope.checkboxes = checkboxFactory;
$scope.search = searchFactory;
}]);
someApp.controller('listCtrl', ['$scope','listFactory','searchFactory', function($scope, listFactory, searchFactory) {
$scope.listItems = listFactory;
//console.log(search);
$scope.search = searchFactory;
}]);
You need to add a couple of things.
First store the fact that a box is selected in your model :
<input type="checkbox" ng-model="checkbox.selected"/>
Then define your filterByCategory to filter :
someApp.filter('filterByCategory', function() {
return function(input, checkboxes) {
console.log(input, checkboxes);
var ret =[];
for (var i in input){
var match = false;
for (var j in checkboxes){
if (checkboxes[j].selected && checkboxes[j].item == input[i].item){
ret.push(input[i]);
}
}
}
if (ret.length > 0){
return ret;
} else {
return input;
}
};
});
Some explanations about this filter :
a filter function can take n arguments, the first one is the array to filter and the following (arg1, arg2, ...) are parameters you used.
array | filterName:arg1:arg2
We want to filter the listItems with the checkboxes, that's why I'm doing that
Then you need to let your ListController be aware of checkboxes :
someApp.controller('listCtrl', ['$scope','checkboxFactory','listFactory','searchFactory', function($scope, checkboxFactory,listFactory, searchFactory) {
$scope.checkboxes = checkboxFactory;
And finally use your filter in the list :
<li ng-repeat="item in listItems | filter: search.query | filterByCategory : checkboxes">
{{ item.name }}
</li>
All these modifications are available on the fiddle : http://jsfiddle.net/vorg019v/2/

How to parse model data in the view onto a javascript function in Angular

Assuming I have the following:
<button ng-repeat="{{item in items}}" ng-click="{{item.name}}Function()">{{item.name}}</button>
I need to be able to get the ng-click to dynamically change based on the item.name such as
firstItemFunction()
secondItemFunction()
etc.
If $scope has references to the functions:
$scope.items =
[
{ name: 'firstItemFunction' },
{ name: 'secondItemFunction' }
];
$scope.firstItemFunction = function () {
console.log('firstItemFunction');
};
$scope.secondItemFunction = function () {
console.log('secondItemFunction');
};
HTML:
<button ng-repeat="item in items" ng-click="this[item.name]()">
{{item.name}}
</button>
Demo: http://plnkr.co/edit/FSrGumlZqm4Rdku6I3X5?p=preview
Alternatively:
$scope.items = [{
name: 'firstItemFunction'
}, {
name: 'secondItemFunction'
}];
$scope.firstItemFunction = function() {
console.log('firstItemFunction');
}
$scope.secondItemFunction = function() {
console.log('secondItemFunction');
}
$scope.execute = function(action) {
$scope[action]();
};
And:
<button ng-repeat="item in items" ng-click="execute(item.name)">
{{item.name}}
</button>
Demo: http://plnkr.co/edit/6jATpgEAvFgTFXbvQ6IE?p=preview
If the functions are defined globally use HTML from above, inject $window and:
$scope.items = [{
name: 'firstItemFunction'
}, {
name: 'secondItemFunction'
}];
$scope.execute = function(action) {
$window[action]();
};
Demo: http://plnkr.co/edit/TinMbmvMTIQS4vptQMYf?p=preview
I would move the logic for determining which function to call to your javascript.
html
<button ng-repeat="{{item in items}}" ng-click="figureOutFunction(item)">{{item.name}}</button>
javascript
$scope.figureOutFunction(item){
if(item.name == "firstItem"){
firstItemFunction();
}
else if(item.name == "secondItem"){
secondItemFunction();
}
};
edit
If you want to avoid the switch, you can do it this way:
html
<button ng-repeat="{{item in items}}" ng-click="item.action()">{{item.name}}</button>
javascript
var firstItemFunction = function(){
...
};
var secondItemFunction = function(){
...
};
$scope.items = [{
name: 'firstItem',
action: firstItemFunction
}, {
name: 'secondItem',
action: secondItemFunction
}];
I would avoid creating unnecessary functions that call others.

exact filter in angular

In Angular, is there a way to modify the filter such that it only returns exact matches?
Example:
var words = [
{ title: "ball" },
{ title: "wall" },
{ title: "all" },
{ title: "alloy" }
];
var wordsFiltered = filter('filter')
(
words,
{
'title': 'all'
}
);
The above will match 'ball', 'wall', 'all' and 'alloy'. But I would like it to only match 'all'. Any way to change it?
UPDATE
Starting from AngularJS v.1.1.3 the exact filtering is provided natively:
Find words that exactly match title:
<input ng-model="match.title" />
<br>
and exactly match type:
<input ng-model="match.type" />
<hr>
<table>
<tr ng-repeat="word in words | filter:match:true">
<td>{{word.title}}</td>
</tr>
</table>
Plunker
Your question implies that you would want to match against multiple object properties so here's a filter that does that:
app.controller('AppController',
[
'$scope',
function($scope) {
$scope.match = {};
$scope.words = [
{ title: "ball", type: 'object' },
{ title: "wall", type: 'object' },
{ title: "all", type: 'word' },
{ title: "alloy", type: 'material' }
];
}
]
);
app.filter('exact', function(){
return function(items, match){
var matching = [], matches, falsely = true;
// Return the items unchanged if all filtering attributes are falsy
angular.forEach(match, function(value, key){
falsely = falsely && !value;
});
if(falsely){
return items;
}
angular.forEach(items, function(item){ // e.g. { title: "ball" }
matches = true;
angular.forEach(match, function(value, key){ // e.g. 'all', 'title'
if(!!value){ // do not compare if value is empty
matches = matches && (item[key] === value);
}
});
if(matches){
matching.push(item);
}
});
return matching;
}
});
<body ng-controller="AppController">
Find words that exactly match title:
<input ng-model="match.title" />
<br>
and exactly match type:
<input ng-model="match.type" />
<hr>
<table>
<tr ng-repeat="word in words | exact:match">
<td>{{word.title}}</td>
</tr>
</table>
</body>
PLUNKER
Try this :
var words = [
{ title: "ball" },
{ title: "wall" },
{ title: "all" },
{ title: "alloy" }
];
var wordsFiltered = filter('filter')
(
words,
{
'title': 'all'
},
true
);
You can use Regex to achieve a simple implementation:
<input ng-model="query" />
<tr ng-repeat="word in words | filter: myFilter">
In the controller:
$scope.myFilter = function (word) {
if ($scope.query === '') return true;
var reg = RegExp("^" + $scope.query + "$");
return reg.test(word.title);
};
I would create a new filter. Is this what you want?
HTML
<div ng-controller="MyCtrl">
{{words | exactMatch:'all'}} !
</div>
JavaScript
var myApp = angular.module('myApp',[]);
myApp.filter('exactMatch', function() {
return function(words, pattern) {
var result = [];
words.forEach(function (word) {
if (word.title === pattern) {
result.push(word);
}
});
return result;
}
});
function MyCtrl($scope) {
$scope.words = [
{title: "ball", other: 1},
{title: "wall", other: 2},
{title: "all", other: 3},
{title: "alloy", other: 4},
{title: "all", other: 5},
];
}
JsFiddle: jsfiddle
More information about custom filters: filters, creating custom filters and using filters
If you want use filter in Javascript instead of html you should look here: jsfiddle
I created my own filter.
<select
ng-model="selection.neType"
ng-options="option.NE_TYPE_ID as option.NAME for option in networkElementTypes">
<option value="">Todos</option>
</select>
<select
ng-model="selection.neTypeVendor"
ng-options="option.VENDOR_TYPE_ID as option.NAME for option in networkElementTypeVendors | exactMatch: {FK_NE_TYPE_ID: selection.neType}">
<option value="">All</option>
</select>
app.filter('exactMatch', function() {
return function(elements, pattern) {
var result = [];
var fieldSearch = Object.keys(pattern)[0];
elements.forEach(function (element) {
if (element[fieldSearch] == pattern[fieldSearch]) {
result.push(element);
}
});
return result;
}
});
angular-filter is a useful library of filters.
One of their filters is the where filter that does an exact match.

Resources