Skip to content

extending #23

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -134,5 +134,8 @@
}
}
}
},
"cli": {
"analytics": false
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,16 @@ export class NgxTouchKeyboardComponent {
debug = false;

@Output() closePanel = new EventEmitter<void>();
//This event that come from the application, and deal with accept click.
//With this event we can declare the method that treatment with this event in the parent app
@Output() acceptClick: EventEmitter<NgxTouchKeyboardComponent>;
//This method responsible validate the input text value.
//For example if you wont to accept only numbers input.
validate: ((args: string | undefined) => boolean) | undefined;
//This variable declare for us if We make changing text value after We click on 'accept' button,
//If We click on 'accept' button and We pass the validation then We need to change the final text value
//Otherwise (if We not passing the validation process) then We need to return back to the previous text.
textBeforeAccept: string = '';

private _activeButtonClass = 'active';
private _holdInteractionTimeout!: number;
Expand All @@ -45,7 +55,10 @@ export class NgxTouchKeyboardComponent {
private _sanitizer: DomSanitizer,
private _elementRef: ElementRef<HTMLInputElement>,
@Inject(LOCALE_ID) private _defaultLocale: string
) {}
) {

this.acceptClick = new EventEmitter<NgxTouchKeyboardComponent>();
}

// -----------------------------------------------------------------------------------------------------
// @ Accessors
Expand Down Expand Up @@ -191,8 +204,26 @@ export class NgxTouchKeyboardComponent {

// And set focus to input
this._focusActiveInput();
//When we setting
this._activeInputElement.select();
}

/**
* Copy the value text from the input text element
*/
setTextBeforeAccept(): void {
this.textBeforeAccept = this._activeInputElement != undefined ? this._activeInputElement.value : '';
}


/**
* Get the active input text element
*/
getActiveInputElement(): HTMLInputElement | HTMLTextAreaElement | null {
return this._activeInputElement;
}


/**
* Check whether the button is a standard button
*/
Expand Down Expand Up @@ -253,7 +284,30 @@ export class NgxTouchKeyboardComponent {
this.layoutName =
this.layoutName === 'alphabetic' ? 'shift' : 'alphabetic';
return;
} else if (button === fnButton.DONE) {
}
else if (button === fnButton.DONE) {
//If we click on 'done' button we need to check the value before We close the keyboard panel
if (this.validate) { //If there is validation method declarations
if (this.validate(this._activeInputElement?.value)) { //If the validation pass then
//We accept the value changed
this.textBeforeAccept = this._activeInputElement != undefined ? this._activeInputElement.value : '';
//We calling to accept method to make any thing you wont and declare at this 'accept' method
this.acceptClick.emit(this);
}
else //If the validation not pass then
{
//We need return to the previous text
//For example if we accept only number and the text value was '222' and we changed him to '222ttg' value
//Then we will return to '222' number
if(this._activeInputElement != null && this._activeInputElement)
this._activeInputElement.value = this.textBeforeAccept;
}
}
else {
//If there is no validation method then we accept any text and setting him and calling to 'accept' method to make any thing you wont
this.textBeforeAccept = this._activeInputElement ? this._activeInputElement.value : '';
this.acceptClick.emit(this);
}
this.closePanel.emit();
return;
}
Expand Down
111 changes: 109 additions & 2 deletions projects/ngx-touch-keyboard/src/lib/ngx-touch-keyboard.directive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ import {
ComponentRef,
Directive,
ElementRef,
EventEmitter,
Inject,
Input,
OnDestroy,
Output,
} from '@angular/core';
import { DOCUMENT } from '@angular/common';
import { ComponentPortal } from '@angular/cdk/portal';
Expand All @@ -16,13 +18,17 @@ import {
PositionStrategy,
} from '@angular/cdk/overlay';
import { NgxTouchKeyboardComponent } from './ngx-touch-keyboard.component';
import { fnButton } from './Locale/constants';

@Directive({
selector: 'input[ngxTouchKeyboard], textarea[ngxTouchKeyboard]',
selector: 'input[ngxTouchKeyboard], textarea[ngxTouchKeyboard], div[ngxTouchKeyboard]',
exportAs: 'ngxTouchKeyboard',
})
export class NgxTouchKeyboardDirective implements OnDestroy {
isOpen = false;
@Output() acceptClick: EventEmitter<NgxTouchKeyboardComponent>;

@Input() validate!: ((args: string | undefined) => boolean) | undefined;

private _locale!: string;
/** locale */
Expand All @@ -34,6 +40,26 @@ export class NgxTouchKeyboardDirective implements OnDestroy {
this._locale = value;
}

private _divMode!: boolean;
/** div mode */
@Input()
get ngxTouchKeyboardDiv() {
return this._divMode;
}
set ngxTouchKeyboardDiv(value: any) {
this._divMode = coerceBooleanProperty(value);
}

private _openWithButton!: boolean;
/** open virtual keyboard with button instead of focus on text input*/
@Input()
get ngxTouchKeyboardOpenWithButton() {
return this._openWithButton;
}
set ngxTouchKeyboardOpenWithButton(value: any) {
this._openWithButton = coerceBooleanProperty(value);
}

private _debugMode!: boolean;
/** debug mode */
@Input()
Expand Down Expand Up @@ -63,8 +89,28 @@ export class NgxTouchKeyboardDirective implements OnDestroy {
constructor(
private _overlay: Overlay,
private _elementRef: ElementRef<HTMLInputElement>,
private _elementDivRef: ElementRef<HTMLDivElement>,
@Inject(DOCUMENT) private _document: any
) {}
) {

this.acceptClick = new EventEmitter<NgxTouchKeyboardComponent>();

if (this._elementRef.nativeElement.type != undefined) {
this._elementRef.nativeElement.addEventListener('blur', () => {
this.blurEventHandler();
});
this._elementRef.nativeElement.addEventListener('focus', () => {
if (!this.ngxTouchKeyboardOpenWithButton)
this.openPanel();
});
}
else {

this.ngxTouchKeyboardDiv = true;
this._declareDivEvents();
}

}

// -----------------------------------------------------------------------------------------------------
// @ Lifecycle hooks
Expand Down Expand Up @@ -123,18 +169,40 @@ export class NgxTouchKeyboardDirective implements OnDestroy {
this._panelRef.instance.debug = this.ngxTouchKeyboardDebug;
this._panelRef.instance.setLocale(this._locale);
this._panelRef.instance.setActiveInput(this._elementRef.nativeElement);
//We initialize the text before accept to keep the last change,
//If there is validation process for the text input and the user insert wrong text
//Then We need return to the previous text.
this._panelRef.instance.setTextBeforeAccept();
this.isOpen = true;

// Reference the input element
this._panelRef.instance.closePanel.subscribe(() => this.closePanel());
this._panelRef.instance.acceptClick.subscribe((element) => {
this.acceptClick.emit(element);
});
this._panelRef.instance.validate = this.validate;

}
blurEventHandler() {
this._panelRef.instance.handleButtonPress(fnButton.DONE);
//this.closePanel();
}

/**
* Close keyboard panel
*/
closePanel(): void {
//The problem is that when I want to display the keyboard again
//I have to lose focus from the text input
//(by clicking on the screen outside the text input) and then when
//I click on the text input the keyboard will appear...
//To deal with this problem we makes focus out by calling blur method
this._panelRef.instance.getActiveInputElement()?.blur();
this._overlayRef.detach();
this.isOpen = false;
//We check if We in div mode, then We need to return from input text right to div content
if (this.ngxTouchKeyboardDiv)
this._replaceInputToDivElement();
}

/**
Expand Down Expand Up @@ -253,4 +321,43 @@ export class NgxTouchKeyboardDirective implements OnDestroy {
// Return input
return element;
}
/**
* Create the overlay
*
* @private
*/
private _declareDivEvents(): void {
this._elementDivRef.nativeElement.addEventListener('click', () => {
//When we click on the div element, We need to check if the virtual keyboard is open
//because We wont to prevent from the click listener to action when we press on the virtual keyboard
if (!this.isOpen) {
const element: HTMLInputElement = document.createElement('input');
this._elementRef.nativeElement = element;
this._elementRef.nativeElement.value = this._elementDivRef.nativeElement.innerHTML;
this._elementDivRef.nativeElement.innerHTML = '';
this._elementRef.nativeElement.addEventListener('blur', () => {
this.blurEventHandler();
});
this._elementRef.nativeElement.addEventListener('focus', () => {
if (!this.ngxTouchKeyboardOpenWithButton)
this.openPanel();
});

this._elementDivRef.nativeElement.appendChild(this._elementRef.nativeElement);
// if (this._elementDivRef.nativeElement.removeAllListeners)
// this._elementDivRef.nativeElement.removeAllListeners('click');
this._elementRef.nativeElement.focus();
}
});
}

/**
* Create the overlay
*
* @private
*/
private _replaceInputToDivElement(): void {
this._elementDivRef.nativeElement.innerHTML = this._elementRef.nativeElement.value;
this._declareDivEvents();
}
}
38 changes: 38 additions & 0 deletions src/app/app.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
<input
type="text"
ngxTouchKeyboard
ngxTouchKeyboardOpenWithButton
#basicTouchKeyboard="ngxTouchKeyboard"
/>
<button
Expand All @@ -64,6 +65,35 @@
/>
</div>

<div style="margin-bottom: 2rem"></div>

<span>Open with focus and accept click event</span>
<div class="native-input">
<input
type="text"
ngxTouchKeyboard
ngxTouchKeyboardDebug
#basic2TouchKeyboard1="ngxTouchKeyboard"
(acceptClick)="acceptClick($event)"
[validate]="validateNumber"
/>
</div>
<div style="margin-bottom: 2rem"></div>


<span>text label that replace to text input</span>
<div class="native-input" style="color: rgb(177, 106, 44);">
<div
ngxTouchKeyboard="en-US"
ngxTouchKeyboardDebug
#basic2TouchKeyboard1="ngxTouchKeyboard"
(acceptClick)="acceptClick($event)"
>
when you click on me you can change me
</div>
</div>


<div style="margin-bottom: 2rem"></div>

<span>Open with focus (Fullscreen mode)</span>
Expand Down Expand Up @@ -103,6 +133,7 @@
matInput
type="text"
ngxTouchKeyboard
ngxTouchKeyboardOpenWithButton
#materialTouchKeyboard="ngxTouchKeyboard"
/>
<button
Expand Down Expand Up @@ -187,6 +218,7 @@
matInput
type="text"
[ngxTouchKeyboard]="language"
ngxTouchKeyboardOpenWithButton
#defaultTouchKeyboard="ngxTouchKeyboard"
/>
<button
Expand All @@ -206,6 +238,7 @@
type="text"
inputmode="search"
[ngxTouchKeyboard]="language"
ngxTouchKeyboardOpenWithButton
#searchTouchKeyboard="ngxTouchKeyboard"
/>
<button
Expand All @@ -225,6 +258,7 @@
type="text"
inputmode="email"
[ngxTouchKeyboard]="language"
ngxTouchKeyboardOpenWithButton
#emailTouchKeyboard="ngxTouchKeyboard"
/>
<button
Expand All @@ -244,6 +278,7 @@
type="text"
inputmode="url"
[ngxTouchKeyboard]="language"
ngxTouchKeyboardOpenWithButton
#urlTouchKeyboard="ngxTouchKeyboard"
/>
<button
Expand All @@ -263,6 +298,7 @@
type="text"
inputmode="numeric"
[ngxTouchKeyboard]="language"
ngxTouchKeyboardOpenWithButton
#numericTouchKeyboard="ngxTouchKeyboard"
/>
<button
Expand All @@ -282,6 +318,7 @@
type="text"
inputmode="decimal"
[ngxTouchKeyboard]="language"
ngxTouchKeyboardOpenWithButton
#decimalTouchKeyboard="ngxTouchKeyboard"
/>
<button
Expand All @@ -301,6 +338,7 @@
type="text"
inputmode="tel"
[ngxTouchKeyboard]="language"
ngxTouchKeyboardOpenWithButton
#telTouchKeyboard="ngxTouchKeyboard"
/>
<button
Expand Down
Loading