When we "Tab" into a input field, we want to select all the content, if we start typing, it should remove the existing content and add new content.

We can use HMTL 'select' event.

  @HostListener('select', ['$event'])
onSelect($event: UIEvent) {
this.fullFieldSelected = this.input.selectionStart ===
&& this.input.selectionEnd === this.input.value.length;
}

'fullFieldSelected' variable check whether the field is selected.

If we start typing, it should clean the input value and move the cursor to the first placeholder place.

    // Select the whole field
if (this.fullFieldSelected) {
this.input.value = this.buildPlaceHolder();
const firstPlaceHolderPos = findIndex(this.input.value, (char) => char === '_');
this.input.setSelectionRange(firstPlaceHolderPos, firstPlaceHolderPos);
}

There is one problem, if using trying to do Ctrl + C, it will clean up the field and put 'c' there. So we should prevent this happen.

  @HostListener('keydown', ['$event', '$event.keyCode'])
onKeyDown($event: KeyboardEvent, keyCode) { // if user trying to do copy & paste, then we don't want to
// overwrite the value
if ($event.metaKey || $event.ctrlKey) {
return;
} if(keyCode !== TAB) {
$event.preventDefault();
} // get value for the key
const val = String.fromCharCode(keyCode);
// get position
const cursorPos = this.input.selectionStart; // Select the whole field
if (this.fullFieldSelected) {
this.input.value = this.buildPlaceHolder();
const firstPlaceHolderPos = findIndex(this.input.value, (char) => char === '_');
this.input.setSelectionRange(firstPlaceHolderPos, firstPlaceHolderPos);
} switch(keyCode) {
case LEFT_ARROW:
this.handleLeftArrow(cursorPos);
return;
case RIGHT_ARROW:
this.handleRightArrow(cursorPos);
return;
case BACKSPACE:
this.handleBackSpace(cursorPos);
return;
case DELETE:
this.handleDelete(cursorPos);
return;
} const maskDigit = this.mask.charAt(cursorPos);
const digitValidator = digitValidators[maskDigit] || neverValidator;
if (digitValidator(val)) {
overWriteCharAtPosition(this.input, val, cursorPos);
this.handleRightArrow(cursorPos);
}
}

So, we check whether '$event.metaKey or $event.ctrlKey', if those keys are pressed, then we consider user is trying to copy & paste.

--------

import {Directive, ElementRef, HostListener, Input, OnInit} from '@angular/core';

import * as includes from 'lodash.includes';
import * as findLastIndex from 'lodash.findlastindex';
import * as findIndex from 'lodash.findIndex';
import {SPECIAL_CHARACTERS, TAB, overWriteCharAtPosition, LEFT_ARROW, RIGHT_ARROW, BACKSPACE, DELETE} from './mask.utils';
import {digitValidators, neverValidator} from './digit_validation'; @Directive({
selector: '[au-mask]'
})
export class AuMaskDirective implements OnInit { @Input('au-mask') mask = ''; input: HTMLInputElement;
fullFieldSelected = false; ngOnInit() {
this.input.value = this.buildPlaceHolder();
} constructor(el: ElementRef) {
this.input = el.nativeElement;
} @HostListener('select', ['$event'])
onSelect($event: UIEvent) {
this.fullFieldSelected = this.input.selectionStart ===
&& this.input.selectionEnd === this.input.value.length;
} @HostListener('keydown', ['$event', '$event.keyCode'])
onKeyDown($event: KeyboardEvent, keyCode) { // if user trying to do copy & paste, then we don't want to
// overwrite the value
if ($event.metaKey || $event.ctrlKey) {
return;
} if(keyCode !== TAB) {
$event.preventDefault();
} // get value for the key
const val = String.fromCharCode(keyCode);
// get position
const cursorPos = this.input.selectionStart; // Select the whole field
if (this.fullFieldSelected) {
this.input.value = this.buildPlaceHolder();
const firstPlaceHolderPos = findIndex(this.input.value, (char) => char === '_');
this.input.setSelectionRange(firstPlaceHolderPos, firstPlaceHolderPos);
} switch(keyCode) {
case LEFT_ARROW:
this.handleLeftArrow(cursorPos);
return;
case RIGHT_ARROW:
this.handleRightArrow(cursorPos);
return;
case BACKSPACE:
this.handleBackSpace(cursorPos);
return;
case DELETE:
this.handleDelete(cursorPos);
return;
} const maskDigit = this.mask.charAt(cursorPos);
const digitValidator = digitValidators[maskDigit] || neverValidator;
if (digitValidator(val)) {
overWriteCharAtPosition(this.input, val, cursorPos);
this.handleRightArrow(cursorPos);
}
} handleDelete(cursorPos) {
overWriteCharAtPosition(this.input, '_', cursorPos);
this.input.setSelectionRange(cursorPos, cursorPos);
} handleBackSpace(cursorPos) {
const previousPos = this.calculatePreviousCursorPos(cursorPos);
if (previousPos > -) {
overWriteCharAtPosition(this.input, '_', previousPos);
this.input.setSelectionRange(previousPos, previousPos);
}
} calculateNextCursorPos(cursorPos) {
const valueBeforeCursor = this.input.value.slice(cursorPos + );
const nextPos = findIndex(valueBeforeCursor, (char) => !includes(SPECIAL_CHARACTERS, char));
return nextPos;
} calculatePreviousCursorPos(cursorPos) {
const valueBeforeCursor = this.input.value.slice(, cursorPos);
const previousPos = findLastIndex(valueBeforeCursor, (char) => !includes(SPECIAL_CHARACTERS, char));
return previousPos;
} handleRightArrow(cursorPos) {
const nextPos = this.calculateNextCursorPos(cursorPos);
if(nextPos > -) {
const newNextPos = cursorPos + nextPos + ;
this.input.setSelectionRange(newNextPos, newNextPos);
}
} handleLeftArrow(cursorPos) {
const previousPos = this.calculatePreviousCursorPos(cursorPos);
if(previousPos > -) {
this.input.setSelectionRange(previousPos, previousPos);
}
} buildPlaceHolder(): string {
const chars = this.mask.split(''); const value = chars.reduce((acc, curr) => {
return acc += includes(SPECIAL_CHARACTERS, curr) ?
curr :
'_';
}, ''); return value;
} }

