├── index.ts ├── src ├── module.ts └── trim-value-accessor.ts ├── .gitignore ├── .npmignore ├── tsconfig.json ├── LICENSE ├── README.MD ├── package.json ├── tslint.json └── CHANGELOG.md /index.ts: -------------------------------------------------------------------------------- 1 | export * from './src/module'; 2 | -------------------------------------------------------------------------------- /src/module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { TrimValueAccessor } from './trim-value-accessor'; 3 | 4 | @NgModule({ 5 | declarations: [ TrimValueAccessor ], 6 | exports: [ TrimValueAccessor ] 7 | }) 8 | export class TrimValueAccessorModule { } 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Node 2 | node_modules/* 3 | npm-debug.log 4 | 5 | # TypeScript 6 | *.js 7 | *.map 8 | *.d.ts 9 | 10 | # ignore dist in git repo 11 | dist/ 12 | 13 | # JetBrains 14 | .idea 15 | .project 16 | .settings 17 | .idea/* 18 | *.iml 19 | 20 | # VS Code 21 | .vscode/* 22 | 23 | # Windows 24 | Thumbs.db 25 | Desktop.ini 26 | 27 | # Mac 28 | .DS_Store 29 | **/.DS_Store 30 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | # Node 2 | node_modules/* 3 | npm-debug.log 4 | 5 | # DO NOT IGNORE TYPESCRIPT FILES FOR NPM 6 | # TypeScript 7 | # *.js 8 | # *.map 9 | # *.d.ts 10 | 11 | # ignore src for npm 12 | src/ 13 | index.ts 14 | 15 | # JetBrains 16 | .idea 17 | .project 18 | .settings 19 | .idea/* 20 | *.iml 21 | 22 | # VS Code 23 | .vscode/* 24 | 25 | # Windows 26 | Thumbs.db 27 | Desktop.ini 28 | 29 | # Mac 30 | .DS_Store 31 | **/.DS_Store 32 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "noImplicitAny": true, 4 | "module": "commonjs", 5 | "target": "ES5", 6 | "emitDecoratorMetadata": true, 7 | "experimentalDecorators": true, 8 | "sourceMap": true, 9 | "declaration": true, 10 | "outDir": "./dist", 11 | "typeRoots": [ 12 | "node_modules/@types" 13 | ] 14 | }, 15 | "files": [ 16 | "index.ts" 17 | ], 18 | "exclude": [ 19 | "node_modules", 20 | "dist", 21 | "**/*.spec.ts" 22 | ], 23 | "angularCompilerOptions": { 24 | "strictMetadataEmit": true, 25 | "skipTemplateCodegen": true 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Khashayar Hajian 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.MD: -------------------------------------------------------------------------------- 1 | # TrimValueAccessor for Angular 2 | 3 | Angular's missing trim input functionality (equivalent of AngularJS `ng-trim`) 4 | 5 | **Caveats:** 6 | 7 | * It's a drop-in solution, meaning it applies to all input fields as soon as this module is used. 8 | * It does not work with inputs that are already using another value accessor, since Angular only allows one value accessor per form control. This means it cannot be used with Angular Material inputs (the `matInput` directive uses a value accessor). 9 | 10 | ## Installation 11 | 12 | To install this library, run: 13 | 14 | ```bash 15 | $ npm install ng-trim-value-accessor --save 16 | ``` 17 | 18 | ## Usage 19 | 20 | In your Angular `AppModule`: 21 | 22 | ```typescript 23 | import { NgModule } from '@angular/core'; 24 | import { TrimValueAccessorModule } from 'ng-trim-value-accessor'; 25 | 26 | @NgModule({ 27 | imports: [ 28 | TrimValueAccessorModule 29 | ] 30 | }) 31 | export class AppModule { } 32 | ``` 33 | 34 | ## Opt-out 35 | 36 | By default, it ignores all `readonly` and `input[type="password]` fields. For example the following field remains untouched: 37 | 38 | ```html 39 | 40 | ``` 41 | 42 | However if you want to *explicitly opt-out*, give a field `ng-trim-ignore` css class: 43 | 44 | ```html 45 | 46 | ``` 47 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ng-trim-value-accessor", 3 | "version": "3.0.2", 4 | "scripts": { 5 | "build": "ng-packagr -p package.json", 6 | "prepublish": "ng-packagr -p package.json", 7 | "lint": "tslint src/**/*.ts" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/khashayar/ng-trim-value-accessor" 12 | }, 13 | "author": { 14 | "name": "Khashayar Hajian", 15 | "email": "me@khashayar.me" 16 | }, 17 | "keywords": [ 18 | "angular", 19 | "value accessor", 20 | "angular custom value accessor", 21 | "angular trim value accessor" 22 | ], 23 | "license": "MIT", 24 | "bugs": { 25 | "url": "https://github.com/khashayar/ng-trim-value-accessor/issues" 26 | }, 27 | "main": "./dist/index.js", 28 | "types": "./dist/index.d.ts", 29 | "dependencies": {}, 30 | "devDependencies": { 31 | "@angular/common": "^8.0.0", 32 | "@angular/compiler": "^8.0.0", 33 | "@angular/compiler-cli": "^8.0.0", 34 | "@angular/core": "^8.0.0", 35 | "@angular/forms": "^8.0.0", 36 | "@angular/platform-browser": "^8.0.0", 37 | "@angular/platform-browser-dynamic": "^8.0.0", 38 | "@angular/platform-server": "^8.0.0", 39 | "@types/es6-shim": "^0.31.35", 40 | "codelyzer": "^5.1.0", 41 | "ng-packagr": "^5.5.0", 42 | "tslint": "^4.4.2", 43 | "typescript": "^3.4.0", 44 | "zone.js": "^0.10.2" 45 | }, 46 | "ngPackage": { 47 | "$schema": "./node_modules/ng-packagr/ng-package.schema.json", 48 | "lib": { 49 | "entryFile": "index.ts" 50 | }, 51 | "dest": "dist" 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/trim-value-accessor.ts: -------------------------------------------------------------------------------- 1 | import { Directive, HostListener, forwardRef } from '@angular/core'; 2 | import { DefaultValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; 3 | 4 | const TRIM_VALUE_ACCESSOR: any = { 5 | provide: NG_VALUE_ACCESSOR, 6 | useExisting: forwardRef(() => TrimValueAccessor), 7 | multi: true 8 | }; 9 | 10 | /** 11 | * The trim accessor for writing trimmed value and listening to changes that is 12 | * used by the {@link NgModel}, {@link FormControlDirective}, and 13 | * {@link FormControlName} directives. 14 | */ 15 | @Directive({ 16 | selector: ` 17 | input:not([type=checkbox]):not([type=radio]):not([type=password]):not([readonly]):not(.ng-trim-ignore)[formControlName], 18 | input:not([type=checkbox]):not([type=radio]):not([type=password]):not([readonly]):not(.ng-trim-ignore)[formControl], 19 | input:not([type=checkbox]):not([type=radio]):not([type=password]):not([readonly]):not(.ng-trim-ignore)[ngModel], 20 | textarea:not([readonly]):not(.ng-trim-ignore)[formControlName], 21 | textarea:not([readonly]):not(.ng-trim-ignore)[formControl], 22 | textarea:not([readonly]):not(.ng-trim-ignore)[ngModel], 23 | :not([readonly]):not(.ng-trim-ignore)[ngDefaultControl] 24 | `, 25 | providers: [ TRIM_VALUE_ACCESSOR ] 26 | }) 27 | export class TrimValueAccessor extends DefaultValueAccessor { 28 | 29 | @HostListener('input', ['$event.target.value']) 30 | ngOnChange = (val: string) => { 31 | this.onChange(val.trim()); 32 | }; 33 | 34 | @HostListener('blur', ['$event.target.value']) 35 | ngOnBlur = (val: string) => { 36 | this.writeValue(val.trim()); 37 | this.onTouched(); 38 | }; 39 | 40 | writeValue(value: any): void { 41 | if (typeof value === 'string') { 42 | value = value.trim(); 43 | } 44 | 45 | super.writeValue(value); 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "rulesDirectory": [ 3 | "node_modules/codelyzer" 4 | ], 5 | "rules": { 6 | "class-name": true, 7 | "comment-format": [ 8 | true, 9 | "check-space" 10 | ], 11 | "curly": true, 12 | "eofline": true, 13 | "forin": true, 14 | "indent": [ 15 | true, 16 | "spaces" 17 | ], 18 | "label-position": true, 19 | "label-undefined": true, 20 | "max-line-length": [ 21 | true, 22 | 140 23 | ], 24 | "member-access": false, 25 | "member-ordering": [ 26 | true, 27 | "static-before-instance", 28 | "variables-before-functions" 29 | ], 30 | "no-arg": true, 31 | "no-bitwise": true, 32 | "no-console": [ 33 | true, 34 | "debug", 35 | "info", 36 | "time", 37 | "timeEnd", 38 | "trace" 39 | ], 40 | "no-construct": true, 41 | "no-debugger": true, 42 | "no-duplicate-key": true, 43 | "no-duplicate-variable": true, 44 | "no-empty": false, 45 | "no-eval": true, 46 | "no-inferrable-types": true, 47 | "no-shadowed-variable": true, 48 | "no-string-literal": false, 49 | "no-switch-case-fall-through": true, 50 | "no-trailing-whitespace": true, 51 | "no-unused-expression": true, 52 | "no-unused-variable": true, 53 | "no-unreachable": true, 54 | "no-use-before-declare": true, 55 | "no-var-keyword": true, 56 | "object-literal-sort-keys": false, 57 | "one-line": [ 58 | true, 59 | "check-open-brace", 60 | "check-catch", 61 | "check-else", 62 | "check-whitespace" 63 | ], 64 | "quotemark": [ 65 | true, 66 | "single" 67 | ], 68 | "radix": true, 69 | "semicolon": [ 70 | "always" 71 | ], 72 | "triple-equals": [ 73 | true, 74 | "allow-null-check" 75 | ], 76 | "typedef-whitespace": [ 77 | true, 78 | { 79 | "call-signature": "nospace", 80 | "index-signature": "nospace", 81 | "parameter": "nospace", 82 | "property-declaration": "nospace", 83 | "variable-declaration": "nospace" 84 | } 85 | ], 86 | "variable-name": false, 87 | "whitespace": [ 88 | true, 89 | "check-branch", 90 | "check-decl", 91 | "check-operator", 92 | "check-separator", 93 | "check-type" 94 | ], 95 | 96 | "directive-selector-name": [true, "camelCase"], 97 | "component-selector-name": [true, "kebab-case"], 98 | "directive-selector-type": [true, "attribute"], 99 | "component-selector-type": [true, "element"], 100 | "use-input-property-decorator": true, 101 | "use-output-property-decorator": true, 102 | "use-host-property-decorator": true, 103 | "no-input-rename": true, 104 | "no-output-rename": true, 105 | "use-life-cycle-interface": true, 106 | "use-pipe-transform-interface": true, 107 | "component-class-suffix": true, 108 | "directive-class-suffix": true 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. 4 | 5 | 6 | ## [3.0.2](https://github.com/khashayar/ng-trim-value-accessor/compare/v3.0.1...v3.0.2) (2019-08-28) 7 | 8 | 9 | ### Reverts 10 | 11 | * adding `dist` folder ([c6c187c](https://github.com/khashayar/ng-trim-value-accessor/commit/c6c187c)) 12 | 13 | 14 | 15 | 16 | ## [3.0.1](https://github.com/khashayar/ng-trim-value-accessor/compare/v3.0.0...v3.0.1) (2019-08-28) 17 | 18 | 19 | 20 | 21 | # [3.0.0](https://github.com/khashayar/ng-trim-value-accessor/compare/v2.0.4...v3.0.0) (2019-08-27) 22 | 23 | 24 | 25 | 26 | ## [2.0.4](https://github.com/khashayar/ng-trim-value-accessor/compare/v2.0.3...v2.0.4) (2018-07-10) 27 | 28 | 29 | ### Bug Fixes 30 | 31 | * must call `onTouched` on blur ([9d91696](https://github.com/khashayar/ng-trim-value-accessor/commit/9d91696)), closes [#13](https://github.com/khashayar/ng-trim-value-accessor/issues/13) 32 | 33 | 34 | 35 | 36 | ## [2.0.3](https://github.com/khashayar/ng-trim-value-accessor/compare/v2.0.2...v2.0.3) (2018-06-05) 37 | 38 | 39 | ### Bug Fixes 40 | 41 | * remove extra quote from selector ([57bfb99](https://github.com/khashayar/ng-trim-value-accessor/commit/57bfb99)), closes [#18](https://github.com/khashayar/ng-trim-value-accessor/issues/18) 42 | 43 | 44 | 45 | 46 | ## [2.0.2](https://github.com/khashayar/ng-trim-value-accessor/compare/v2.0.0...v2.0.2) (2017-11-23) 47 | 48 | 49 | ### Bug Fixes 50 | 51 | * **build:** compile before publish on npm ([3647281](https://github.com/khashayar/ng-trim-value-accessor/commit/3647281)), closes [#9](https://github.com/khashayar/ng-trim-value-accessor/issues/9) 52 | 53 | 54 | 55 | 56 | ## [2.0.1](https://github.com/khashayar/ng-trim-value-accessor/compare/v2.0.0...v2.0.1) (2017-11-23) 57 | 58 | 59 | ### Bug Fixes 60 | 61 | * **build:** compile before publish on npm ([3647281](https://github.com/khashayar/ng-trim-value-accessor/commit/3647281)), closes [#9](https://github.com/khashayar/ng-trim-value-accessor/issues/9) 62 | 63 | 64 | 65 | 66 | # [2.0.0](https://github.com/khashayar/ng-trim-value-accessor/compare/v1.0.1...v2.0.0) (2017-10-30) 67 | 68 | 69 | ### Features 70 | 71 | * opt-out option ([69ff6db](https://github.com/khashayar/ng-trim-value-accessor/commit/69ff6db)), closes [#8](https://github.com/khashayar/ng-trim-value-accessor/issues/8) 72 | 73 | 74 | ### BREAKING CHANGES 75 | 76 | * Ignore all element with `ng-trim-ignore` class. 77 | 78 | It can be used as an opt-out option so the this library ignores 79 | a field and doesn't trim the value of it. 80 | 81 | 82 | 83 | 84 | ## [1.0.1](https://github.com/khashayar/ng-trim-value-accessor/compare/v1.0.0...v1.0.1) (2017-09-25) 85 | 86 | 87 | 88 | 89 | # [1.0.0](https://github.com/khashayar/ng-trim-value-accessor/compare/v0.1.0...v1.0.0) (2017-09-25) 90 | 91 | 92 | ### Features 93 | 94 | * provide an option to bail out of trimming ([6e05184](https://github.com/khashayar/ng-trim-value-accessor/commit/6e05184)), closes [#7](https://github.com/khashayar/ng-trim-value-accessor/issues/7) 95 | 96 | 97 | ### BREAKING CHANGES 98 | 99 | * `readonly` input fields are now ignored. 100 | 101 | This could be used as way to bail out of trimming as well, for 102 | example in cases where another ValueAccessor is applied to a field. 103 | 104 | 105 | 106 | 107 | # [0.1.0](https://github.com/khashayar/ng-trim-value-accessor/compare/v0.0.6...v0.1.0) (2017-07-25) 108 | 109 | 110 | ### Bug Fixes 111 | 112 | * angular doesn't detect the selector ([ebe4312](https://github.com/khashayar/ng-trim-value-accessor/commit/ebe4312)), closes [#6](https://github.com/khashayar/ng-trim-value-accessor/issues/6) 113 | 114 | 115 | ### Features 116 | 117 | * apply trim on input's blur event ([6fe2e67](https://github.com/khashayar/ng-trim-value-accessor/commit/6fe2e67)), closes [#4](https://github.com/khashayar/ng-trim-value-accessor/issues/4) 118 | 119 | 120 | 121 | 122 | ## [0.0.6](https://github.com/khashayar/ng-trim-value-accessor/compare/v0.0.5...v0.0.6) (2017-06-20) 123 | 124 | 125 | ### Bug Fixes 126 | 127 | * ignore radio and password inputs ([7c2787e](https://github.com/khashayar/ng-trim-value-accessor/commit/7c2787e)), closes [#2](https://github.com/khashayar/ng-trim-value-accessor/issues/2) 128 | 129 | 130 | 131 | 132 | ## [0.0.5](https://github.com/khashayar/ng-trim-value-accessor/compare/v0.0.4...v0.0.5) (2017-05-09) 133 | 134 | 135 | ### Bug Fixes 136 | 137 | * unused contructor, which breaks on angular 4.0 is removed ([9efd7fc](https://github.com/khashayar/ng-trim-value-accessor/commit/9efd7fc)) 138 | 139 | 140 | 141 | 142 | ## [0.0.4](https://github.com/khashayar/ng-trim-value-accessor/compare/v0.0.3...v0.0.4) (2017-02-09) 143 | 144 | 145 | ### Bug Fixes 146 | 147 | * **writer:** input view value doesn't get updated ([156f034](https://github.com/khashayar/ng-trim-value-accessor/commit/156f034)), closes [#1](https://github.com/khashayar/ng-trim-value-accessor/issues/1) 148 | 149 | 150 | 151 | 152 | ## 0.0.3 (2017-02-09) 153 | --------------------------------------------------------------------------------