Angular ngModel doesn't fire Kendo change event - javascript

I have a Kendo model instance (person for this example) and watching it is modified or not by using dirty property.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Kendo + Angular</title>
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.2.714/styles/kendo.common.min.css">
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.2.714/styles/kendo.rtl.min.css">
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.2.714/styles/kendo.default.min.css">
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.2.714/styles/kendo.mobile.all.min.css">
<script src="http://code.jquery.com/jquery-1.12.3.min.js"></script>
<script src="http://kendo.cdn.telerik.com/2016.2.714/js/angular.min.js"></script>
<script src="http://kendo.cdn.telerik.com/2016.2.714/js/jszip.min.js"></script>
<script src="http://kendo.cdn.telerik.com/2016.2.714/js/kendo.all.min.js"></script>
</head>
<body>
<div ng-app="app" ng-controller="MainCtrl">
<div>Person name: {{ person.name }}</div>
<input type="text" name="name" ng-model="person.name"> <!-- This input don't work -->
<button ng-click="foo()">Foo</button> <!-- This button work because I call person.set method manually -->
<div>This person is modified? {{ person.dirty }}</div>
</div>
<script>
var Person = kendo.data.Model.define({
id: "personId", // the identifier of the model
fields: {
"name": {
type: "string"
},
"age": {
type: "number"
}
}
});
angular.module("app", ["kendo.directives"])
.controller("MainCtrl", function ($scope) {
$scope.person = new Person({
name: "John Doe",
age: 42
});
$scope.foo = function () {
$scope.person.set('name', "Kendo");
}
});
</script>
</body>
</html>
But when I type to text box dirty don't change because Angular ngModel doesn't fire Kendo "change" event. My real app have dozens of models like this, so is there any way to fix this automatically???
Thanks.

You can write a directive to replace for ng-model,
<input type="text" name="name" k-bind-model="person.name">
angular.module('app')
.directive("kBindModel", ["$parse", function ($parse) {
return {
restrict: "A",
scope: false,
link: function (scope, element, attributes, controller) {
var key = null;
var strs = attributes.kBindModel.split('.');
if (strs && strs.length > 1) {
key = strs[1];
}
var model = scope[strs[0]];
element.change(function () {
scope.$apply(function () {
model.set(key, element.val());
});
});
scope.$watch(attributes.kBindModel, function (n, o) {
element.val(n);
});
}
}
}]);

Related

angular js filters working but with errors

Angular js filter Working Fine But Throwing Itteration Errors
var app = angular.module('NGapp', []);
app.filter('altDate', altDate);
app.controller('MainCtrl', MainCtrl)
function MainCtrl($scope) {
$scope.data = {
'listProductCost': [{
'data': 1
}, {
'data': 23
}, {
'data': 234
}, ]
}
}
function altDate(_) {
return function(value) {
console.log(value)
if (!value || value.length === 0) {
return [];
} else {
var f = []
angular.forEach(value, function(data) {
f.push(data['data']);
})
var s = []
s.push({
'min': _.min(f),
'max': _.max(f)
})
return s;
}
//return s;
};
}
app.factory('_', LodashFactory);
/** #ngInject */
function LodashFactory($window) {
return $window._;
}
<!DOCTYPE html>
<html ng-app="NGapp">
<head>
<meta charset="utf-8" />
<title>AngularJS </title>
<link rel="stylesheet" href="style.css" />
<script data-require="lodash.js#4.17.4" data-semver="4.17.4" src="https://cdn.jsdelivr.net/npm/lodash#4.17.4/lodash.min.js"></script>
<script data-require="angular.js#1.5.x" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.11/angular.min.js" data-semver="1.5.11"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<p>Hello {{name}}!</p>
<md-card-content layout="row" layout-align="none" ng-repeat="datas in data.listProductCost | altDate ">
<div class="dark" flex="30">HO Cost</div>
<div>
<span>{{datas.min}}</span> % to <span>{{datas.max}}</span> %
</div>
</md-card-content>
</body>
</html>
Here is my Working Code With angularjs filter . the filter is working fine but iam getting itteration error in console
the purpose filter is to print only the minimum and maximum value of the discount. can anyone can resolve the issue or give me a idea to resolve this thanks in advance
I see you using lodash. Why not use _.minBy() instead of _.min() ?
That way you can reduce your altDate function to
altDate(_){
return function(value) {
return {
min: _.minBy(value, function(i) { return i.data }),
max: _.maxBy(value, function(i) { return i.data})
}
}
}

Angular Get Selected Value From Checkbox

