Kendo dropdownlist not executing ng-focus binded function - angularjs

I have this dropdown defined on template
<select id="{{vm.field.id}}"
        kendo-drop-down-list
        k-data-source="vm.field.options"
        k-data-value-field="'code'"
        k-data-text-field="'description'"
        k-index="vm.selectedIndex"
        k-ng-model="vm.field.value"
        k-value-primitive="true"
        k-options="vm.field.config"
        ng-blur="vm.unfocusField()"
        ng-focus="vm.focusField()"
        k-on-change="vm.onValueChange()">
</select>
As you can see, I have ng-focus set (targeting to vm.focusField() function), this event is rightly applied and function triggered when I focus field by clicking directly on it with the mouse. But when this field is focused by tabbing (tab keyboard) from a previous field on form list. When I press tab, the field gets "focused" since in html the class 'k-state-focused' is added to element and I can use the up and down cursor buttons to change dropdownlist value, BUT, the ng-focus binded function is not executed. In resume this ng-focus words focusing by click, but not executed focusing by tab keyboard. I proved this function is not being called in this situation using developer tools and breakpoints on binded function

I received this code sample from the telerik support team, which helped solve my problem.
<!DOCTYPE html>
<html>
<head>
<base href="http://demos.telerik.com/kendo-ui/dropdownlist/angular">
<style>html { font-size: 14px; font-family: Arial, Helvetica, sans-serif; }</style>
<title></title>
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2017.1.118/styles/kendo.common.min.css" />
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2017.1.118/styles/kendo.blueopal.min.css" />
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2017.1.118/styles/kendo.blueopal.mobile.min.css" />
<script src="https://kendo.cdn.telerik.com/2017.1.118/js/jquery.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2017.1.118/js/angular.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2017.1.118/js/kendo.all.min.js"></script>
</head>
<body>
<div id="example" ng-app="KendoDemos">
<div class="demo-section k-content" ng-controller="MyCtrl">
<h4>Static data</h4>
<select kendo-drop-down-list="mydropdown">
<option>Albania</option>
<option>Andorra</option>
<option>Armenia</option>
<option>Austria</option>
</select>
</div>
</div>
<script>
var app = angular.module("KendoDemos", [ "kendo.directives" ])
.controller("MyCtrl", function($scope){
$scope.$on("kendoWidgetCreated", function(event, widget){
if (widget === $scope.mydropdown) {
widget.wrapper.on("focus", $scope.onFocus);
widget.wrapper.on("blur", $scope.onBlur);
}
});
$scope.onFocus = function(){
console.log("Kendo DropDownList focused!");
};
$scope.onBlur = function(){
console.log("Kendo DropDownList blured!");
};
});
</script>

Related

Detecting which field was actually modified

I created a simple form which uses Angular JS for validation. The form has a Save and Modify button. If a user hits the modify button, it allows them to make changes to their inputs/fields. Another cool thing is that if something is actually modified, it will go ahead remain highlighted orange (so that a user knows which part of the form was modified) but if nothing is modified then there is no border once you go away from the field. My question/new requirement is the following:
If suppose I went on to the name field, for example, I change it and then decide to go back to what it was written originally, then theoritcally there should be no orange highlight remaining on the field. How do I make that happen? So if I change the field from A to B but then change it back to A, no border should be there because I ended up not changing the value. I have no idea how to do this. Any suggestions/guidance/tutorials that can help me solve this would be greatly appreciated. I have a snippet of my code below
<!DOCTYPE html>
<html>
<head>
<script src="https://code.angularjs.org/1.4.8/angular.js" data-semver="1.4.8" data-require="angular.js#1.4.8"></script>
<script>
var app = angular.module("app", []);
app.controller("ctrl", function($scope) {
});
</script>
<style>
.someCSS {
border: 5px solid orange;
}
</style>
</head>
<body ng-app="app" ng-controller="ctrl">
<form name="custForm">
Name:
<input id="name" ng-class="{someCSS: custForm.name.$dirty}" ng-model="someModel.name" />
<br> email:(change some value)
<input id="email2" name="email2" ng-class="{someCSS: custForm.email2.$dirty}" ng-model="someModel.email2" />
</form>
Touched:{{custForm.name.$touched}}
<br> dirty:{{custForm.email2.$dirty}}
<br>
</body>
We had a similar case - but even added an undo button. When populating the model for the first time, we stored a side-copy (use $angular.copy for a deep copy). Then when a field changed, the directive looked at the old value compared with the new value. E.G. <input ng-class="{highlight-orange:old.name !== new.name}" />
<!DOCTYPE html>
<html lang="en-US">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script>
var app = angular.module('myApp', []);
app.service('mySvc', function() {
this.getData = function() {
return { firstName:'Jack', lastName:'Sparrow' };
}
});
app.controller('myCtrl', function($scope, mySvc) {
$scope.old = mySvc.getData();
$scope.new = angular.copy($scope.old);
});
</script>
<style>
.different { color: red; }
</style>
</head>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
<p>Name : <input type="text" ng-model="new.firstName" ng-class="{different:new.firstName !== old.firstName}"></p>
<h1>Hello {{(new.firstName === old.firstName) ? 'Good, old' : 'Happy, new'}} {{new.firstName}}</h1>
</div>
</body>
</html>
Copy the code above into a file then load it into your browser.

