Get Selected Object Of Kendo Drop Down List - angularjs

I am using the Kendo Drop Down List. More specifically, I'm using Kendo Angular directives. Currently, I have the following in my markup:
<input id='myDropDownList' kendo-drop-down-list ng-model="selectedSport" k-data-source="sports" k-data-text-field="'name'" />
<button ng-click='send()'>Submit</button>
My controller has the following:
$scope.selectedSport = null;
$scope.sports: [
{ id: 1, name: 'Basketball' },
{ id: 2, name: 'Football' },
{ id: 3, name: 'Tennis' }
];
$scope.send = function () {
alert($scope.selectedSport);
};
When I run this code, I get the selectedSport ID. However, I want the entire object. Every other StackOverflow post I've found uses retrieves the ID. For the life of me, I can't figure out how to get the object. Does anyone know how to get the selected JSON object instead of just the id?
Thanks!

This answer is probably outdated for current versions of the Kendo Angular bindings.
As mentioned in hally9k's answer, there is now an attribute k-ng-model that can handle this, so you would use
k-ng-model="selectedSport"
in place of
ng-model="selectedSport"
Previous answer below; this may or may not still be relevant in case you're using an older version of Kendo UI:
I don't think you can configure the kendo widget to store the dataItem directly - underneath it all is still a <select> with a primitive value. So you'll probably have to get the dataItem from the widget's data source, e.g. like this:
HTML:
<div ng-controller="MyController">
<select id='myDropDownList' kendo-drop-down-list ng-model="selectedSport" k-data-source="sports" k-data-value-field="'id'" k-data-text-field="'name'"></select>
<button ng-click='send()'>Submit</button>
</div>
JS:
function MyController($scope) {
$scope.selectedSport = null;
$scope.sports = new kendo.data.DataSource({
data: [{
id: 1,
name: 'Basketball'
}, {
id: 2,
name: 'Football'
}, {
id: 3,
name: 'Tennis'
}]
});
$scope.send = function () {
var dataItem = $scope.sports.get($scope.selectedSport);
console.log(dataItem);
};
}
You could, however, create your own directive for kendoDropDownList which uses a k-data-item attribute (for example) and use it like this:
HTML:
<select id='date' k-ddl k-data-source="sports" k-data-text-field="name" k-data-item="dataItem">
JS:
var app = angular.module('Sample', ['kendo.directives']).directive("kDdl", function () {
return {
link: function (scope, element, attrs) {
$(element).kendoDropDownList({
dataTextField: attrs.kDataTextField,
dataValueField: "id",
dataSource: scope[attrs.kDataSource],
change: function () {
var that = this;
var item = that.dataItem();
scope.$apply(function () {
scope[attrs.kDataItem] = item.toJSON();
});
}
});
}
};
});
function MyController($scope) {
$scope.sports = [{
id: 1,
name: 'Basketball'
}, {
id: 2,
name: 'Football'
}, {
id: 3,
name: 'Tennis'
}];
$scope.dataItem = $scope.sports[0];
$scope.send = function () {
console.log($scope.dataItem);
};
}
That way, you could keep the controller free from Kendo UI DataSource-specific code and instead only work with JS data types. (see JSBin)

Using k-ng-model will bind the dataItem instead of just the text value:
<input id='myDropDownList' kendo-drop-down-list k-ng-model="selectedSport" k-data-source="sports" k-data-text-field="'name'" />

I know this is an old question, but you could use the select event of the dropdownlist to get the underlying json object:
select: function (e) {
var item = this.dataItem(e.item.index());
...
}
You would then store the json object (item variable above) from the select event so that you can get to it from your submit method. There is probably a way to get the selected json object without having to use the select event as well.

The proper way to get the text value is to use the 'k-select' event of Kendos dropdownlist:
<select kendo-drop-down-list k-select="vm.test" k-data-text-field="'groupName'" k-data-value-field="'id'" k-data-source="vm.groupList" ng-model="vm.groupId"></select>
Then in your angular controller expose the 'test' function (example assumes you are using 'controller as vm'):
function DocumentTypeController() {
var vm = this;
vm.test = test;
vm.groupId = null;
function test(dropdown) {
alert('text is:' + dropdown.item.text());
}
}
I hope that helps.

Related

How to select the option in ngOptions with the help of the third parameter present in the option object?

