select2 widget fails to update the selected value programatically - angularjs

Working with angular, select2 widget.
I am declaring it in HTML something like this:
<div>
<select id = "dropdown"
...
<option value = "1" id="1">1</option>
<option value = "2" id="2" >2</option>
<option value = "3" id="3"" >3</option>
/select>
</div
and want to programatically change the selected item (called from another function).
When invoking the code:
$("#dropdown").select2().select2('val', "3")
I can see that the value at the dropdown changes, but when actually accessing the model attribute of the drop down (to fetch the selected item), it is not set to what I tried to set it to.
When checking the onChange event of the dropdown, I can see the e.val is undefined.
See the next fiddle as an example (after click the link, I wasn't suppose to get "undefined" in the alert box): http://jsfiddle.net/kcArV/1/
Any ideas what I am doing wrong ?

It should be
$('#attribute').select2().on('change', function(e) {
alert($(this).val());
});
e is the event object, not the select control, the method context this points to the select element, so you can call the .val() to get the selected value
Demo: Fiddle

Related

Angular 2 Select Component set initial selection

I am trying to create a select component wrapper in Angular 2 using ngModel. The events all fire off correctly once the selection is changed but I cannot set the initial selection when it's rendered.
This is my component:
#Component({
selector: 'my-dropdown',
inputs: ['selectedItem', 'items', 'label'],
outputs: ['selectedItemChange'],
template: `
<div class="field">
<label>{{label}}</label>
<select class="ui search selection dropdown" [ngModel]="selectedItem" (change)="onChange($event.target.value)">
<option value="" selected>Please Select</option>
<option *ngFor="#item of items" [value]="item.value">{{item.label}}</option>
</select>
</div>`
})
export class MyDropdownComponent {
items: DropdownValue[];
selectedItem: DropdownValue;
selectedItemChange: EventEmitter<any> = new EventEmitter();
private onChange(newValue) {
console.log(newValue);
this.selectedItem = this.items.find(item => item.value == newValue);
console.log(this.selectedItem);
this.selectedItemChange.emit(newValue);
}
}
And I'm using it in the view like this:
<my-dropdown [items]="selectItems" [(selectedItem)]="itemToSelect" [label]="'Please Select'"></my-dropdown>
When I set the itemToSelect value in the parent component on init, it does not set the selected option value in the UI.
I have also tried to use the ngModelChange event but it does not fire a change event.
itemToSelect is initially set to an object, so the input property of MyDropdownComponent is initially set to an object. But then in onChange() a string value is emit()ted, which then causes itemToSelect to be set to a string, and hence the input property becomes a string. Not good.
Just consistently use an object and it will work. Also, there is no need to assign this.selectedItem in onChange(), since the selected value will propagate back down from the parent (in general, you should never set input properties in the component – it also looks weird). You can also use ngModelChange now too:
<select class="ui search selection dropdown" [ngModel]="selectedItem.value"
(ngModelChange)="onChange($event)">
private onChange(newValue) {
console.log('nv',newValue);
selectedItem = this.items.find(item => item.value == newValue);
console.log('si',selectedItem);
this.selectedItemChange.emit(selectedItem);
}
}
Plunker
Note that I did not solve the issue of the user selecting "Please select". You'll need to add some logic to onChange() to handle that case.
When I set the itemToSelect value in the parent component on init, it does not set the selected option value in the UI.
Assuming you are using ngOnInit() in the parent, you should set value in one of the lifecycle hooks that are called later (because child doesn't yet exist in ngOnInit()), try ngAfterViewInit()...

selecting radio button by default in angularjs application

Please find the plunker for radio buttons. I am expecting when I select radio button, the selected object from $scope.itemList to be assigned to selectedItemDetails but it is not happening. And also by default when the page loads I want the default radio button to be selected based on var tagNumTobeSelectedByDefault = 2; i.e., "Gety of House" to be selected by default, how can I do it?
I am getting the index of the object to be selected from the list as follows:
var indexObjectTobeSet = $scope.itemList.map(function(x) {
return x.tagNum;
}).indexOf(tagNumTobeSelectedByDefault);
But failing to set that particular radio button.
You don't set the index, you set selectedItemDetails' value to the actual object you want selected in the $scope.itemList array. Thus,
$scope.selectedItemDetails = $scope.itemList.filter(function(item) { return item.tagNum === tagNumTobeSelectedByDefault; })[0];
should work (just remember to put it after the $scope.itemList definition). You might even want to consider moving the itemList object into a service or constant.
When you are declaring selectedItemDetails as an empty literal {}, you do not have a specific binding. Declare a property the ng-model can attach to :
$scope.selectedItemDetails = { selected : null }
and
<input type="radio" ng-model="selectedItemDetails.selected" name="eachCat" data-ng-value="eachCat">
Then it works. Now you can also set the default selected radio item with
$scope.selectedItemDetails = { selected : $scope.itemList[3] }
http://plnkr.co/edit/9hVxlhzvCmx3PIsbImVD?p=preview

Angular: Select dropdown with ng-model-options setter getter set to true

Can somebody show me an example on how to bind ng-options to a getter and setter model, a plnker demo will be great.
Example on what i want to accomplish:
// As you can see the item is a object with two properties example:
// {Text: "hello", Value: 10}
setgetObject: function(value) {
if (angular.isDefined(value)) {
myObject = angular.copy(value); //copy the incoming object
}
return ????
}
<select class="form-control" name="rumFra" ng-model="getterSetter.setgetObject"
ng-options="item as item.Text for item in vm.configuration.Form.Room track by item.Value"
ng-model-options=" {getterSetter: true }">
Each time I make a new selection on my dropdown it will set the myObject with the new value but the dropdown is not effected even if I return the input element.
A working example on how to use Select tag with ng-options and ng-model-options="{setterGetter= "true"}" will be appreciated :-)
Look at Numyx's example:
http://plnkr.co/edit/SqJG8NP7e9NB9okcD4hN?p=preview
Because it is working but not with objects. Can somebody do it with objects?
Just use ng-model . ng-model binds the input,select and textareas.
see the example
<select ng-options="p.name for p in animal"
ng-model="selectedanimal"></select>

