How to pre-select values in multi select input with AngularJS - angularjs

I have the following HTML:
<div ng-controller="CreateSpreadsheetCtrl as csCtrl" ng-init="csCtrl.init()">
<select multiple="multiple" style="height:100px;" class="form-control"
ng-model="csCtrl.Template.BusinessUnitMappings"
ng-options="department as department.LocalizedName for department in csCtrl.DepartmentMasters">
</select>
</div>
Inside the CreateSpreadsheetCtrl.init(), we are loading an array called "DepartmentMasters" (csCtrl.DepartmentMasters) which contains a list of objects (e.g. {Id:1, Name: "Department 1" }, {Id:2, Name: "Department 2" }).
Also in the init() method, we load this "csCtrl.Template" object, which has a property inside it called "BusinessUnitMappings" (csCtrl.Template.BusinessUnitMappings), which is an array of DepartmentMaster objects.
With the above code, it binds correctly to the model and when you change the selections, csCtrl.Template.BusinessUnitMappings is bound correctly.
However, when csCtrl.Template.BusinessUnitMappings is pre-loaded with an existing array of objects, it doesn't select it in the UI when the page initially loads.

Change the expression to :
ng-options="department as department.Name for department in csCtrl.DepartmentMasters track by department.Id"
Working Demo :
var myApp = angular.module('myApp', []);
myApp.controller('MyCtrl',function($scope) {
var ctrl = this;
ctrl.DepartmentMasters = [
{Id:1, Name: "Department 1" },
{Id:2, Name: "Department 2" },
{Id:3, Name: "Department 3" },
{Id:4, Name: "Department 4" },
{Id:5, Name: "Department 5" }
];
ctrl.Template = {
"BusinessUnitMappings" : [
{Id:2, Name: "Department 2" },
{Id:3, Name: "Department 3" }
]
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MyCtrl as csCtrl">
<select multiple="true" style="height:100px;" class="form-control"
ng-model="csCtrl.Template.BusinessUnitMappings"
ng-options="department as department.Name for department in csCtrl.DepartmentMasters track by department.Id"></select>
</div>

Related

AngularJS second dropdown does not update when first dropdown changes

I'm creating a search page where the user can search for data using pre-selected search criteria listed in the first drop-down. In the example below those criteria are 'First Name', 'Country' and 'Nationality'.
When the user selects Country or Nationality, a second drop-down appears to select one of the countries/nationalities. To fill this drop-down i use ng-options with a variable inside that points to a string defined in the controller.
But when one of those two options is selected and you want to switch to the other, the second drop-down does not get updated. The value inside ngOptions does get updated in the HTML, just the data inside the dropdown isn't.
When you select 'First Name' in between there is no issue. Does anyone know what I can use so the values inside the second dropdown gets updated?
Below is my code and a working plunker: http://plnkr.co/edit/LYpOdoLpgiMeHxlGzmub?p=preview
var myApp = angular.module('myApp', []);
myApp.controller("SomeController", function($scope) {
var vm = this;
vm.search = {id:0, criteria: {}, value: ''};
vm.referenceData = {
countries: [
{COUNTRY_ID:1, COUNTRY_NAME: 'UNITED KINGDOM'},
{COUNTRY_ID:2, COUNTRY_NAME: 'AUSTRALIA'},
{COUNTRY_ID:3, COUNTRY_NAME: 'SOUTH AFRICA'},
{COUNTRY_ID:4, COUNTRY_NAME: 'NETHERLANDS'},
],
nationalities: [
{NATIONALITY_ID: 1, NATIONALITY_NAME: "BRITISH"},
{NATIONALITY_ID: 2, NATIONALITY_NAME: "AUSTRALIAN"},
{NATIONALITY_ID: 3, NATIONALITY_NAME: "SOUTH AFRICAN"},
{NATIONALITY_ID: 4, NATIONALITY_NAME: "DUTCH"},
]
};
vm.criteriaList = [
{ name: 'First Name', key: 'FIRST_NAME'},
{ name: 'Country', key: 'COUNTRY_ID', options:'o.COUNTRY_ID as o.COUNTRY_NAME for o in ctrl.referenceData.countries' },
{ name: 'Nationality', key: 'NATIONALITY', options:'o.NATIONALITY_ID as o.NATIONALITY_NAME for o in ctrl.referenceData.nationalities' }
];
});
<!DOCTYPE html>
<html>
<head>
<script data-require="angular.js#1.6.2" data-semver="1.6.2" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-app="myApp" ng-controller="SomeController as ctrl">
<p>Criteria:</p>
<select ng-model="search.criteria" ng-change="search.value = ''" ng-options="criteria as criteria.name for criteria in ctrl.criteriaList">
<option value="">- Select Criteria -</option>
</select>
<p>Value:</p>
<!-- TEXT INPUT -->
<input type="text" ng-model="search.value" placeholder="Search Value" ng-if="!search.criteria.options" />
<!-- DROPDOWN INPUT -->
<select ng-model="search.value" ng-if="search.criteria.options" ng-options="{{search.criteria.options}}"></select>
</html>
This is an easy fix you just need a variable that can if out the second dropdown everytime you switch. The dom needs something to force it to refresh since there isnt a scope.$apply happening.
Plunker Working
Try this:
var myApp = angular.module('myApp', []);
myApp.controller("SomeController", function($scope, $timeout) {
var vm = this;
vm.somVal = false; ///ADD THIS
vm.search = {id:0, criteria: {}, value: ''};
vm.triggerSomeVal = function(){ ///ADD THIS
vm.someVal = true;
$timeout(function(){vm.someVal = false}, 100)
};
vm.referenceData = {
countries: [
{COUNTRY_ID:1, COUNTRY_NAME: 'UNITED KINGDOM'},
{COUNTRY_ID:2, COUNTRY_NAME: 'AUSTRALIA'},
{COUNTRY_ID:3, COUNTRY_NAME: 'SOUTH AFRICA'},
{COUNTRY_ID:4, COUNTRY_NAME: 'NETHERLANDS'},
],
nationalities: [
{NATIONALITY_ID: 1, NATIONALITY_NAME: "BRITISH"},
{NATIONALITY_ID: 2, NATIONALITY_NAME: "AUSTRALIAN"},
{NATIONALITY_ID: 3, NATIONALITY_NAME: "SOUTH AFRICAN"},
{NATIONALITY_ID: 4, NATIONALITY_NAME: "DUTCH"},
]
};
vm.criteriaList = [
{ name: 'First Name', key: 'FIRST_NAME'},
{ name: 'Country', key: 'COUNTRY_ID', options:'o.COUNTRY_ID as o.COUNTRY_NAME for o in ctrl.referenceData.countries' },
{ name: 'Nationality', key: 'NATIONALITY', options:'o.NATIONALITY_ID as o.NATIONALITY_NAME for o in ctrl.referenceData.nationalities' }
];
});
<p>Criteria:</p>
<select ng-model="search.criteria" ng-change="search.value = ''; ctrl.triggerSomeVal()" ng-options="criteria as criteria.name for criteria in ctrl.criteriaList">
<option value="">- Select Criteria -</option>
</select>
<p>Value:</p>
<!-- TEXT INPUT -->
<input type="text" ng-model="search.value" placeholder="Search Value" ng-if="!search.criteria.options" />
<!-- DROPDOWN INPUT ADD !someVal-->
<select ng-model="search.value" ng-if="search.criteria.options && !ctrl.someVal" ng-options="{{search.criteria.options}}"></select>

filter by text in specifiec property

I have an array of objects, like those
{ name: "task1", owner: "david", des: "task1 description" },
{ name: "task2", owner: "Smith", des: "task2 description" },
{ name: "task1", owner: "david", des: "task1 description" },
also a select and textbox
and a table that shows them all.
i am looking a way to filter, the data in the table.
The user will select a value from drop-down and enter text in the textbox.
Then the table data will be filtered by text matches in selected value (object property) from drop-down.
Example:
choosing "name" from dropdown and write "task" in textbox will return all 3 items in array. text word is contained within all 3 records.
choosing "name" from dropdown and write "task1" in textbox will return record 1 and 3.
textbox value will be required for the filter to happen.
Can it be done with angularjs filter?
https://plnkr.co/edit/Afs7MOIziUOvFWzBY7qf?p=preview
You need to use ng-disabled property on text-box
Working Plunker
Html need to update
<input ng-model="filterdata[filterProperty]" type="text" ng-disabled="!filterProperty" />
At that point it's probably easiest to write a custom filter. Custom filters are very easy and straightforward and allow you to control all aspects of how and when the filter is applied. Here is a working sample for your case - it's not very robust because it will break if you try to filter a numeric property, but it gives you the gist and something to build on and customize for your needs.
angular.module('myApp', [])
.controller('myCtrl', function($scope) {
$scope.cards = [{
name: "task1",
owner: "david",
des: "task1 description"
},
{
name: "task2",
owner: "Smith",
des: "task2 description"
},
{
name: "task3",
owner: "Smith",
des: "task3 description"
},
{
name: "task4",
owner: "Davis",
des: "task4 description"
},
{
name: "task5",
owner: "Thomas",
des: "task5 description"
},
{
name: "task6",
owner: "david",
des: "task6 description"
}
];
})
.filter('myFilter', function() {
return function(items, property, value) {
// if items, property or value are missing return items by default
if (!items || !property || !value) {
return items;
}
// create an array to hold the matched items
var out = [];
angular.forEach(items, function(item) {
// see if the item property value contains the desired value
if (item[property].toLowerCase().includes(value.toLowerCase())) {
out.push(item);
}
});
// return the array of items
return out;
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.min.js"></script>
<body ng-app="myApp">
<div ng-controller="myCtrl">
<div>
<select ng-model="filterProperty">
<option value="">filter by</option>
<option value="name">name</option>
<option value="owner">owner</option>
<option value="des">des</option>
</select>
<input ng-model="filterData" type="text" />
</div>
<table style="border: 1px solid">
<tbody>
<tr>
<th>name</th>
<th>owner</th>
<th>description</th>
</tr>
<tr ng-repeat="x in cards | myFilter:filterProperty:filterData">
<td>{{x.name}}</td>
<td>{{x.owner}}</td>
<td>{{x.des}}</td>
</tr>
</tbody>
</table>
</div>
</body>

Preselected values for angular-schema-form

Does angular-schema-form have a method to show preselected values?
When the titleMap on the select will set an integer, preselected values will show. But if it will set an object, I found no way of showing the correct name.
Is there anything to tie the object to, like with ng-options where you can set an attribute to compare them with the "track by" clause?
ng-options="option as option.name for option in array track by option.id"
In my example code, cats1 will set an object, cats2 will set an integer.
HTML:
<body>
<div ng-controller="MainCtrl">
<div class="login-container">
<form name="myForm"
sf-schema="schema"
sf-form="form"
sf-model="model">
</form>
</div>
</div>
</body>
Controller:
app.controller('MainCtrl', ['$scope', function ($scope) {
$scope.form = [
{
key: 'cats1',
type: 'select',
titleMap: [
{value: {id: 0, name: "Leopard"}, name: "Leopard"},
{value: {id: 1, name: "Tiger"}, name: "Tiger"}
]
},
{
key: 'cats2',
type: 'select',
titleMap: [
{value: 0, name: "Leopard"},
{value: 1, name: "Tiger"}
]
}
];
$scope.schema = {
"type": "object",
"properties": {
"cats1": {
"title": "Cats",
"type": "object"
},
"cats2": {
"title": "Cats",
"type": "number"
}
}
};
$scope.model = {cats1: {id: 1, name: "Tiger"}, cats2: 1};
}]);
Here is a plunkr:
https://plnkr.co/edit/0hK5Hrc9GXklfRwa6fjE?p=preview

Ng-Options for objects in an array

Here I have a select, where I want to repeat the contacts on the supplier.
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="AppCtrl">
Hello {{name}}
<div ng-repeat="supplier in suppliers">
{{supplier.name}}
<select ng-options="contact.id as contact.name for contact in supplier.contacts">
</select>
</div>
</div>
<script>
var app = angular.module('app',[]);
//app.directive('appDirective', function() {});
//app.factory('appService', function() {});
app.controller('AppCtrl', ['$scope', function($scope){
$scope.name = "dave";
$scope.suppliers = [
{id: 0, name: "dave", contacts : [
{id: 0, name: 'c1'},
{id: 1, name: 'c2'},
{id: 2, name: 'c3'},
{id: 3, name: 'c4'},
]},
{id: 1, name: "Steve", contacts : [
{id: 0, name: 'c1'},
{id: 1, name: 'c2'},
{id: 2, name: 'c3'},
{id: 3, name: 'c4'},
]}
]
}]);
</script>
Here I have the controller.
How come this doesn't seem to work?
http://jsfiddle.net/gnosticdave/091vpadb/1/
contacts is part of each supplier - so your array is actually supplier.contacts
select ng-options="contact.id as contact.name for contact in supplier.contacts"
^^^^^^^^^^^^^^^^^^^^
Also, ngOptions needs an ngModel
Demo: http://jsfiddle.net/091vpadb/3/
Change:
<select ng-options="contact.id as contact.name for contact in contacts">
to:
<select ng-options="contact.id as contact.name for contact in supplier.contacts">

ng-repeat + array of arrays

In most cases people use:
$scope.fields = [
{name: "name", desc: "its name", required: "yes"},
{name: "surname", desc: "its surname", required: ""}
];
I prefer this type of array:
$scope.fields = [
["name", "its name", "required"],
["surname", "its surname", ""]
];
so I can easy use splice function to modify elements.
I created list of input fields like this:
<li class="ng-class:item[2]" ng-repeat="field in fields">
<div>{{field[1]}}: <input type="text" data-ng-model="field[0]" name="field[0]" id="field[0]" /> </div>
</li>
Can anyone explain why input fields are initially filled with name or surname values not empty?

Resources