Is it possible to invoke a component on ng-click?

Previously there was a <div>, the contents of which i was toggling on ng-click. With components in Angular 1.5, i moved the contents of the <div>and created a component. I want to load this component on ng-click now.
Is this possible ?
I did not find any help yet. If possible, a help would be great.
Its possible to show/hide the component (having your div content). I have created a plnkr, refer the below code and plnkr link
https://plnkr.co/edit/sZSfslXTDGfvGwiDdBSZ?p=preview
HTML:
<!DOCTYPE html>
<html ng-app="componentApp">
<head>
<script data-require="angularjs#1.5.8" data-semver="1.5.8" src="https://opensource.keycdn.com/angularjs/1.5.8/angular.min.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-controller="componentController">
<button ng-click="showComponent()" id="changeText">Show Component</button>
<div-content ng-if="isShowContent"></div-content>
</body>
</html>
JS:
angular.module("componentApp", [])
.controller("componentController", function($scope) {
$scope.isShowContent = false;
$scope.showComponent = function() {
$scope.isShowContent = !$scope.isShowContent;
document.getElementById("changeText").innerHTML = $scope.isShowContent ? "Hide Component" : "Show Component";
};
})
.component("divContent", {
template: "This is the content of my div"
});

How to add animation to angularjs uib-alert directive

I want to add fade-in animation for new alerts pushed into array and fade-out for dismissed alerts.
Alerts are dismissed automatically after 5 seconds.
I've already included angular-animate ui-bootstrap and ui-bootstrap-tpls libraries.
How can i get these animations working?
See Demo: http://plnkr.co/edit/ecbCA7h2zVA4XnvUHfFX?p=preview
HTML
<html ng-app="myApp">
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.css" />
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.js"></script>
<script src="https://code.angularjs.org/1.5.0/angular-animate.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/1.1.2/ui-bootstrap.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/1.1.2/ui-bootstrap-tpls.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-controller="MainController">
<h1>Alert With Animation</h1>
<uib-alert
ng-repeat="alert in alerts"
type="{{alert.type}}"
dismiss-on-timeout="5000"
close="alerts.splice($index, 1);">{{alert.msg}}
</uib-alert>
<input type='text' ng-model='msg' />
<button ng-click="addAlert(msg,'danger')">Add Alert</button>
</body>
</html>
SCRIPT
(function() {
var app = angular.module("myApp", ['ui.bootstrap', 'ngAnimate']);
app.controller("MainController", function($scope) {
$scope.alerts = [];
$scope.msg = "No Animation!";
$scope.addAlert = function(msg, type) {
$scope.alerts.push({
msg: msg,
type: type
});
};
});
}());
Answer is based on Pankaj's comment.
Which lead me to this article: http://www.yearofmoo.com/2013/08/remastered-animation-in-angularjs-1-2.html
added class='repeat-item' to <uib-alert>..</uib-alert> element.
added proper stylings for animation effects.
<style type="text/css">
.repeat-item.ng-enter,
.repeat-item.ng-leave {
-webkit-transition: 0.5s linear all;
transition: 0.5s linear all;
}
.repeat-item.ng-enter,
.repeat-item.ng-leave.ng-leave-active {
opacity: 0;
}
.repeat-item.ng-leave,
.repeat-item.ng-enter.ng-enter-active {
opacity: 1;
}
</style>
See working demo: https://plnkr.co/edit/CK2lV4mBVGs8q5gyYklE?p=preview
One little glitch
When you click to add an alert for the very first time, there is no fade-in animation. After that, everything seems OK.

How to call angular controller function when ons-switch is changed?

