Angular 2 RC4 - Select ngModel delayed update - angularjs

I'm trying to create a select control that will bind the value to an Object and on change I can get access to the selected object.
I know there has a been a lot of changes in the forms so not sure if this is a user error or bug or not possible.
Here is where I'm at so far: Link to Plunker
import { Component } from '#angular/core';
#Component({
selector: 'my-app',
template: `
<h1>My First Angular 2 App</h1>
<select (change)="onChange($event)" [(ngModel)]="selected">
<option value=''></option>
<option *ngFor="let d of data" [ngValue]="d">
{{d.name}}
</option>
</select>
`
})
export class AppComponent {
diagnostic;
selected;
data = [
{ id: 1 , name: 'query 1', filters: [
{ 'filter1': 'material = 1'},
{'filter2': 'plant = 2'}
]
},
{ id: 2 , name: 'query 2', filters: [
{ 'filter1': 'material = 1'},
{'filter2': 'plant = 2'}
]
}
];
onChange(event) {
console.log(event.target.value);
console.log(this.selected);
}
}
What I would like to have happen is that when the onChange event is called that either I pass the Object value of the selected item into that method or get access to the selected value through the property bound in ngModel.
//expected
onChange(event) {
console.log(event.target.value) // selected object bound to ngValue
console.log(this.selected) // ngModel updated to object bound to selected option
}
But unfortunately, the event.target.value is a string version of the object and this.selected sort of works but is always behind on being updated.
Is there another way or proper way to handle this? Is the delay in the ngModel a bug?
Any help would be appreciated!

You should define select inputs/outputs as following:
<select [(ngModel)]="selected" (ngModelChange)="onChange()">
<option *ngFor="let d of data" [ngValue]="d">
{{d.name}}
</option>
</select>
and then the model is correctly applied to the property. http://plnkr.co/edit/JGgflTY9LvrDDhqqlSGP?p=preview
Notice that the definition of ngModel and ngModelChange should be ordered as is in example :)

Related

Write out what i select in my <select> list in angular

I want to write out the option i choose from my select list. I know that i should use change but now how i should use it. !now im just writing to get the letters in!
My ts file:
import { Component, OnInit } from '#angular/core';
import { selectBeverage } from "../interface-beverage";
#Component({
selector: 'app-select-beverage',
templateUrl: './select-beverage.component.html',
styleUrls: ['./select-beverage.component.css']
})
export class SelectBeverageComponent implements OnInit {
beverages: selectBeverage[] = [
{ id: 1, drink: "Beer" },
{ id: 2, drink: "Soda" },
{ id: 3, drink: "Wine" },
{ id: 4, drink: "Water" }
];
clickedBeverage(){
}
constructor() {
}
ngOnInit(): void {
}
}
My template file:
<select [(ngModel)]="beverages">
<option *ngFor="let b of beverages" [value]="b.id">
{{b.drink}}
</option>
</select>
<br><br>
One {{selectedOption}}, coming right up! ```
Create a variable in the typescript file named beverageToDisplay and bind to that in the template within the <select> tag.
.ts
beverageToDisplay: string;
.html
<select [(ngModel)]="beverageToDisplay">
<option *ngFor="let b of beverages" >
{{b.drink}}
</option>
</select>
<p *ngIf="beverageToDisplay">One {{beverageToDisplay}}, coming right up!</p>
Working stackblitz found here.
The [(ngModel)] of the select contains the selected value, not the list of options.
.ts file:
export class SelectBeverageComponent implements OnInit {
...
// add member here
selectedOption: any; // instead of any one could use something more precise in the next step
...
}
Template file:
<select [(ngModel)]="selectedOption"> <!-- i corrected value of ngModel, it contains the selected value -->
<option *ngFor="let b of beverages" [value]="b.id">
{{b.drink}}
</option>
</select>
<br><br>
One {{selectedOption | json}}, coming right up! ```

AngularJS: refresh ng-options when property source object changes

