binding two selects angular - angularjs

I have two selects
The first one is for regions
and the second one for cities
The first one is filled with regions
Now i have a methode that brings cities by the id of the region .
I dont know how to get the idregion and put it into the params function
This is my first select
<div class="form-group">
<label for="">Region</label>
<select class="form-control"
[(ngModel)]="region" name="Region">
<option></option>
<option *ngFor="let region of
objectKeys(dropDownList2)|keys"
[value]="dropDownList2[region].idRegion">
{{dropDownList2[region].nomRegion}}
</option>
</select>
</div>
My services :
getville() {
return this.http.get(this.urltest + 'Villes');
}
getRegion() {
return this.http.get(this.urltest + 'Regions');
}
GetRegionVille(idRegion) {
return this.http.get(this.urltest + 'Villes/GetRegionVille/' + idRegion);
}
My component.ts :
getidregion() {
this.res.getRegion().subscribe(R => {
this.dropDownList2 = R as any;
});
}
getregionville() {
this.res.GetRegionVille(****i don t know how to get the idregion**** )
.subscribe(response => {
this.dropDownList = response as any;
});
}
this is my function
// GET: api/Villes
[HttpGet("GetRegionVille/{id}")]
public async Task<IActionResult> GetRegionVille([FromRoute] int id)
{
var req = from v in _context.Villes
join r in _context.Regions
on v.IdRegion equals r.IdRegion
where r.IdRegion == id
select new {v.NomVille };
return Ok(req);
}
My select of the cities :
<div class="form-group">
<label for="">Ville</label>
<select class="form-control" name="Ville"
[(ngModel)]="ville">
<option></option>
<option *ngFor="let ville of objectKeys(dropDownList) |
keys"
[value]="dropDownList[ville].idVille">
{{dropDownList[ville].nomVille}}
</option>
</select>

The selected value will be in region variable as you state [(ngModel)]="region" and you can use (ngModelChange)="onChange($event)" to get an event when value changes
I am not sure if using two way data binding with (ngModelChange) is efficient, so please see this answer How can I get new selection in "select" in Angular 2?

Related

multiselect dropdown in angularjs only works on initialization of Controller

I am using jquery, bootstrap multi-select dropdown. I want to populate multi-select dropdown (talukas) on selectionChange event of other normal (single-select) dropdown (city). I am not able to figure out why the multi select dropdown populates on initial load of a controller and why not on selection change of other dropdown. Can you please help me. Thank you.
Scenario - 1 => This works fine
<div ng-controller="tempController" ng-init="initializeController()" ng-cloak>
<select id="multiSelect" name="multiSelect" multiselect=""
multiple="" ng-model="selectedTalukas" ng-options="option.talukaId as
option.label for option in talukas"></select>
</div>
// .js
$scope.selectedTalukas = [];
$scope.initializeController = function () {
$scope.talukas = [
{ talukaId: 1, label: 'Taluka1' },
{ talukaId: 2, label: 'Taluka2' },
{ talukaId: 3, label: 'Taluka3' }
]
}
Scenario - 2 => This DO NOT works fine - WHY
<select id="city" class="form-control select2" name="ddlCity" ng-model="c" ng-options="c as c.name for c in city | orderBy:'name'"
ng-change="selectedCityChange(c)" >
</select>
<select id="multiSelect" name="multiSelect" multiselect=""
multiple="" ng-model="selectedTalukas" ng-options="option.talukaId as
option.label for option in talukas"></select>
$scope.selectedCityChange = function (selectedValue) {
if (selectedValue !== undefined) {
$scope.selectedCity = selectedValue;
$scope.selectedCityId = selectedValue.cityId;
$scope.ajaxPost(selectedValue.cityId,
'/api/Taluka/getTalukasForSelectedCity',
$scope.selectedCityChangeComplete,
$scope.selectedCityChangeError);
}
};
$scope.selectedCityChangeComplete = function (response) {
$scope.talukas = response.data.talukaMasters;
}

Why getting value like this [1] in AngularJS

