Trying to create a keyboard shortcut for a button using Angular - angularjs

I want to be able to set a keyboard shortcuts for buttons in an application I'm building. I'd like to be able to pass in the keyboard button code as a parameter to make it configurable. Here's what I have so far using the documentation before I got stuck. HTML:
<div ng-controller="BtnCtrl">
<button class="primary-btn" type="submit" ng-keypress="press($event, '12')">Button</button>
</div>
JavaScript:
angular.module('App')
.controller('BtnCtrl', function ($scope) {
$scope.press = function($event, hotKeyRef) {
if ($event.keyCode==hotKeyRef) {
//need some code here to trigger the button press
}
}
});
So using my approach, I'm unsure of a) how to trigger the button press from inside the function and b) whether this is the correct way of passing in the keyCode data.
I might also be taking completely the wrong approach, so any other guidance would be appreciated.
Thanks

For the question a).
The main uses of a < button > html element is to fire an event on a click.
So if you want to use a keypress, why use this element ? I don't really see what you want to achieve. that seems controversal.
for b) :
By default, ng-keypress is intended to be used in an input element.
Otherwise, it seems that some posts, where I inquired, manage to make it work out.
You can see what it can look like, for example on this post (Is it possible to listen for arrow keyspress using ng-keypress?)
in which the person trying to setup the konami code.
Moreover, it seems that you can have trouble depending on which browser (Chrome, Firefox, Safari, IE) you uses. Be careful.
I hope this could help you.

hi there is an excellent plugin for your scenario u can check the below link
https://github.com/chieffancypants/angular-hotkeys/
u can also check the below stackoverflow link
What is AngularJS way to create global keyboard shortcuts?

Related

Angular-Material "md-datepicker" directive - "md-open-on-focus" issue

As exampled in this fiddle, there's seems to be an inconsistency issue with opening the md-datepicker multiple times when using md-open-on-focus.
The problem occurs after opening and closing it for the first time (which works ok) - after that, it'll randomly open on click and become unstable.
<md-datepicker ng-model="timeModel" md-hide-icons="all" md-open-on-focus></md-datepicker>
Has anyone experienced the same behavior and found a solution? Thanks.
Currently, the problem with md-hide-icons="all" and md-open-on-focus used together is, when you click outside, the focus remains on the input. But, since there are no icons to click for and focus is already on the input, there is no way we can open the datepicker.
If you click outside, and click outside again, focus from the input is gone, and it will work normally from there on which should arguably be the expected behavior.
But if you don't want such behavior, we can do something to change it!
Now, having a look at the datePicker code, in the closeCalendarPane function, they have
self.calendarPaneOpenedFrom.focus();
which is responsible for keeping focus on input. If we remove it, it would lose focus while clicking outside (or selecting a date from the picker) which is exactly what we want. They have some code handling input when openOnFocus is true but not sure how that helps!
Forked jsfiddle (changed line is at #31449)
Also, changing the library code isn't what we would normally want to do. So, for now, you could have a workaround like having a callback on md-is-open and removing the focus from the input element inside callback using your favourite way (jQuery/angular.element or pure JS) [As mentioned by #quirimmo]
Hope that helps!
Unfortunately this functionality it's not implemented yet in angular material.
If you take a look to the official examples, you will see the same behavior in the one using md-open-on-focus.
https://material.angularjs.org/1.1.0/demo/datepicker
You need a little workaround in order to make it works. Just changed your example code:
HTML:
<md-datepicker ng-model="timeModel" md-hide-icons="all" md-is-open="isOpen" md-open-on-focus></md-datepicker>
JS:
angular.module('sandbox', ['ngMaterial'])
.controller('Ctrl', function($scope, $timeout) {
$scope.timeModel = new Date();
$scope.$watch('isOpen', function(newValue, oldValue) {
if (!newValue && oldValue) {
document.querySelector('.md-datepicker-input').blur();
}
});
});
https://jsfiddle.net/ecs9ao89/
You can achieve also the same behavior defining a new directive and requiring the base datepicker of angular material, and open it on click.
But this solution is smaller effort.

Antd Dropdown component with OK and reset options

I would like to use Dropdown component and provide two options OK and reset buttons (as provided in Table example),
after some research I didn't find any mention about this functionality in Dropdown or Menu component api,
Does anyone implemented such functionality outside of Table components, any inputs how this is work?
The code implementing the OK and RESET options of that component are implemented specifically for the table dropdown here (https://github.com/ant-design/ant-design/blob/master/components/table/filterDropdown.tsx#L196-L222).
You can either implement it similarly (i.e. wrap the Menu with a div and handle the events yourself) or you could create an ant design github ticket and ask whether a) this should be part of the design specification and b) whether there should be a reusuable way to consume this
According to this issue in github such functionality can be reached via Popover with Menu + Buttons
You will want to bind to the change event via javascript/jQuery.
On $(document.ready() you can call a function that will do this binding.
Then you just check the value of the dropdown via a jQuery selector.
<script>
$(document).ready(function() {
$("dropdownSelector").change(function() {
var val = $(this).value();
//logic to do things
});
});
</script>
You can check out different ways to use jQuery selectors here: https://api.jquery.com/category/selectors/

How do I return focus to an element when the entire page changes?

I have a complicated setup. My application is driven by a set of "rules" which dictate what the user interface is. The UI is rendered by looping through the rules and creating the individual dropdowns. Initially, everything renders properly. However, once a user makes a change to the UI, other rules may be affected. In my application, an api call is made, which then returns a modified set of rules. In the attached plunker, I've simplified things such that only the new set of rules is applied, which causes the page to re-render. The problem is that my users would like to be able to tab between all of the entries on the page and make changes. However, once the page is re-rendered, the currently selected page element is now gone nothing has the focus. I've tried to put the focus back on the proper element by tracking a common Id, but to no avail.
Using either of these doesn't seem to work.
var el = document.getElementById(focusId);
el.focus();
angular.element(el).focus();
I've also tried using the autofocus attribute on the dropdown that I want to have focus, but that didn't work either. I'm using angularjs 1.2. Any ideas are appreciated.
http://plnkr.co/edit/ND9PKqULIOlixWR4XChN?p=preview
If you want to assign auto focus dynamically to a element on the DOM from angular you can use this:
var myEl = angular.element(document.querySelector('select'));
myEl.attr('autofocus',"attr val");
You can also pass in an id like: angular.element(document.querySelector('#focusId'));
You can look here for a prior answer which may be of some more help!
-Cheers!
Problem here is, you are trying to focus the element before the blur event completes. So you need to execute the focus code after blur event. Async execution of your focus code would solve the problem. You can use either setTimeout or $timeout.
setTimeout(function(){
angular.element('#'+focusId).focus();
/* //or
var el = document.getElementById(focusId);
el.focus();
*/
});
or
$timeout(function(){
angular.element('#'+focusId).focus();
/* //or
var el = document.getElementById(focusId);
el.focus();
*/
});
dont forgot to inject $timeout to your controller if you are using second code. Hope this helps :)

