I have the following html:
<input type="checkbox" ng-model="user.show_value" ng-blur="update_show_value()">
A value (true / false) is fetched from the database and passed to the ng-model. Depending on it, the checkbox is checked / uncheked. The function inside ng-blur triggers the update in the database and works:
$scope.update_show_value() = function() {
if ($scope.user.show_value != undefined) {
$scope.loading = true;
//IF VALUE IS VALID, CALL THE UPDATEPIN FUNCTIONn
User.updatevalue($scope.user)
//IF SUCCESSFUL, GET VALUE
.success(function(data) {
$scope.loading = false;
$scope.formData = {}; //CLEAR FORM SO THAT USER CAN ENTER NEW DATA
$scope.user.show_value = {type : $scope.user[0].show_value}; //PASS VALUE IN OUR SCOPE
});
}
};
The issue is that I would have to use the checkbox from other devices that don't support the click event. From these devices I should use the equivalent of enter (keycode 13). So I added the onkeydown event to detect when the enter key is being pressed on the checkbox. Using an example from w3schools, I see it works (here is the example http://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_event_key_keycode3)
<input type="checkbox" ng-model="user.show_value" onkeydown="keyCode(event)" ng-blur="update_show_value()">
Now I want to call the update function when the onkeydown event detects that the code 13 was pressed. Something like this:
<script>
function keyCode(event) {
var x = event.keyCode;
if (x == 13) {
alert ("You pressed the Escape key!");
update_show_value();
}
}
</script>
However, calling update_show_value inside the keycode function does not work. Actually, adding update_show_value inside the keycode function causes everything else not to work (ex. the alert)
So for some reason I think that scope functions cannot be called inside javascript functions. If that is true, is there a workaround?
You can get the scope object outside of Angular by using:
angular.element(event.target).scope(); // and then call whatever functions you want to on that scope object
You can define your own directive to handle keydown
angular.directive('myKeydown', [ function () {
return {
link: function(scope, elem, attrs) {
element.bind('keydown', function() {
scope.update_show_value();
});
}
};
}]);
Or just use ng-keydown instead: https://docs.angularjs.org/api/ng/directive/ngKeydown :
$scope.keyCode = function($event) {
. . .
$scope.update_show_value();
};
Remove () from $scope.update_show_value
Try Below Code:
<script>
var app=angular.module("myApp", []);
app.controller("myCtrl", function($scope) {
$scope.update_show_value = function() {
alert(1);
};
});
</script>
Related
I'm pretty new on JS and I need to call an external function when an onblur event happens with the <input type="text" id="username">.
Here is the code:
<input type="text" id="username">
<input type="hidden" id="feedback" value="">
<script>
var elUsername = document.getElementById("username");
elUsername.onblur = PagSeguroDirectPayment.onSenderHashReady(function(response){
if(response.status == 'error') {
console.log(response.message);
return false;
}
var hash = response.senderHash; //Hash will be available here.
var elFeedback = document.getElementById("feedback");
elFeedback.setAttribute("value", hash);
});
</script>
The code shows no error but as soon as the page loads, the function is being called, sending the hash value immediately to the <input type="text" id="username">. Instead of this, I'd like that this value was only available as the onblur event had been triggered.
Thank you!
The onblur event handler expects a reference to a function which it can execute when the blur occurs. You're instead executing the function and then assigning onblur the return value of your onSenderHasRead() method.
As stated above, onblur expects a reference to a function. In order to do this, you can write your own function which performs the code you want to run when the blur occurs. Then, you can assign onblur a reference to this function:
function handleBlur() {
PagSeguroDirectPayment.onSenderHashReady(function(response) {
if (response.status == 'error') {
console.log(response.message);
return false;
}
var hash = response.senderHash; //Hash will be available here.
var elFeedback = document.getElementById("feedback");
elFeedback.setAttribute("value", hash);
});
}
elUsername.onblur = handleBlur; // a reference to the handleBlur function (note: we are not calling this function, as onblur will call it for us)
Having to create an additional function and then using it later on can disrupt the flow of your code sometimes, so you'll often see people use an anonymous function, which are function expressions that can be assigned in-line, and don't require a name (hence the anonymity):
// onblur will call this --\/ function when a blur occurs
elUsername.onblur = function() {
PagSeguroDirectPayment.onSenderHashReady(function(response) {
if (response.status == 'error') {
console.log(response.message);
return false;
}
var hash = response.senderHash; //Hash will be available here.
var elFeedback = document.getElementById("feedback");
elFeedback.setAttribute("value", hash);
});
}
These days it's often good practice to use .addEventListener() rather than modifying the element's blur event handler. This way if another library or piece of code overwrites the onblur property later on, your blur event will still be registered:
elUsername.addEventListener('blur', function() {
PagSeguroDirectPayment.onSenderHashReady(function(response) {
if (response.status == 'error') {
console.log(response.message);
return false;
}
var hash = response.senderHash; //Hash will be available here.
var elFeedback = document.getElementById("feedback");
elFeedback.setAttribute("value", hash);
});
});
I have a custom icon component using isolate scope where a user can define what he or she wants to happen on ng-click:
<ers-icon name="history" ng-click="ctrl.clickAlert('history')"></ers-icon>
This calls a method from within the user's controller as follows:
this.clickAlert = function (icon) {
alert("You selected the " + icon + " icon.");
}
I need to add enter key functionality to the icon component without adding any other code, from I have above, to my html element. So essentially listen for the enter key press from within the directive and evaluate the ng-click directive on ers-icon. Here is what I have as the icon directive:
// on click works fine
.on("click", (event:JQueryEventObject):void => {
if (this.ngDisabled) {
event.preventDefault();
event.stopPropagation();
}
});
}
//execute whatever function is specified inside ng-click on enter key press
.on("keydown", (event:JQueryEventObject):void => {
if (event.keyCode === 13) {
if (this.ngDisabled) {
event.preventDefault();
event.stopPropagation();
} else {
// need to execute ng-click here
// this try doesn't work, gives me undefined
$scope.$apply(() => {
$scope.$eval($attr.ngClick);
}
}
}
});
This runs fine on enter key press but I can't get the controller function defined on ng-click to run.
I thought maybe $eval or $parse would work but it looks like those will only evaluate expressions within {{}}. What is the best way to execute that ng-click attribute so that when a user hits the enter key, the "this.clickAlert" function is ran and an alert is shown on the screen?
I can't really change any of the code as is above, just looking for the solution within the else statement of the on keydown listener.
I solved it this way:
.on("keydown", (event:JQueryEventObject):void => {
if (event.keyCode === 13) {
if (this.ngDisabled) {
event.preventDefault();
event.stopPropagation();
} else {
// need to execute ng-click here
this.element.trigger("click");
}
}
});
I'm using Angular JS and I need to write a directive that will initiate a function ONLY when the spacebar (32) gets pressed twice in a row. The app has forms also and users might need to actually hit space twice in a textarea or input field, so we need to account for that as well. We also need to make sure the page doesn't scroll when pressing the spacebar, but doing event.preventDefault(); actually prevents the spacebar from being used to type a space in a form element. Any ideas as to how to accomplish this? Is it even possible? I might consider binding to a key combination instead if this is too difficult. Here is a sample of what I have so far:
(function() {
"use strict";
angular
.module("app.spaceFunc")
.directive("triggerFunc", triggerFunc);
triggerFunc.$inject = ["$window"];
/* #ngInject */
function triggerFunc($window) {
var directive = {
link: link,
restrict: "A"
};
return directive;
function link(scope, element, attrs) {
var upHitOnce = false;
angular.element($window).bind("keydown", function(event) {
if ((event.keycode || event.which) === 32) {
//Prevents page scrolling (spacebar default's behaviour)
event.preventDefault();
if (upHitOnce) {
//some function gets executed here
console.log("Spacebar pressed twice");
upHitOnce = false;
} else {
upHitOnce = true;
}
} else {
upHitOnce = false;
}
});
}
}
})();
The directive is attached to the body element
<body trigger-func>
I don't know how I can intercept a keydown event of the window and set from there an angular var into the scope, of a specify controller.
Here is a simple way to do it from your controller.
angular.element(window).bind("keydown",keydown);
function keydown(e) {
$scope.eventKeydown = e.keyCode;
$scope.$apply();
}
You can use this:
window.onkeydown = keydown;
function keydown(e) {
$scope.eventKeydown = e;
console.log(e);
console.log($scope.eventKeydown);
}
i have an html textbox with onkeypress event to send message like below
<input type="text" data-bind="attr:{id: 'txtDim' + $data.userID, onkeypress: $root.sendMsg('#txtDim' + $data.userID, $data)}" />
I have written javascript function to to send message while preesing enter button like below:
self.sendMsg = function (id, data) {
$(id).keydown(function (e) {
if (e.which == 13) {
//method called to send message
//self.SendDIM(data);
}
});
};
In my case i have to press enter button 2 times to send the message.
1: keypress call self.sendMsg
2: keypress call self.SendDIM
But i need to send message on one keypress only. It can be done in plain javascript only. But i need viewmodel data, so applied in data-bind. So not working fine.
The reason you need to press enter twice is that your sendMsg method is only attaching a handler to the keydown event. This handler is then invoked on the second button press.
A better approach would be to write a custom binding handler that attaches the event handler and passes the view model through:
ko.bindingHandlers.returnAction = {
init: function(element, valueAccessor, allBindingsAccessor, viewModel) {
var value = ko.utils.unwrapObservable(valueAccessor());
$(element).keydown(function(e) {
if (e.which === 13) {
value(viewModel);
}
});
}
};
You can see a running example here
I have added keypress event like below to textbox
<input type="text" data-bind="attr:{id: 'txtGoalsheetNote' + $data.userID}, event:{keypress: $root.SendMsg}" />
And in javascript i have added the following method by keeping event as a parameter
self.SendMsg= function (data, event) {
try {
if (event.which == 13) {
//call method here
return false;
}
return true;
}
catch (e)
{ }
}
Then its work.