I need to get id from table but I am getting id like this [1]. I need to get 1 only.
Controller
public JsonResult GetLineManagerId(string LineManagerId)
{
var lineManagerId = db.Employees
.Where(x => x.FirstName == LineManagerId)
.Select(x =>x.Id);
return Json(lineManagerId);
}
Angular
$scope.GetLineManagerId = function (LineManagerId) {
$http.get('/Official/GetLineManagerId?LineManagerId=' + LineManagerId).then(function (data) {
console.log(data);
$scope.lineManagerId = data.data;
$scope.empModel.lineManagerId = $scope.lineManagerId[0].lineManagerId;
});
};
html
<select ng-model="empModel.name" id="" name="Name" class="form-control"
ng-change="GetLineManagerId(empModel.name)"
ng-click="GetLineManagerId(empModel.name)"
ng-options="d.name as d.name for d in name">
<option></option>
</select>
<select ng-model="empModel.id" id="" name="Id" class="form-control"
>
<option>{{lineManagerId}}</option>
</select>
when I click on 1st dropdown I get id like this [1].. I need to get number only like this 1
I need to get id number in dropdown, also if someone help me to get id in text input instead of using dropdown.
Try this, Please don't use ng-click here
<select ng-model="empModel.name" id="" name="Name" class="form-control"
ng-change="GetLineManagerId(empModel.name)"
ng-options="d.name as d.name for d in name">
<option></option>
Load linemanager using this
<select ng-model="empModel.id" id="" name="Id" class="form-control"
ng-options="d.lineManagerId as d.lineManagerId for d in lineManagerId"
>
<option></option>
</select>
your other portion will remain unchanged I think
You are returning an array/enumeration instead of a single value.
public JsonResult GetLineManagerId(string LineManagerId)
{
var lineManagerId = db.Employees
.Where(x => x.FirstName == LineManagerId)
.Select(x =>x.Id); // returns an IEnumerable<T> for whatever Id is
return Json(lineManagerId);
}
You have to select a single result like
var lineManagerId = db.Employees
.Where(x => x.FirstName == LineManagerId)
.Select(x =>x.Id)
// returns first value or default, i.e. 0 for int, null for string
.FirstOrDefault();

Remove select options based on button click in angular js

In my app i have a select html which has following options
"Addition","Deletion","Duplicate","Member Duplicate"
Above drop down page is common for both add and edit screen. As of now if we come from any addition click or edit click drop-down has all options. (Note: drop-down binds at the time of loading page itself. we will show/hide depending on click)
As per new requirement I need to remove all other options except "Addition" in addition click and remove "Addition" option in edit click.
select html:
<select name="ReasonID" required ng-model="member.ReasonID" class="form-control" ng-options="reason.ID as reason.Description for reason in reasons |orderBy: reason.Description"></select>
Js
$scope.manageMember = function (member) {
$scope.showGrid = false;
$scope.showForm = true;
reset();
$scope.memberTemp = member;
angular.extend($scope.member, member); };
Please let me know if you need more details from my end.
Update :
Here the full sample code and working demo with dummy data.
HTML
<div ng-app>
<h2>Todo</h2>
<div ng-controller="TodoCtrl">
<select name="ReasonID" required ng-model="member.ReasonID" class="form-control" ng-options="reason.ID as reason.Description for reason in reasons |orderBy: reason.Description"></select>
<br/>
<input type="button" ng-click="manageMember(undefined)" value="add"/>
<input type="button" ng-click="manageMember('bla bla bla')" value="edit"/>
</div>
</div>
JS
function TodoCtrl($scope) {
$scope.reasons = [{ID:1,Description :"Addition"}, {ID:2,Description :"Deletion"},{ID:3,Description :"Duplicate"},{ID:4,Description :"Member Duplicate"}];
var reasonsTemp =angular.copy($scope.reasons);
$scope.manageMember = function (member) {
console.log(reasonsTemp)
$scope.reasons=reasonsTemp;// assign global object to model
$scope.showGrid = false;
$scope.showForm = true;
$scope.memberTemp = member;
var EditArray=[];
for(var i = 0 ; $scope.reasons.length>i;i++)
{
if($scope.reasons[i].Description === ($scope.memberTemp == undefined ? "Addition" : "bla bla bla"))// condition for is this addition or not
{
EditArray = $scope.reasons[i];
break;
}
else // if is it not addition, then addition only offect that object. because we were already assigned original value globally
{
if($scope.reasons[i].Description!=="Addition")
{
EditArray.push($scope.reasons[i])
}
}
}
$scope.reasons=EditArray;
console.log($scope.reasons);
}
}
Working Demo On console window
Try this,
HTML
<select ng-model="selectedOption">
<option ng-show="reason.show" ng-repeat="reason.ID as reason.Description for reason in reasons |orderBy: reason.Description">{{reason.ID}}</option>
</select>
JS
$scope.manageMember = function (member) {
$scope.showGrid = false;
$scope.showForm = true;
reset();
$scope.memberTemp = member;
angular.extend($scope.member, member);
if(member){
for(var i = 0 ; $scope.reasons.length>i;i++)
{
$scope.reasons[i].show = true;
if($scope.reasons[i].ID == "Addition"){$scope.reasons[i].show = false;}
}
}else{
for(var i = 0 ; $scope.reasons.length>i;i++)
{
$scope.reasons[i].show = false;
if($scope.reasons[i].ID == "Addition"){$scope.reasons[i].show = true;}
}
}
}
Suppose you have two buttons as,
<input type="button" ng-click="toAdd=true">Add</input>
<input type="button" ng-click="toAdd=false">Edit</input>
And the select box code should be like,
<select ng-model="selectedOption">
<option ng-show="toAdd">Addition</option>
<option ng-show="!toAdd">Deletion</option>
<option ng-show="!toAdd">Duplicate</option>
<option ng-show="!toAdd">Member Duplicate</option>
</select>
Hope this helps.

