Angular PrimeNG FocusTrap Tabbing Issue - html

I have two time only calendar components which I used to be able to tab directly through with PrimeNG 5.
However with PrimeNG 9 with focusTrap set to false (e.g. [focusTrap]="false") and with onBlur closing the overlay (this.calendar1.overlayVisible = false;). 2 Tab presses are required to go to the next component, Shift-Tab works correctly.
The issue is when the tab is pressed, the up arrow for the time on the popup/overlay grabs focus and then the overlay is closed, so an additional tab is required to exit the time only calendar component, see this StackBlitz:
https://stackblitz.com/edit/primeng-calendar-demo-7qcnhr?file=src/app/app.component.html
How can I through the calendar components, can the popup/overylays not grab focus like it did in PrimeNG 5?
Any help would be appreciated.
The code of interest is :
app.component.html
<p-calendar #calendar1 [(ngModel)]="date" [timeOnly]="true" [focusTrap]="false" (onBlur)="hideCalendar(calendar1)"></p-calendar>
<p-calendar #calendar2 [(ngModel)]="date" [timeOnly]="true" [focusTrap]="false" (onBlur)="hideCalendar(calendar2)"></p-calendar>
app.component.ts
hideCalendar(calendar: Calendar) {
calendar.overlayVisible = false;
}
Cheers.

Related

Angular - Unselect all Checkbox

I was able to successfully Add Select All functionality when checkbox is clicked. However I am unable to Uncheck All when all items are already selected
Here is the link to code - https://stackblitz.com/edit/angular-material-select-all-aota2app.component.html
Your function unselectAll() has never been called
<mat-checkbox (ngModelChange)="selected = !selected" [ngModel]="checked">Check/ Uncheck</mat-checkbox>

CDK Focus Trap breaks on click outside dialog with Shift Tab

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.

How to fix Angular bug requiring user to click a separate element before choosing a second mat chip

Here is the link for an example of the issue I will attempt to describe. In the chips autocomplete example, click the text box to select a new fruit.
Now, before clicking anywhere else, click again on the text box as you did before.
This should result in no options showing up. The issue here is that the user must either begin keying in a new selection or first click another element in the window before matchip will show the options to choose from. I am wondering if there is a way to fix this issue. I would like a user to be able to choose a selection from the list and then immediately click the text box as they had before and make a new selection.
I'm using mat-chip-list inside an outer *ngFor iterating over a FormArray.
Here is what I'have done. It's pretty efficient :
<input
#validatorInput
#operationTrigger="matAutocompleteTrigger"
[formControl]="contactCtrl"
[matAutocomplete]="auto"
[matChipInputFor]="chipList"
(blur)="contactCtrl.setValue(''); validatorInput.value='';"
(click)="contactCtrl.setValue(''); validatorInput.value=''; operationTrigger.openPanel()">
The trick is
Always clear your html input and your (shared) formControl with an empty and not null value each time the blur and click events occur.
Do NOT do this 'clear' on the input focus event. (Because when you delete the last chip, the input is auto-focus and you will have the famous Expression has changed after it was checked.
Call operationTrigger.openPanel(); when the user click on the input
Setting contactCtrl.setValue(''); allows your autocomplete panel to be automatically opened when you call operationTrigger.openPanel()
Setting validatorInput.value=''; is just a way to properly sync your formControl with the html input to ensure a good UX/UI behavior.
Inside my formArray, the formControl is the same for all the inputs but it does not matter since the user can only manipulate one input at a given time
Since you didn't post your code and you mention the example on the material site I'm going to do it as a fork of the stackblitz example they have on their site.
But this will allow you to open the autocomplete panel again despite having had the cursor there and choosing an option previously.
// Using MatAutocompleteTrigger will give you access to the API that will allow you to
// to open the panel or keep it open
...
#ViewChild(MatAutocompleteTrigger, {static: false}) trigger: MatAutocompleteTrigger;
...
ngAfterViewInit() {
fromEvent(this.fruitInput.nativeElement, 'click')
.pipe(
tap(() => {
this.trigger.openPanel()
})
).subscribe()
}
Link to the full stackblitz:
https://stackblitz.com/edit/angular-sb38ig

Clear All button on primeng multi-select

Hi I am working on a Angular4 application and for UI I am using Primeng.
I have a multi-select element which behaves pretty much the same as it does over here https://www.primefaces.org/primeng/#/multiselect
The only thing I want different is on the drop-down, when "X" (close) button is clicked, I want it to clear all the selection instead of closing the drop-down itself.
Is there any way to achieve that in primeng ?
Help is appreciated !
You can manually trigger the checkbox in the left by jquery.
declare var jquery:any;
declare var $ :any;
$('.ui-chkbox-box.ui-widget.ui-corner-all.ui-state-default').trigger('click')
or you make the value of the p-multiselect equal to [].
Ex.
//html
<p-multiSelect #multiselect>
<button type="button" (click)="functionToClear(multiselect)"</button>
</p-multiselect>
//ts
functionToClear(multiselect): void {
multiselect.value = [];
}
It isn't possible, but you can clear all the selection by clicking the checkbox in the left corner twice.
While it isn't a supported functionality of the Multiselect PrimeNg component, if you really want it to do that, you would have to manually edit the component, multiselect.js, and modify the close(event) function to do what you want.
you can use formGroup and try to clear value following way:
html:
<ng-multiselect-dropdown [(ngModel)]="data"
[data]="fetchedData" [settings]="customeSettings"
formControlName="myControl">
</ng-multiselect-dropdown>
.ts:
this.form_name.controls.myControl.setValue("");
normally the multi-select input in primeng is binded to a property that holds the selected members, usually an array.
you can use a reset button for example that when clicked, it will empty that propery/array and this will clear all the selected check boxes of the multi-select.
Since PrimeNg version 13, you can use [showClear]="true" property to display an 'X' icon next to the control value.

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