I'm just getting into angular and onsen-ui and ran into a simple problem. I'm hoping the answer is trivial.
I have a ons-switch which I want to execute code in my controller when the switch is changed:
<ons-switch var="mark_as_favorite" onchange="toggleFavorite()"/>
This results in a toggleFavorite is not defined. This makes sense, because the scope is probably different. So how do I access the controller method from the ons-switch?
--Keith
If you are unfamiliar with AngularJS, use var attribute. var attribute dispose a Onsen UI element as a global variable.
index.html
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<script src="components/loader.js"></script>
<link rel="stylesheet" href="components/loader.css">
<link rel="stylesheet" href="css/style.css">
<script>
ons.bootstrap();
function checkIsSwitchEnabled() {
// mySwitch is disposed as a global variable. So mySwitch is accessible from everywhere.
var isChecked = mySwitch.isChecked();
alert(isChecked);
}
</script>
</head>
<body>
<ons-navigator title="Navigator" var="myNavigator" page="page1.html">
</ons-navigator>
</body>
</html>
page1.html
<ons-page>
<div style="text-align: center">
<br/>
<br/>
<br/>
<ons-switch var='mySwitch' onchange='checkIsSwitchEnabled()'></ons-switch>
</div>
</ons-page>
this is what i did..
html
<ons-page ng-controller="yourcntrl">
<ons-switch modifier="list-item" ng-model="obj.IsSelected" ng-change="switchTrigger(obj)"></ons-switch>
</ons-page>
Js
myApp.controller('yourcntrl', function ($scope) {
ons.ready(function () {
$scope.switchTrigger= function (obj) {
alert(obj.IsSelected);
}
});
}
If you use the ngModel directive, Onsen will apply that model to the underlying checkbox and your variable will be updated automatically on change
<ons-switch ng-model="mark_as_favorite">
This is especially useful if you need to update other things on the page as they will update automatically. I use this to show and hide additional options based on the checkbox value and to apply conditional classes:
<div class="example" ng-class="{favorite: mark_as_favorite==true}">Some content</div>
You can use the ng-change attribute to execute code when the ons-switch is toggled.
Example:
<ons-page ng-controller="MyCtrl">
<ons-switch ng-model="MyCtrl.switchState" ng-change="MyCtrl.toggleSwitch(event)">/ons-switch>
</ons-page>
Now you can use event.value to access the boolean if the switch is on or off.

Broken bindings when using modal dialog in angular

I am using the ngModal modal dialog box directive for my angular application. It's displaying some weird behavior that I don't quite understand. When I attach variables directly to the controller's $scope and reference them in the dialog box, the binding breaks. Changing their values in the dialog has no effect on the variables in the controller. But if I add the variables as properties to an object and then add the object to the $scope it works. In other words, if I do this
$scope.v1 = 1
$scope.v2 = 'abc'
it doesn't work, but if I do
$scope.myData = {
v1: 1,
v2: 'abc'
}
things work fine. What's the deal? You can see a working version of the code here and a broken version here.
If the plunk apps aren't loading for you, here is the code:
html
<!DOCTYPE html>
<html data-ng-app='ngModalDemo'>
<head>
<title>ngQuickDate Demo</title>
<link href="http://netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="ng-modal.css" media="all" />
<style type='text/css'>
body{font-family:'Helvetica Neue',Helvetica,sans-serif}
h1 { padding: 0; margin: 0; }
.ng-cloak { display: none; }
</style>
</head>
<body>
<div ng-controller='DemoController'>
<modal-dialog show='myData.modalShown' width='500px' dialog-title='Modal Dialog Title' on-close='logClose()'>
<p>This is some html content</p>
<p>
<label for='hello'>Hello:</label>
<input type='text' name='hello' ng-model='myData.hello' />
</p>
<p>
<label for='foo'>Foo:</label>
<input type='text' name='foo' ng-model='myData.foo' />
</p>
<img src='http://upload.wikimedia.org/wikipedia/commons/2/22/Turkish_Van_Cat.jpg' width='300px'/>
</modal-dialog>
<button ng-click='toggleModal()'>Toggle Modal</button>
<br/>
<br/>
<br/>
<p><strong>Shown?</strong> {{myData.modalShown}}</p>
<p><strong>Hello</strong>: {{myData.hello}}</p>
<p><strong>Foo</strong>: {{myData.foo}}</p>
</div>
<script type="text/javascript" src="https://code.angularjs.org/1.3.0-beta.5/angular.js"></script>
<script type="text/javascript" src="ng-modal.js"></script>
<script type="text/javascript" src="app.js"></script>
<script type="text/javascript" src="controller.js"></script>
</body>
</html>
angular app
app.config(function(ngModalDefaultsProvider) {
return ngModalDefaultsProvider.set({
closeButtonHtml: "<i class='fa fa-times'></i>"
});
});
angular controller
app = angular.module('ngModalDemo')
app.controller('DemoController', function($scope) {
$scope.myData = {
link: "http://google.com",
modalShown: false,
hello: 'world',
foo: 'bar'
}
$scope.logClose = function() {
console.log('close!');
};
$scope.toggleModal = function() {
$scope.myData.modalShown = !$scope.myData.modalShown;
};
});

Resources