Drop down list filters aren't working

I'm trying to filter one drop down list (DDL) based on a selection made in another. I was referencing this question for how to do it: Angularjs Filter data with dropdown
My DDLs look like this:
<select class="form-control input-sm"
ng-change="echo(selectedDepartment);"
ng-model="selectedDepartment"
ng-options="d as d.DepartmentName for d in departmentList track by d.DepartmentId"></select>
<select class="form-control input-sm"
ng-change="echo(selectedTeam);"
ng-model="selectedTeam"
ng-options="t as t.TeamName for t in (teamList | filter: filterTeams) track by t.TeamId"></select>
<select class="form-control input-sm"
ng-change="echo(selectedRep);"
ng-model="selectedRep"
ng-options="r as (r.FirstName + ' ' + r.LastName) for r in (repList | filter: filterReps) track by r.UserId"></select>
The echo function in ng-change is just using console.log so I can verify that the model is being updated when a selection is made and it is.
Here are my filter functions:
$scope.filterTeams = function (team) {
console.log("Team's DeptId: " + team.Department.DepartmentId + " Selected Dept Id: " + $scope.selectedDepartment.DepartmentId);
return (team.Department.DepartmentId === $scope.selectedDepartment.DepartmentId);
};
$scope.filterReps = function(rep) {
return (rep.TeamId === $scope.selectedTeam.TeamId);
};
What's strange is that when I reference $scope.selectedDepartment in my filter function it's always an empty object even after the echo function running in ng-change shows it's been updated.
The filter functions are part of the same controller that the DDLs are referencing and have the same $scope object.
When I select a department my team DDL goes blank since it's comparing team.Department.DepartmentId to undefined.
How can $scope.selectedDepartment be an empty object and be populated at the same time?
For inexplicable reasons you can't use $scope in a filter function. So to make this work you have to create a local variable in your controller and copy the value from your $scope variable to the local one for the filter function to use. Then everything works.
Here's the updated view:
<select class="form-control input-sm"
ng-change="updateSelectedDepartment(selectedDepartment);"
ng-model="selectedDepartment"
ng-options="d as d.DepartmentName for d in departmentList track by d.DepartmentId"></select>
<select class="form-control input-sm"
ng-change="updateSelectedTeam(selectedTeam);"
ng-model="selectedTeam"
ng-options="t as t.TeamName for t in (teamList | filter: filterTeams) track by t.TeamId"></select>
<select class="form-control input-sm"
ng-model="selectedRep"
ng-options="r as (r.FirstName + ' ' + r.LastName) for r in (repList | filter: filterReps) track by r.UserId"></select>
And here's the relevant sections from the controller:
var selectedDepartment = {};
var selectedTeam = {};
$scope.updateSelectedDepartment = function(dept) {
selectedDepartment = dept;
};
$scope.updateSelectedTeam = function (team) {
selectedTeam = team;
};
$scope.filterTeams = function (team) {
return (team.Department.DepartmentId === selectedDepartment.DepartmentId);
};
$scope.filterReps = function (rep) {
return (rep.Team.TeamId === selectedTeam.TeamId);
};
Here's another option...instead of making the filter a function on your controller, make it an actual filter (the added benefit there is you can reuse the filter in other areas). So do this:
.filter('teamsFilter', function() {
return function(teamsList, selectedDepartment) {
var out = [];
angular.forEach(teamsList, function(team) {
if (team.Department.DepartmentId === selectedDepartment.DepartmentId) {
out.push(team);
}
});
return out;
}
})
And then use it like this:
<select ng-model="selectedTeam"
ng-options="t as t.TeamName for t in (teamList | teamsFilter: selectedDepartment)"></select>