how to set the default 'select' ng-model to an object?

I am trying to do a search engine interface with angular. The user selects some parameters in a form, click "search" and then it fills the url with the parameters using $location.search()
the search interface parameters which are used to build the form :
params = {
milestones: [ "a", "b", "c", "d", etc. ],
properties: [
{ "name": "name A", type: "text" },
{ "name": "name B", type: "checkbox" },
{ etc. }
]
}
inside the controller :
$scope.query = $location.search(); // get the parameters from the url
$scope.search = function (query) { // set the parameters to the url
$location.search(query);
};
and the html of the form
<select ng-model="query.milestone_name" ng-options="ms for ms in params.milestones">
<option value="">-select milestone-</option>
</select>
<select ng-model="property" ng-options="prop.name for prop in params.properties" ng-change="query.property_name=property.name">
<!-- if the object 'property' was passed in the url, it would look like this `%5Bobject%20Object%5D`, so its 'name' parameter is converted to a string -->
<option value="">-select property-</option>
</select>
<span ng-switch="property.type">
<label ng-switch-when="text">{{query.property_name}}: <input type="text" ng-model="query.property_value"></label>
<label ng-switch-when="checkbox">{{query.property_name}}: <input type="checkbox" ng-model="query.property_value"></label>
</span>
<button ng-click="search(query)">search</button>
and somewhere else in the page is the list of results.
the user can also access to a search result page with an url like this:
http://myapp.com/search?milestone_name=a&property_name=name%20A
almost everything works fine : the list of results is displayed, the "milestone" parameter is pre-selected with the correct value in the select component, but not the "property" parameter because it's not a string, it's an object.
how can i set the default value (ng-model) of the select component to an object ?
or any other idea on how i should do this ?
When using an array of objects for the select to iterate over, the ng-options directive needs to have an attribute of the object to match against (and differentiate between arrays)
Use the track by section of the directive declaration eg
<select ng-model="property" ng-options="prop.name for prop in params.properties track by prop.name" ng-change="query.property_name=property.name">
<!-- if the object 'property' was passed in the url, it would look like this `%5Bobject%20Object%5D`, so its 'name' parameter is converted to a string -->
<option value="">-select property-</option>
</select>
You can use this form of comprehension expression in ngOptions: label group by group for value in array. Html drop down list will display only name of selected object. Model will contain whole selected object. You can set selected object from controller.
<select ng-model="property"
ng-options="prop as prop.name for prop in params.properties">
</select>
Check this plnkr example.
ng-options is generating some options to be used with ng-model. In your syntax (prop.name for prop in params.properties) you've told it to bind to the object found in the array (as oppose to a property on it - which is what you want to do) and use its name property as the value to display. So when you try and set the ng-model to be an object that's not in the ng-options array nothing happens - I'm guessing because it's using reference/shallow equality and not deep equality. So what you should do is either:
Convert the ng-options object to be an array of strings.
Use a syntax that involves keys, such as:
prop.name as prop.name for prop in params.properties
http://jsfiddle.net/C5ENK/
If that doesn't suit your needs let me know why and I'll see if I can help further.
i found a kind of solution…
when selecting a property, it saves the index of this object and then when the page loads, it sets the ng-model of the select to the value of this index. it uses this : example for setting the index and this example for getting the value of this index in the array of objects.

Angular JS - Resetting a dropdown with a function

I have a listener set up in Angular to trigger an event when a select box's option changes.
I also have a button, which I want to "reset" the selection box to blank (NOT option 1).
Here's some code:
HTML:
<select id="dropdown" ng-model="orderProp" >
<option ng-repeat="cats in categories" value="{{cats}}">{{cats}}</option>
</select>
<button id="showHide" ng-click="showAll($event)" >Show all results</button>
Javascript:
$scope.showAll = function($event){
$scope.orderProp ="0";
}
Listener function on the select box:
$scope.$watch( 'orderProp', function ( val ) {
$scope.filteredMarkersProperty = $filter('filter')($scope.markersProperty, val);
$scope.zoomProperty = 11;
calcFocus();
});
This KINDA works, although only sometimes, and I have no idea why it works (or doesn't) as I think it's the wrong way of going about it. I tried resetting it with jQuery .prop('selectedIndex',0);, but while this resets the index it doesn't trigger the listening function at all so this won't work.
Any ideas?
First - take a look at ngOptions in the select directive: http://docs.angularjs.org/api/ng.directive:select
<select ng-options="cats for cats in categories" ng-model="orderProps"></select>
<button ng-click="orderProps='0'">Show all results</button>
This will work as long as '0' is not one of the categories. The select-box will show a blank when the value of orderProps does not match any of the values in categories.
Your $watch function is not a listener on the select box, it watches orderProps and orderProps can get changed outside the select box. If you want a listener on the select box you could add a ng-change="myOnChangeFn()".
Added a working plunkr: http://plnkr.co/edit/fqWkJBYOXGaYsK9Fnedc?p=preview

Resources