I have options array for select dropdown like
[
{key:1,value'foo',selected:true},
{key:2,value'foo2',selected:false}
]
I want to select option value with the property selected true in my model. So for this option array of my model should be initialized and bind to 1.
Any help is appreciated!! Thanks in advance :)
For this i know i can do it by looping in controller and setting the value whose property selected is true. I am looking for an alternative which is better. Also i have tried ng-repeat on options and it works, but i think ngOptions is better from the view of performance.
If I understood the requirements correctly:
angular.module('selectExample', [])
.controller('ExampleController', ExampleController);
ExampleController.$inject = ['$scope'];
function ExampleController($scope) {
$scope.selectOptions = [{
key: 1,
value: 'foo',
selected: true
},
{
key: 2,
value: 'foo2',
selected: false
}
];
$scope.filterOptions = filterOptions;
setFirstOptions($scope, 'selected', $scope.selectOptions);
}
function filterOptions(data) {
return data.filter(function(item) {
return item.selected;
});
}
function setFirstOptions($scope, variable, data) {
var filteredOptions = filterOptions(data);
if (filteredOptions.length > 0) {
$scope[variable] = filteredOptions[0];
}
}
angular.bootstrap(
document.querySelector('body'), ['selectExample']
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div ng-controller="ExampleController">
<select ng-model="selected" ng-options="option.value for option in filterOptions(selectOptions)">
</div>

Angular 1.5 ng-change on select element in component triggering previous response

I'm just starting to play with components in Angular 1.5.x and have created one for a select box on a form - I pass in the field, list and label to the component and it creates the form 'part' consisting of the label and select box with the correct options - so far, so good.
Now I want to implement an ng-change on the select so I am passing in the function I want to use for this. The problem I have is that the function is triggering with the old value for the select not the new value. I can see that the function is triggering prior to the actual change. If I put the change function within the component change event it registers correctly, but not using a passed in function.
I have created a cut-down fiddle at https://jsfiddle.net/7gd3m2k0/
<div ng-app="demoApp">
<div ng-controller="RoleController as ctrl">
<nac-select
field="ctrl.MemberRole.record.member"
list="ctrl.Lists.Member"
label="Member"
on-change="ctrl.MemberRole.changeMember();"></nac-select>
<div ng-bind="ctrl.MemberRole.record.member.name"></div>
</div>
</div>
angular.module('demoApp', [])
.component('nacSelect', nacSelect)
.controller('RoleController', roleController)
var nacSelect = {
bindings: {
field: '=',
list: '<',
label: '#label',
onChange: '&'
},
controller: function () {
var ctrl = this;
ctrl.change = function () {
alert(ctrl.field.name); //gives new selection
ctrl.onChange(); //gives previous selection
}
},
template: `
<label>{{$ctrl.label}}</label>
<select ng-model="$ctrl.field" ng-options="r as r.name for r in $ctrl.list" ng-change="$ctrl.change();">
<option value="">(Please Select)</option>
</select>
`
};
var roleController = function(){
var ctrl = this;
ctrl.Lists = {
Member: [
{id: 1, name: 'Fred Smith'},
{id: 2, name: 'Jenny Jones'},
{id: 3, name: 'Jane Doe'}
]
};
ctrl.MemberRole = {
record: {
member: null
},
changeMember: function(){
alert(ctrl.MemberRole.record.member.name);
}
};
};
I guess I am missing something simple, but I can't figure it out. Thank you for your assistance
You need to pass in variable that you want to alert in the first controller, check this:
https://jsfiddle.net/pegla/7gd3m2k0/1/
so your function would look like this:
changeMember: function(name){
alert(name);
}
when you're using nac-select
<nac-select field="ctrl.MemberRole.record.member" list="ctrl.Lists.Member" label="Member" on-change="ctrl.MemberRole.changeMember(name);"></nac-select>
and in the end in the nac-select:
<select ng-model="$ctrl.field" ng-options="r as r.name for r in $ctrl.list | orderBy: 'name'" ng-required="$ctrl.req" ng-if="!$ctrl.list.processing" ng-change="$ctrl.onChange($ctrl.field)">
or if you want to pass in object:
<nac-select field="ctrl.MemberRole.record.member" list="ctrl.Lists.Member" label="Member" on-change="ctrl.MemberRole.changeMember({id, name});"></nac-select>
then your changeMember can look like this:
changeMember: function(obj){
alert(`${obj.name} ${obj.id}`);
}
New fiddle:
https://jsfiddle.net/pegla/7gd3m2k0/2/

AngularJS two-way data binding not working properly in directive

i am trying to implement radio-button list using ng-repeat.
typeList.html
<div ng-repeat="type in types" >
<input type="radio" id={{type.id}} name="{{type.name}}" ng-model="result" ng-value="type.id" >
{{type.name}}
<div> Result {{result}} </div> //result is changing only in the row of clicked radio-button. It should change in every row.(two way data-binding).
</div>
Directive:
angular.module('app').directive('myList',function(){
return{
restrict: 'A',
scope: {
types: '=', //here list is passed to be printed with ng-repeat
result: '=' //here I want to store which radio-button was selected last time by id
},
templateUrl: 'html/typeList.html'
};
});
Directive has isolated scope. I am passing two parameters. List to be printed with radio buttons and result object which stores answer(id-what radio button was clicked last time) in parent scope. Unfortunately whenever i click on radio-buttons my result is changing only locally.
Passing parameters to my directive.
<div my-list types="list" result="selected"></div>
Passed list and result paramater from controller to myList directive.
$scope.list = [
{ id: 1, name:'Name 1' },
{ id: 2, name:'Name 2' },
{ id: 3, name:'Name 3' }
];
$scope.selected = -1;
I would be grateful for any help.
You have to pass a non-primitive object to the model to get its reference for two-war binding. Just wrap selected into an object for its reference.
In your controller use.
$scope.list = [{
id: 1,
name: 'Name 1'
}, {
id: 2,
name: 'Name 2'
}, {
id: 3,
name: 'Name 3'
}];
$scope.ctrlModel = {
selected: -1
}
And in the Markup that is 'html/typeList.html'
<div ng-repeat="type in types" >
<input type="radio" id={{type.id}} ng-model="result.selected" ng-value="type.id" >
{{type.name}}
</div>
Result {{result.selected}}
Working Fiddle Demo
Hope it helps.
try to have scope variables as object like
$scope.types = {
list: {},
selected: 'radioValueThatNeedsToBeSelected'
}

Passing Array of Objects into Angular Directive

I have an array of objects in my angular controller, e.g.
[{
label: 'label1',
data: [{
type: TimelineChart.TYPE.POINT,
at: new Date([2015, 1, 1])
}, {
type: TimelineChart.TYPE.POINT,
at: new Date([2015, 2, 1])
}]
}, {
label: 'label2',
data: [{
type: TimelineChart.TYPE.POINT,
at: new Date([2015, 1, 11])
}, {
type: TimelineChart.TYPE.POINT,
at: new Date([2015, 1, 15])
}]
}];
Every object has a Date field. How can I pass this array of objects into my directive?
I tried passing by reference:
<div id= "chart" my-directive my-data="data"></div>
$scope: {
myData: '='
},
link: function($scope, $element, $attrs) {
function init() {
var data = $scope.myData;
var timeline = new TimelineChart($element[0], data);
}
$attrs.$observe("myData", init);
}
However, it didn't work. I get undefined.
Passing in as an attribute, i.e. my-data="{{ data }}" and using JSON.parse($attrs.myData) does not work due to the Date fields.
It's very simple to pass the data to directive. I think what you are missing is scope. You are using $scope instead of scope. Directive Definition object takes scope not $scope. So what you need to do it.
scope: { //make it scope
myData: '='
},
link: function($scope, $element, $attrs) {
function init() {
var data = $scope.myData;
var timeline = new TimelineChart($element[0], data);
}
$attrs.$observe("myData", init);
}
Here's the fiddle
I think the problem is your array object is lost in $scope . For confirmation, use console.log($scope.myData);
And see in browser console what it returns, if undefined then simply write console.log($scope); and then run the application . Go to browser console and expand $parent until you find myData object. Count the number of parent scope.
If suppose you found it under 3rd parent ,the use
$scope.$parent.$parent.$parent.myData instead of $scope.myData .
This will work :)