angular js filter/search and unique selects

I've tried most of the SO answers for identifying unique values in angular.js ( i am a novice) but my problem is trying to get these into a select form and for that to have a filter on the data in a table.
essentially i have some data, I want to display it in a table and in the table header have a select dropdown of unique values in that column of data and be able to filter the table displayed by values selected.
I'm trying to use
app.filter('unique', function () {
return function ( collection, keyname) {
var output = [],
keys = []
found = [];
if (!keyname) {
angular.forEach(collection, function (row) {
var is_found = false;
angular.forEach(found, function (foundRow) {
if (foundRow == row) {
is_found = true;
}
});
if (is_found) { return; }
found.push(row);
output.push(row);
});
}
else {
angular.forEach(collection, function (row) {
var item = row[keyname];
if (item === null || item === undefined) return;
if (keys.indexOf(item) === -1) {
keys.push(item);
output.push(row);
}
});
}
return output;
};
});
and my html looks like this
<th> Number:
<br/>
<select ng-model="search.number"
ng-options="row.numberfor row in data | unique:'number'">
<option value=""> </option>
</select>
</th>
and then the table data itself
</tr>
</thead>
<tbody>
<tr ng-repeat="r in data | filter:{ number: search.number, }">
<td> {{r.number}}</td>
</tr>
</tbody>
</table>
The output generates this, but the value isn't set correctly so filtering returns nothing (as 0,1,2,3.. have not matching rows of data).
<select ng-model="search.number"
ng-options="row.numberfor row in data | unique:'number'"
class="ng-pristine ng-valid">
<option value="" class=""> </option>
<option value="0">1023 456789</option>
<option value="1">1024 456789</option>
<option value="2">1025 456789</option>
<option value="3">1023 111999</option>
<option value="4">1024 111999</option>
</select>
I've also tried this unique function
/*
app.filter('unique', function() {
return function(input, key) {
var unique = {};
var uniqueList = [];
for(var i = 0; i < input.length; i++){
if(typeof unique[input[i][key]] == "undefined"){
unique[input[i][key]] = "";
uniqueList.push(input[i][key]);
}
}
return uniqueList;
};
}); */
but no joy. i had to add [key] to this line uniqueList.push(input[i][key]); just to get the values displayed in the drop down, but I can't seem to control the values of the options in that drop down.
I have no errors in my console.
I have 10 columns/fields to filter on, but I've just included one example here.
Can someone help point me in the right direction. thanks
edit:
I see this directive might be useful, but when the map key->value are the same, is there a quicker/easier way?
app.directive('mySelect', [function () {
return {
restrict: 'E',
transclude: true,
replace: true,
template: '<select ng-options="key as value for (key, value) in myMap" ng-transclude></select>',
link: function postLink(scope, element) {
scope.myMap = {"1":"1","2":"2","3":"3"};
// e.g. hashmap from server
}
};
turns out this works
<select ng-model="search.<?php echo $column; ?>"
ng-options="v for (k, v) in data
| orderBy:'<?php echo $column;?>'
| unique:'<?php echo $column;?>' ">
<option value="">select</option>
</select>
stuck within a foreach that looks at the each of columns in a CSV file.
i.e. the full excel style filtering with any csv passed in.

Resources