[Angular] The Select DOM Event and Enabling Text Copy的更多相关文章

  1. 节点操作,节点属性的操作及DOM event事件

    ##1. 节点操作 createElement(标签名) 创建一个指定名称的元素 someone.appendChild(new_node) 追加一个子节点(作为最后的子节点) someone.ins ...

  2. [DOM Event Learning] Section 1 DOM Event 处理器绑定的几种方法

    [DOM Event Learning] Section 1 DOM Event处理器绑定的几种方法   网页中经常需要处理各种事件,通常的做法是绑定listener对事件进行监听,当事件发生后进行一 ...

  3. Angular this vs $scope $event事件系统

    this vs $scope ------------------------------------------------------------------------------ 'this' ...

  4. JavaScript 基础(四) - HTML DOM Event

    HTML DOM Event(事件) HTML 4.0 的新特性之一是有能力使 HTML 事件触发浏览器中的动作(action),比如当用户点击某个 HTML 元素时启动一段 JavaScript.下 ...

  5. [DOM Event Learning] Section 4 事件分发和DOM事件流

    [DOM Event Learning] Section 4 事件分发和DOM事件流 事件分发机制: event dispatch mechanism. 事件流(event flow)描述了事件对象在 ...

  6. [DOM Event Learning] Section 3 jQuery事件处理基础 on(), off()和one()方法使用

    [DOM Event Learning] Section 3 jQuery事件处理基础 on(),off()和one()方法使用   jQuery提供了简单的方法来向选择器(对应页面上的元素)绑定事件 ...

  7. [DOM Event Learning] Section 2 概念梳理 什么是事件 DOM Event

    [DOM Event Learning] Section 2 概念梳理 什么是事件 DOM Event   事件 事件(Event)是用来通知代码,一些有趣的事情发生了. 每一个Event都会被一个E ...

  8. HTML DOM Event对象

    我们通常把HTML DOM Event对象叫做Event事件 事件驱动模型 事件源:(触发事件的元素)事件源对象是指event对象 其封装了与事件相关的详细信息. 当事件发生时,只能在事件函数内部访问 ...

  9. [ReactJS] DOM Event Listeners in a React Component

    React doesn't provide the listener to listen the DOM event. But we can do it in React life cycle: So ...

随机推荐

  1. 手动连接数据库(jdbc)

    import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import ...

  2. Icomparer和Icomparable集合排序

    c#中实现对象集合的排序可以使用ArrayList中的Sort()方法,而有比较才能谈排序,因为不是基本类型(如string ,int.double......等)所以.NET Framework不可 ...

  3. Tachyon的配置详解

    Tachyon的配置 Tachyon环境变量 Tachyon通用配置 TachyonMaster配置 TachyonWorker配置 用户配置 1 Tachyon的配置 这里以0.5.0版本为例,介绍 ...

  4. init进程

    2.Linux下的三个特殊进程 Linux下有三个特殊的进程idle进程(PID=0),init进程(PID=1),和kthreadd(PID=2)idle进程由系统自动创建,运行在内核态idle进程 ...

  5. ArcGIS “Error HRESULT E_FAIL has been returned from a call to a COM component.” 异常的解决

    错误提示内容: {System.Runtime.InteropServices.COMException (0x80004005): Error HRESULT E_FAIL has been ret ...

  6. 互联网+时代IT管理者的转型

    最近,大众创业万众创新的热潮真是一浪接着一浪,它实际上是一次政府和企事业的自我改革,利用互联网+的思维与技术对生产模式.流通模式与运营模式进行全新的变革,商业的本质是没有变的,仅仅是穿了个马甲来表演. ...

  7. 【剑指Offer面试题】九度OJ1384:二维数组中的查找

    下决心AC全部剑指offer面试题. 九度OJ面试题地址:http://ac.jobdu.com/hhtproblems.php 书籍:何海涛--<剑指Offer:名企面试官精讲典型编程题> ...

  8. js10---call方法总结

    <html> <body> <script type="text/javascript"> function Obj(x, y){ this.x ...

  9. activity-启动动画的设定(下面弹出出现,弹入下面消失)

    1.今天为了把一个activity以dialog的形式显示,而且实现从开始的时候从底部往上弹出,结束的时候,从上往下消失,做了如下的工作. 1)如果把一个activity以dialog的形式显示? 这 ...

  10. 26.event跨进程通信

    以id创建事件 ] = "myevent"; HANDLE event = CreateEventA(NULL, FALSE, FALSE, name); 设置事件 SetEven ...