Saving a checkbox list in Angularjs with node

I want to save and load a checkbox list using binding in angularjs with a node backend. This SO question (How do I bind to list of checkbox values with AngularJS?) answers how I can load the check box from a static javascript object but how can I save the checkbox values after the user selects them?
I want to save the checkbox values in a single field but how can I tell angular to bind the checkbox values into a single field defined in a model to my mongodb? I cant just use ng-model as there are multiple checkboxes.
Needless to say that I am new to angular so any help here is greatly appreciated ...
Thanks for any help you can provide.
kseudo
Just add ng-model to your checkbox. By this way you can update model in controller on any checkbox state change.
Here is example:
HTML
<div ng-controller="Ctrl">
<label ng-repeat="fruit in fruits">
<input
type="checkbox"
name="fruit.name"
ng-model="fruit.value"
> {{fruit.name}}
</label>
<pre>{{fruits| json}}</pre>
</div>
JS
var app = angular.module('app', []);
function Ctrl($scope) {
$scope.fruits = [{
name: 'apple',
value: false
}, {
name: 'orange',
value: false
}, {
name: 'pear',
value: false
}, {
name: 'naartjie',
value: false
}];
}
Demo Fiddle
[EDIT]
BTW we can make the copy by using angular.copy() method. When we press button, the new copy of fruits model will be created (and you should send it to server as json). Old model fruits will stay the same:
$scope.fruitsCopy = [];
$scope.init = function(){
$scope.fruitsCopy = angular.copy($scope.fruits );
}
To convert data to JSon I would use:
var jsonData = JSON.stringify($scope.fruitsCopy);
Demo2 Fiddle
Let's say you defined your model as such:
function Ctrl($scope) {
$scope.items = [{
name: 'A',
checked: false
}, {
name: 'B',
checked: false
}, {
name: 'C',
checked: false
}, {
name: 'D',
checked: false
}];
}
And created a view for the model:
<ul>
<li ng-repeat="item in items">
<label>
<input type="checkbox" ng-model="item.checked">
{{item.name}}
</label>
</li>
</ul>
<button ng-click="save()">save</button>
Next you have to define save function:
$scope.save = function() {
//angular.toJson converts array to string, something like
// '[{"name":"A","checked":false},{"name":"B","checked":true},...]'
var json = angular.toJson($scope.items);
//Service is angular service for your model that makes http requests to your backend
Service.save(json).then(function(){
//here you can notify user that data is persisted
}, function() {
//here you can notify user that there was a problem with request
});
}
And a simple model service:
.service('Service', function($http) {
return new function() {
this.save = function(data) {
return $http.post('url/to/backend', data);
}
}
});

Resources