Full description:
I have list of options with multiple properties (not just key-value pair):
[
{
id: 1,
name: "111",
some: "qqq"
},
{
id: 2,
name: "222",
some: "www"
}
];
And select defined as:
<select name="mySelect" id="mySelect"
ng-options="option.name for option in opts track by option.id"
ng-model="mod1"></select>
Depending on app logic, extra property may change:
{
id: 2,
name: "222",
some: "www1"
}
But actual list in Select doesn't change!
However, if name changes, then entire optionList will be refreshed.
In short you can see demo on JSFiddle OR JSFiddle. I prepared 2 very similar examples:
When button is clicked only extra property updates
When button is clicked - both extra property and key receive new value
Does anybody know solution?
UPDATE
For now I'm solving that issue with update + delay + update solution:
this.click = function(){
$scope.opts = {};
$timeout(function() {
$scope.opts = { /* NEW OBJECT */};
}, 0);
}
OK, so I think I understand what you want, which is to be able to select an option whose nested values may have changed since the list was rendered in the DOM.
Based on that understanding, I believe that the plunker I have created illustrates a solution for you. If you select one of the options, and change the child value in the input field, two-way binding will update the model.
Basically, it is taking the users selection, and on select change, re-assigning the selected object to reference the original option in the options array. This will allow two-way binding to occur. If you view the code, you will see that the input fields are updating the option list itself ($scope.options), where-as the model that is being displayed is $scope.formData.model.
https://plnkr.co/edit/DLhI7t7XBw9EbIezBCjI?p=preview
HTML
<select
name="mySelect"
id="mySelect"
ng-model="formData.model"
ng-change="onChange(formData.model)"
ng-options="option.name for option in options track by option.id"></select>
SELECTED CHILD: {{formData.model.child.name}}
<hr>
<div ng-repeat="option in options">
Child Name for {{ option.name }}: <input ng-model="option.child.name">
</div>
JS
$scope.onChange = function(option) {
angular.forEach($scope.options,function(optionItem){
if (optionItem.id == option.id){
$scope.formData.model = optionItem;
}
})
}
$scope.options = [
{
id: 1,
name: "111",
child: {
id: 11,
name: "111-1"
}
},
{
id: 2,
name: "222",
child: {
id: 22,
name: "222-1"
}
}
];
$scope.formData = {
model: $scope.options[0]
};
Call $apply whenever you want to apply changes made.
$scope.$apply();
This will tell AngularJS to refresh.

Kendo DropdownList and ng-model doesn't work

I have a Kendo Dropdownlist bound to an ObservableArray/DataSource. It duly fills the values from array. But when I bind ng-model to a property, the dropdownlist fails to select the value.
HTML:
<select kendo-drop-down-list k-options="dropOptions" ng-model="user.id"></select>
JS:
var users = [
{ id: 1, name: 'A' },
{ id: 2, name: 'B' },
{ id: 3, name: 'C' },
{ id: 4, name: 'D' },
{ id: 5, name: 'E' },
{ id: 6, name: 'F' }
];
var usersDataSource = new kendo.data.ObservableArray(users);
$scope.dropOptions = {
dataSource: usersDataSource,
dataTextField: 'name',
dataValueField: 'id',
optionLabel: "Select one..."
};
$scope.welcome = "World";
$scope.user = { id: 3 }
$scope.user = { id: 3 } should force dropdownlist to select C.
Here is link to Plunkr:
http://plnkr.co/edit/BxTqWet5sz725ZtKEKJr?p=preview
How can I for dropdownlist to make selection based on value assigned in property bound with ng-model. I have used k-ng-model as well, but it doesn't work. Please help me what am I doing wrong here. Thank you.
Edit: The selection in dropdownlist is not hardcoded. It will be fetched from database.
I was using Angular 1.4.9 with Kendo v2015.3.1111. Downgrading to Angular 1.4.8 made it work.
I got a solution that works.
<select kendo-drop-down-list
k-options="odsSoluciones"
k-data-text-field="'descripcion'"
k-data-value-field="'solucionId'"
k-value="prescDPIntercambio.solucionDPId"
ng-model="prescDPIntercambio.solucionDPId">
</select>
$scope.odsSoluciones =
dataSource: new kendo.data.DataSource({
data: solucionesModel.data,
}),
};
In my case odsSoluciones returns an array with "solucionId" and "descripcion" fields and prescDPIntercambio.solucionDPId is the value I want to see selected
Kendo dropdown value does not reflect selection based on ng-model. Instead it provides a new attribute : k-ng-model
For a basic example, have a look at this: k-ng-model
Just add k-value = "user.id"to the template.
Working Plunker
<div ng-controller="AppCtrl">
<h1>Hello {{ welcome }}!</h1>
<div>Selected value is {{ user.id }}</div>
<select kendo-drop-down-list
k-options="dropOptions"
ng-model="user.id"
value= 3
class="glow"></select>
</div>
There is a wierd situation where when I declare the ng-model as an object for example $scope.abc.xyz = "test" ,the bind works whereas if I do $scope.abc = "test" , the bind does not work.
Not sure what the issue is :)

Set the selected option by value in the Kendo DropDownList