I can't seem to get the selected item from an input checkbox.
<ul>
<li ng-repeat='shoe in shoebox'>
<input type='checkbox' ng-model='shoe.selected' id='shoe-{{shoe.name}}'>
<label for='shoe-{{shoe.name}}'>{{shoe.name}}</label>
</li>
<button ng-click='whatIsChecked(shoe.selected)'>Apply</button>
</ul>
Then in my controller:
$scope.whatIsChecked = function(selectedThing) {
console.log(selectedThing);
};
The above returns undefined.
The list items are displayed correctly, but the shoe.name or checked item doesn't seem to be stored by the ng-model.
the variable shoe is only valid in ng-repeat block.
If you want to got what is selected, you should try filter.
UPD:
Since you don't have the selected property, you should keep the selected items somewhere else by firing the ng-click event.
refer below code snippet.
angular.module("app", [])
.controller("myCtrl", function($scope) {
$scope.checkedShoes = [];
$scope.shoebox = [{
name: 'shoe1'
},
{
name: 'shoe2'
},
{
name: 'shoe3'
},
{
name: 'shoe4'
}
];
$scope.save = function(e, shoe) {
if (e.target.checked) {
$scope.checkedShoes.push(shoe);
} else {
var index = $scope.checkedShoes.indexOf(shoe);
if( index > -1) {
$scope.checkedShoes.splice(index, 1);
}
}
};
$scope.whatIsChecked = function() {
//var selected = $scope.shoebox.filter(function(item) {
// return item.selected === true;
//});
console.log($scope.checkedShoes);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<div ng-app="app" , ng-controller="myCtrl">
<ul>
<li ng-repeat='shoe in shoebox'>
<input type='checkbox' ng-click="save($event, shoe)" id='shoe-{{shoe.name}}'>
<label for='shoe-{{shoe.name}}'>{{shoe.name}}</label>
</li>
<button ng-click='whatIsChecked()'>Apply</button>
</ul>
</div>
You can get the checked items using a angular.Foreach it becomes easy when you have multiple items checked.
$scope.checkedItems = [];
angular.forEach($scope.shoebox, function(value, key) {
if (value.selected)
$scope.checkedItems.push(value.name);
});
Demo
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.shoebox = [{
name: 'Reboke',
selected: false
}, {
name: 'woodlands',
selected: false
}, {
name: 'Nike',
selected: false
}, {
name: 'Fila',
selected: false
}];
$scope.checkedItems = function() {
$scope.checkedItems = [];
angular.forEach($scope.shoebox, function(value, key) {
if (value.selected)
$scope.checkedItems.push(value.name);
});
}
});
<html>
<head>
<meta charset="utf-8" />
<title>AngularJS </title>
<link rel="stylesheet" href="style.css" />
<script src="https://code.angularjs.org/1.4.7/angular.js"></script>
</head>
<body ng-app="myApp" ng-controller="myCtrl">
<ul>
<li ng-repeat='shoe in shoebox'>
<input type='checkbox' ng-model='shoe.selected' id='shoe-{{shoe.name}}'>
<label for='shoe-{{shoe.name}}'>{{shoe.name}}</label>
</li>
<button ng-click='checkedItems()'>Apply</button>
Checked items are: {{checkedItems}}
</ul>
</body>
</html>

angularjs nested ng-repeat function call when finish

I have 2 nested ng-repeat and boolean, which will hide the loading div, but loading div is hiding before all content is rendered. Boolean depends on a callback function which gets all data.
<tr ng-repeat="package in packages track by $index">
<td> {{ pack.Name }}</td>
<td>
<select ng-hide="package.spinStart" class="form-control" ng-model="package.selectedVersion">
<option ng-repeat="pack in package.allPackageVersions track by $index"
value="{{pack.Version}}"
ng-hide="pack.shouldHide"
ng-disabled="!expertModeOn && pack.shouldDissable"
ng-style="!expertModeOn && pack.shouldDissable && {'color':'#ddd'}">
{{pack.NuGetPackageId}} | {{pack.Version}} | {{pack.Published}}
</option>
</select>
How I call the function when all 2 nested loops are finished?
I tried with $watch statement and directive.
Thanks You!
can you use $last?
<!DOCTYPE html>
<html data-ng-app="myApp">
<head>
<link rel="stylesheet" href="style.css">
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
<script src="script.js"></script>
</head>
<body data-ng-controller="testController">
<div ng-repeat="package in packages">
{{package.name}}
<div ng-repeat=" pkg in package.selectedVersion" ng-init="$last && call()">
{{pkg.name}}
</div>
</div>
<script>
angular
.module('myApp', [])
.run(function($rootScope) {
$rootScope.title = 'myTest Page';
})
.controller('testController', ['$scope',
function($scope) {
$scope.packages = [{
name: 'test1',
selectedVersion: [{
name: 'test_ver1'
}, {
name: 'test_ver2'
}, {
name: 'test_ver3'
}]
}, {
name: 'test2',
selectedVersion: [{
name: 'test_ver1'
}, {
name: 'test_ver2'
}, {
name: 'test_ver3'
}]
}];
var counter = 0
$scope.call = function() {
counter++
if (counter == $scope.packages.length) {
alert("All loops finished");
}
}
}
])
</script>
</body>
</html>
You could use a directive which emits an event when the outer loop finishes.
You can reuse this directive in any loop, just resubscribe to the event.
app.directive('onRepeatFinish', function($timeout) {
return {
restrict: 'A',
link: function(scope, element, attrs) {
// $last is a boolean set by angular inside ng-repeats
if (scope.$last) {
// Wait for view to fully render
$timeout(function() {
// Emit upwards the tree
scope.$emit('repeatFinished');
});
}
}
};
});
In your controller, subscribe to the event:
$scope.$on('repeatFinished', function() {
$scope.showLoader = false;
});
Usage in view:
<tr ng-repeat="package in packages track by $index" on-repeat-finish>

AngularJs, Img, onclick

I must do a website. On this website when you click on img it adds a text to the div.
It must has directives and controllers i dont have a clue how to do this...
<!DOCTYPE HTML>
<html>
<head>
<script src="http://code.angularjs.org/1.2.7/angular.min.js"></script>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<link rel="Stylesheet" type="text/css" href="styles/style.css">
<title>AngularJS System Zamówień</title>
<script>
var myApp = angular.module('myApp', []);
myApp.controller('myCtrl', function($scope) {
$scope.data = new Date();
$scope.hambureger ={
nazwa: 'Hambureger',
cena: '5',
}
$scope.crips = {
nazwa: 'Crips',
cena: '4',
}
$scope.cola = {
nazwa: 'Coca-Cola',
cena: '3',
}
$scope.show = function() {
}
}
myApp.directive1('myDir1', function () {
return {
restrict: 'A',
template: '<br>{{hamburger.nazwa}}'
};
});
myApp.directive2('myDir2', function () {
return {
restrict: 'A',
template: '<br>{{frytki.nazwa}}
};
});
myApp.directive3('myDir3', function () {
return {
restrict: 'A',
template: '<br>{{cola.nazwa}}'
};
});
});
</script>
</head>
<body>
<h1 class="ladne"><center>System zamówień żarcia</center></h1>
<div class="d1" ng-app="myApp" ng-controller="myCtrl">
<img src="styles/img/cola.gif" ng-click=""></img>
<img src="styles/img/fryt.gif" ng-click=""></img>
<img src="styles/img/ham.gif" ng-click=""></img>
<br>
<div class="zam">
Data Zamówienia: {{data |date:'yyyy-MM-dd'}}
<br>
Twoje zamówienie: //HERE ANGULAR MUST ADD A TEXT
</div>
</div>
</body>
</html>
It's really hard for me to do this...
So let's explain one more time:
When u click on img, text is added to div(class="zam"), when you press next img it adds new text in new line. Here are 3 diffrent imgs Crips, Hambureger 'n' cola

