CDK Focus Trap breaks on click outside dialog with Shift Tab - html

I have a focus trap that activates when an angular material dialog is opened. A parent component contains the cdkTrapFocus directive from the a11yModule (https://material.angular.io/cdk/a11y/api#CdkTrapFocus), and it's various children can have a varying number of inputs.
The focus trap works as expected when the dialog is opened, preventing the user from pressing tab or shift-tab to access items behind the dialog. However, when a user clicks on the grayed-out area behind the dialog, then presses shift-tab, they gain access to all items behind the dialog.
The focus trap remains broken until they press shift-tab (or tab) enough times to move the focus back inside the dialog. The correct behavior would be that the focus only ever stays trapped in the dialog, no matter what is clicked on inside or outside the dialog.
For the most part I have examined the link above to see what options there are to ensure focus remains trapped, but It has been difficult to determine what directives would be most useful for this problem. Below is the parent component html template.
<div class="dialog-frame dialog-fade dialog-backgray" [ngClass]="{ 'in': shown }" role="dialog">
<div class="dialog-main" [style.width]="dialogWidth" id="dialog-main" cdkTrapFocus>
<ng-template #element> </ng-template>
</div>
</div>
If anyone reading this has a solution to this, I would appreciate your help.

I ran into the shift-tab issue. The solution for me was to add a keydown listener, which prevents focus if the event path is not in the modal:
#HostListener('document:keydown', ['$event'])
onTab(event) {
if (event.key == 'Tab' && this.modalIsOpen) {
let path = event.composedPath();
let modal = path.find((element) => element.tagName && element.tagName.toLowerCase() == this.modalComponentTagName);
if (path && !modal) {
// Tabbing outside of the modal.
event.preventDefault();
this.focusOnFirstElementInModal();
}
}
}
For me this.modalIsOpen is this.document.body.classList.contains('modal-open'), this.modalComponentTagName is 'app-donate-modal', and this.focusOnFirstElementInModal() focuses on the modal's close button.

Related

How to not allow user to enable input editing [duplicate]

I have a button as follows:
<input type="submit" class="button" value="FooBar" name="FooBar" id="FooBar" disabled="disabled">
I am enabling this button only when certain parameters are met. To test whether it was secure, I pressed F12 (or right click -> Inspect Element) and edited out the text disabled="disabled". Doing this overrides my code and that is scary. How can I prevent someone from changing it in this manner?
I am using php and jquery in this page and using the latter to enable or disable the button. I have checked the jquery click function and it not only executes, but shows the button as not disabled. The alert below reads Disabled: false
$("#FooBar").click(function(){
alert('Disabled: ' + $(this).is('[disabled=disabled]'));
})
So how can I prevent a user from changing the button disabled state and thus overriding my logic?
You can disable the right-click by doing:
document.addEventListener('contextmenu', event => event.preventDefault());
but it is not recommended. Why? It achieves nothing other than the annoying user
OR
Alternatively, a better approach is to recheck your validations in submit action and simply returns if it fails, in this case, if user inspects and changed the state of a button, the button stays idle and will not allow to proceed
$("#FooBar").click(function() {
if (!this.acceptenceCriteria()) {
return;
}
alert('Disabled: ' + $(this).is('[disabled=disabled]'));
})
You can't stop people from using dev tools.
You can try a couple of tricks to disable right clicking (like the one below) which will stop some number of people but ultimately the solution to your problem is to use html and http properly.
$(document).bind("contextmenu",function(e) {
e.preventDefault();
});

Polymer message box with default button

Using Polymer 2 and paper-dialog I have created message boxes for my application. For the usual information boxes with only an OK button I would like the enter key to trigger the same handler as the button does. Any idea how to accomplish this?
Note that I also implemented an InputBox and there I used the on-keydown event of the single input element. But for an information box there is no text input element - only static text and an OK button.
You could use a keydown-handler on the paper-dialog itself, and have that handler trigger the button's click-handler:
<paper-dialog on-keydown="_onDialogKeyDown">
<button id="myButton" on-click="_submit">OK</button>
</paper-dialog>
// in Polymer element
_onDialogKeyDown(e) {
if (e.keyCode === 13) {
this.$.myButton.click();
}
}
demo

How to make an input field required before being able to click a input button rather a submit button?

I have a question about making input fields required before being able to click a input button (not submit button). My code below only will send out the requirement notice after a submit button is click.
I have my form split into 3 div's with 'next' buttons in between which conditionally displays the next div. How do I make the input field to be required before the 'next' button brings up the next div portion of my form?
You should post the html for your question. It is missing. That being said, look into the blur event that gets trigger everytime an input loses focus. You could add the logic to display an error to the user and disable the next button.
http://www.w3schools.com/jquery/event_blur.asp
You have two main options:
FIRST OPTION
You could disable your button like so: <input id="but" type="button" disabled>, and then, you could set your field onchange method to enable the button i. e. <input type="text" onchange="changed();"> and in your script,
function changed(){
if(1 == 1){ // custom test
document.getElementById("but").disabled = false;
}
}
SECOND OPTION
In your button handler, verify your textfield is filled i. e.
function butHandler(){
if(document.getElementById("textfield").value !== "") {
// do your actions
}
}

how to remove "X" button from popup in angularJS

How can I remove "X" button from Popup in angularJS? I don't need it because the cancel button that I have implemented has same functional but the "X" button couldn't reset modifies. It will be implemented as default in HTML:
<div class="ngdialog-close"></div>
While opening popup you need to pass one option showClose which will hide close button if its false.(default true)
Code
ngDialog.open({
template: 'templateId',
className: 'ngdialog-theme-default',
showClose: false //<-- while opening dialog make it false
});
You have to read documentation before integrating (using) any module in your project. Here is the complete list of options for ngDialog.
Hide close button

Polymer input capture enter event

I'm trying to detect when a user presses return/enter in a chat box to send the message. How do I detect this for a paper-input element?
paper-input inherits from core-input, which fires a change event when the users hits enter/return or the element loses focus. If you don't care about the losing focus case (e.g only want the case where the user hits ENTER), you could check the document.activeElement:
document.querySelector('paper-input').addEventListener('change', function(e) {
if (document.activeElement == this) {
console.log('ENTER hit on aper-input');
}
});
http://jsbin.com/godaqugacecu/1/edit
See http://www.polymer-project.org/docs/elements/core-elements.html#core-input.