I have a kendo ui dropdownlist with angularjs in my html:
<select kendo-drop-down-list="dropdownlistCatalogs" k-options="optionsDropDownListCatalogs" data-role="dropdownlist" style="display: none;">
<option value="2" selected="selected">Test1</option>
<option value="3">Test2</option>
<option value="4">Test3</option>
</select>
In the angularjs controller, everytime i click on an item in the dropdownlist, i call this function to remove the selected item from the dropdown control:
function removeItemFromDropDown(e) {
var index = e.item.index();
var selectedItem = $scope.dropdownlistCatalogs.dataItem(e.item.index());
$scope.optionsDropDownListCatalogs.dataSource.remove(selectedItem);
}
Now, i want set the selected option to non existing item to show an empty value.
I have tried with:
$scope.dropdownlistCatalogs.value(-1);
but not working
How can i set the dropdownlist by value()?
I'm not sure much about angularjs and if things are different. I see $scope in there which I guess is of angular, since i dont see it defined anywhere. But Usually value will help you with this if using jquery
Add a default blank value at the top with id:-1 and set the default value as 1.
On click of a button, you can change the value to -1
It would look like this :
var data = [
{ "text": "" , id: -1 },
{ "text": "aaa",id: 1 },
{ "text": "bbb",id: 2 },
{ "text": "ccc", id:3}
];
$("#ddl").kendoDropDownList({
dataTextField: "text",
dataValueField: "id",
dataSource: data,
index: 3
});
$("#button").on("click", function ()  {
var dropdownlist = $("#ddl").data("kendoDropDownList");
dropdownlist.value(-1);
});
Here is an working example

Setting default value in select drop-down using Angularjs

I have an object as below. I have to display this as a drop-down:
var list = [{id:4,name:"abc"},{id:600,name:"def"},{id:200,name:"xyz"}]
In my controller I have a variable that carries a value. This value decided which of the above three items in the array will be selected by default in the drop-down:
$scope.object.setDefault = 600;
When I create a drop-down form item as below:
<select ng-model="object.setDefault" ng-options="r.name for r in list">
I face two problems:
the list is generated as
<option value="0">abc</option>
<option value="1">def</option>
<option value="2">xyz</option>
instead of
<option value="4">abc</option>
<option value="600">def</option>
<option value="200">xyz</option>
No option gets selected by default even though i have ng-model="object.setDefault"
Problem 1:
The generated HTML you're getting is normal. Apparently it's a feature of Angular to be able to use any kind of object as value for a select. Angular does the mapping between the HTML option-value and the value in the ng-model.
Also see Umur's comment in this question: How do I set the value property in AngularJS' ng-options?
Problem 2:
Make sure you're using the following ng-options:
<select ng-model="object.item" ng-options="item.id as item.name for item in list" />
And put this in your controller to select a default value:
object.item = 4
When you use ng-options to populate a select list, it uses the entire object as the selected value, not just the single value you see in the select list. So in your case, you'd need to set
$scope.object.setDefault = {
id:600,
name:"def"
};
or
$scope.object.setDefault = $scope.selectItems[1];
I also recommend just outputting the value of $scope.object.setDefault in your template to see what I'm talking about getting selected.
<pre>{{object.setDefault}}</pre>
In View
<select ng-model="boxmodel"><option ng-repeat="lst in list" value="{{lst.id}}">{{lst.name}}</option></select>
JS:
In side controller
$scope.boxModel = 600;
You can do it with following code(track by),
<select ng-model="modelName" ng-options="data.name for data in list track by data.id" ></select>
This is an old question and you might have got the answer already.
My plnkr explains on my approach to accomplish selecting a default dropdown value. Basically, I have a service which would return the dropdown values [hard coded to test]. I was not able to select the value by default and almost spend a day and finally figured out that I should have set $scope.proofGroupId = "47"; instead of $scope.proofGroupId = 47; in the script.js file. It was my bad and I did not notice that I was setting an integer 47 instead of the string "47". I retained the plnkr as it is just in case if some one would like to see. Hopefully, this would help some one.
<select ng-init="somethingHere = options[0]" ng-model="somethingHere" ng-options="option.name for option in options"></select>
This would get you desired result Dude :) Cheers
Some of the scenarios, object.item would not be loaded or will be undefined.
Use ng-init
<select ng-init="object.item=2" ng-model="object.item"
ng-options="item.id as item.name for item in list"
$scope.item = {
"id": "3",
"name": "ALL",
};
$scope.CategoryLst = [
{ id: '1', name: 'MD' },
{ id: '2', name: 'CRNA' },
{ id: '3', name: 'ALL' }];
<select ng-model="item.id" ng-selected="3" ng-options="i.id as i.name for i in CategoryLst"></select>
we should use name value pair binding values into dropdown.see the
code for more details
function myCtrl($scope) {
$scope.statusTaskList = [
{ name: 'Open', value: '1' },
{ name: 'In Progress', value: '2' },
{ name: 'Complete', value: '3' },
{ name: 'Deleted', value: '4' },
];
$scope.atcStatusTasks = $scope.statusTaskList[0]; // 0 -> Open
}
<select ng-model="atcStatusTasks" ng-options="s.name for s in statusTaskList"></select>
I could help you out with the html:
<option value="">abc</option>
instead of
<option value="4">abc</option>
to set abc as the default value.

Resources