& operator not working in the isolated scope of directive

I am using & (expression binding) operator in isolated scope of a directive but I am unable to trigger function on the parent controller . There should be output on the console but I am receiving none.
Here in the HTML part:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Directive &</title>
<script type="text/javascript" src="angular.min.js"></script>
<script src="isolate_scope_&.js"></script>
</head>
<body ng-app="isolate_scope">
<div ng-controller="isolateScopeController">
<b>Ctrl Data</b>
<div ng-repeat="person in persons">
<p>{{person.name}}</p>
</div>
<b>Directive Data</b>
<div ng-repeat="person in persons">
<friends frnd="person.name"></friends>
</div>
<my-button isolatedFunction="printScopeToFile()"></my-button>
</div>
</body>
</html>
Here goes the JS part :
angular.module('isolate_scope', [])
.controller('isolateScopeController', function($scope){
$scope.persons = [
{
name:"tanmay",
age:"28"
},
{
name: "James",
age:"28"
},
{
name:"Rylan",
age:"26"
},
{
name:"Aditya",
age:"23"
}
];
$scope.printScopeToFile = function(){
console.log("printng to file.....");
for(var i in $scope.persons){
console.log("Name = " + $scope.persons[i].name + " Age = " + $scope.persons[i].age);
}
};
})
.directive('friends',function(){
return {
restrict :'E',
template: '<input type="text" ng-model="name">',
scope :{
name:'=frnd'
}
};
})
.directive('myButton',function(){
return {
restrict: 'E',
template: '<button ng-click="isolatedFunction()">callParentfunction</button>',
scope : {
isolatedFunction:"&"
}
};
});
Fiddle for the same: http://jsfiddle.net/v51kob1q/
The attribute isolatedFunction in your <my-button isolatedFunction...> directive should need to be isolated-function, dash-delimited attributes

Categories