protractor - issues with scrolling into infinite scroller

I have a protractor test looking for a record in my infinite scroller component like this.
searchPage.searchEntitlement('search criteria');
var myHiddenElementInScroller = element(by.repeater('result in ctrl.results track by $index').row(12));
browser.driver.executeScript(function () { arguments[0].scrollIntoView(); }, myHiddenElementInScroller .getWebElement());
myHiddenElementInScroller.click();
This is supposed to scroll to the element and click it. Instead its throwing me element not visible error.
Has anyone come across this situation? Any help greatly appreciated.
You might need to explicitly wait for the scrolling into view actually happen:
browser.driver.executeScript("arguments[0].scrollIntoView()", myHiddenElementInScroller.getWebElement()).then(function () {
myHiddenElementInScroller.click();
});
Or, with browser.actions():
browser.actions().mouseMove(myHiddenElementInScroller).click().perform();
In few scenarios the element which we are looking for will be covered with some other element from DOM.when protractor tries to click it,the click will be received by the element that covers the actual element. So in such situation you need to use native javascript click event. Look at the below code.
browser.executeScript("arguments[0].click()", myHiddenElementInScroller.getWebElement())
The above code will send a click event directly to the mentioned webElement even if it is visible or not.
NOTE: this is not the recommended way for clicking an element. but you can you this in scenarios where you have no other workaround to achieve the click event.
Thanks for all the responses. I was able to resolve this issue by using element(by.CssContainingText(cssSelector, searchText)) locator.

AngularJS Save Browse History

I'm trying to solve a problem. I want that when a perform an action or function in the controller to be saved in the brose history. For example, I want to do this:
Type something in a textbox.
Click a link to call a function that will set the string I typed to a variable in $scope and save it at the browser history.
Do the same as the previous step with a different value.
If I click the "back" button from the browser, I want to display the first value I entered.
I have a very simple example of what I want but I don't know what do I have to add to be able to use the "back" and "forward" button from the browser.
http://jsfiddle.net/XMFua/
Thank you very much in advance!
You should use the $location service to set the URL. I don't know how to make it work on jsFiddle, however the following should work:
http://jsfiddle.net/marcenuc/BSDxG/

Resources