commit 0a36f3830b344d16809b087d91e76a3ee96b96d2 Author: Caesar2011 Date: Wed May 17 00:22:45 2017 +0200 Initial commit diff --git a/.idea/AngularCounterInput.iml b/.idea/AngularCounterInput.iml new file mode 100644 index 0000000..24643cc --- /dev/null +++ b/.idea/AngularCounterInput.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..bc8c5e8 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/typescript-compiler.xml b/.idea/typescript-compiler.xml new file mode 100644 index 0000000..17ff836 --- /dev/null +++ b/.idea/typescript-compiler.xml @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/bs-config.json b/bs-config.json new file mode 100644 index 0000000..4e58595 --- /dev/null +++ b/bs-config.json @@ -0,0 +1,8 @@ +{ + "server": { + "baseDir": "src", + "routes": { + "/node_modules": "node_modules" + } + } +} diff --git a/node_modules/.gitignore b/node_modules/.gitignore new file mode 100644 index 0000000..6b8fdaf --- /dev/null +++ b/node_modules/.gitignore @@ -0,0 +1,3 @@ +node_modules/ +src/**/*.js +src/**/*.js.map \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..dc47cd8 --- /dev/null +++ b/package.json @@ -0,0 +1,57 @@ +{ + "name": "angular-counter-input", + "version": "1.0.0", + "description": "Angular Counter Input Test", + "main": "src/main.js", + "scripts": { + "build": "tsc -p src/", + "build:watch": "tsc -p src/ -w", + "serve": "lite-server -c=bs-config.json", + "prestart": "npm run build", + "start": "concurrently \"npm run build:watch\" \"npm run serve\"", + "lint": "tslint ./src/**/*.ts -t verbose" + }, + "keywords": [ + "angular2", + "counter", + "input" + ], + "author": "Sebastian Seedorf", + "license": "ISC", + "dependencies": { + "@angular/common": "~4.0.0", + "@angular/compiler": "~4.0.0", + "@angular/core": "~4.0.0", + "@angular/forms": "~4.0.0", + "@angular/http": "~4.0.0", + "@angular/platform-browser": "~4.0.0", + "@angular/platform-browser-dynamic": "~4.0.0", + "@angular/router": "~4.0.0", + + "angular-in-memory-web-api": "~0.3.0", + "systemjs": "0.19.40", + "core-js": "^2.4.1", + "rxjs": "5.0.1", + "zone.js": "^0.8.4" + }, + "devDependencies": { + "concurrently": "^3.2.0", + "lite-server": "^2.2.2", + "typescript": "~2.1.0", + + "canonical-path": "0.0.2", + "tslint": "^3.15.1", + "lodash": "^4.16.4", + "jasmine-core": "~2.4.1", + "karma": "^1.3.0", + "karma-chrome-launcher": "^2.0.0", + "karma-cli": "^1.0.1", + "karma-jasmine": "^1.0.2", + "karma-jasmine-html-reporter": "^0.2.2", + "protractor": "~4.0.14", + "rimraf": "^2.5.4", + + "@types/node": "^6.0.46", + "@types/jasmine": "2.5.36" + } +} diff --git a/src/app/app.component.ts b/src/app/app.component.ts new file mode 100644 index 0000000..7b11a65 --- /dev/null +++ b/src/app/app.component.ts @@ -0,0 +1,16 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'my-app', + template: `
+ +
+ +

form is valid: {{ form.valid ? 'true' : 'false' }}

+ +

Value:

+
{{ result | json }}
`, +}) +export class AppComponent { + public result = 10; +} diff --git a/src/app/app.module.ts b/src/app/app.module.ts new file mode 100644 index 0000000..96f0cff --- /dev/null +++ b/src/app/app.module.ts @@ -0,0 +1,18 @@ +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; + +import { AppComponent } from './app.component'; +import {JsonInputModule} from "./json-input.module"; +import {FormsModule, ReactiveFormsModule} from "@angular/forms"; + +@NgModule({ + imports: [ + BrowserModule, + FormsModule, + ReactiveFormsModule, + JsonInputModule, + ], + declarations: [ AppComponent ], + bootstrap: [ AppComponent ] +}) +export class AppModule { } diff --git a/src/app/json-input.component.ts b/src/app/json-input.component.ts new file mode 100644 index 0000000..eadb75d --- /dev/null +++ b/src/app/json-input.component.ts @@ -0,0 +1,73 @@ +import { Component, Input, forwardRef } from '@angular/core'; +import { ControlValueAccessor, NG_VALUE_ACCESSOR, NG_VALIDATORS, FormControl, Validator } from '@angular/forms'; + +@Component({ + selector: 'json-input', + template: + ` + +
{{value}}
+ + `, + providers: [ + { + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => JsonInputComponent), + multi: true, + }, + { + provide: NG_VALIDATORS, + useExisting: forwardRef(() => JsonInputComponent), + multi: true, + }] +}) +export class JsonInputComponent implements ControlValueAccessor, Validator { + private value: number; + private parseError: boolean; + + // this is the initial value set to the component + public writeValue(obj: any) { + if (obj) { + // this will format it with 4 character spacing + this.value = parseInt(obj) || 0; + } + } + + // registers 'fn' that will be fired wheb changes are made + // this is how we emit the changes back to the form + public registerOnChange(fn: any) { + this.propagateChange = fn; + } + + // validates the form, returns null when valid else the validation object + // in this case we're checking if the json parsing has passed or failed from the onChange method + public validate(c: FormControl) { + return (!this.parseError) ? null : { + jsonParseError: { + valid: false, + }, + }; + } + + // not used, used for touch input + public registerOnTouched() { } + + // change events from the textarea + private onChange(event: any, number: number) { + + // get value from text area + this.value = this.value + number; + if (isNaN(this.value)) { + this.parseError = false; + } else { + // set parse error if it fails + this.parseError = true; + } + + // update the form + this.propagateChange(this.value); + } + + // the method set in registerOnChange to emit changes back to the form + private propagateChange: (_: any) => void = () => { }; +} \ No newline at end of file diff --git a/src/app/json-input.module.ts b/src/app/json-input.module.ts new file mode 100644 index 0000000..b0ed74d --- /dev/null +++ b/src/app/json-input.module.ts @@ -0,0 +1,20 @@ +import {FormsModule} from '@angular/forms'; +import { CommonModule } from '@angular/common'; +import { NgModule } from '@angular/core'; +import { JsonInputComponent } from './json-input.component'; + + +@NgModule({ + imports: [ + CommonModule, + FormsModule, + ], + exports: [ + JsonInputComponent, + ], + declarations: [ + JsonInputComponent, + ], + providers: [], +}) +export class JsonInputModule { } diff --git a/src/index.html b/src/index.html new file mode 100644 index 0000000..8327435 --- /dev/null +++ b/src/index.html @@ -0,0 +1,25 @@ + + + + Angular QuickStart + + + + + + + + + + + + + + + + + Loading AppComponent content here ... + + diff --git a/src/main.ts b/src/main.ts new file mode 100644 index 0000000..311c44b --- /dev/null +++ b/src/main.ts @@ -0,0 +1,5 @@ +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; + +import { AppModule } from './app/app.module'; + +platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/src/styles.css b/src/styles.css new file mode 100644 index 0000000..58e1a7d --- /dev/null +++ b/src/styles.css @@ -0,0 +1,5 @@ +h1 { + color: #369; + font-family: Arial, Helvetica, sans-serif; + font-size: 250%; +} diff --git a/src/systemjs-angular-loader.js b/src/systemjs-angular-loader.js new file mode 100644 index 0000000..8b10054 --- /dev/null +++ b/src/systemjs-angular-loader.js @@ -0,0 +1,49 @@ +var templateUrlRegex = /templateUrl\s*:(\s*['"`](.*?)['"`]\s*)/gm; +var stylesRegex = /styleUrls *:(\s*\[[^\]]*?\])/g; +var stringRegex = /(['`"])((?:[^\\]\\\1|.)*?)\1/g; + +module.exports.translate = function(load){ + if (load.source.indexOf('moduleId') != -1) return load; + + var url = document.createElement('a'); + url.href = load.address; + + var basePathParts = url.pathname.split('/'); + + basePathParts.pop(); + var basePath = basePathParts.join('/'); + + var baseHref = document.createElement('a'); + baseHref.href = this.baseURL; + baseHref = baseHref.pathname; + + if (!baseHref.startsWith('/base/')) { // it is not karma + basePath = basePath.replace(baseHref, ''); + } + + load.source = load.source + .replace(templateUrlRegex, function(match, quote, url){ + var resolvedUrl = url; + + if (url.startsWith('.')) { + resolvedUrl = basePath + url.substr(1); + } + + return 'templateUrl: "' + resolvedUrl + '"'; + }) + .replace(stylesRegex, function(match, relativeUrls) { + var urls = []; + + while ((match = stringRegex.exec(relativeUrls)) !== null) { + if (match[2].startsWith('.')) { + urls.push('"' + basePath + match[2].substr(1) + '"'); + } else { + urls.push('"' + match[2] + '"'); + } + } + + return "styleUrls: [" + urls.join(', ') + "]"; + }); + + return load; +}; diff --git a/src/systemjs.config.extras.js b/src/systemjs.config.extras.js new file mode 100644 index 0000000..027dfe5 --- /dev/null +++ b/src/systemjs.config.extras.js @@ -0,0 +1,11 @@ +/** + * Add barrels and stuff + * Adjust as necessary for your application needs. + */ +// (function (global) { +// System.config({ +// packages: { +// // add packages here +// } +// }); +// })(this); diff --git a/src/systemjs.config.js b/src/systemjs.config.js new file mode 100644 index 0000000..129704a --- /dev/null +++ b/src/systemjs.config.js @@ -0,0 +1,45 @@ +/** + * System configuration for Angular samples + * Adjust as necessary for your application needs. + */ +(function (global) { + System.config({ + paths: { + // paths serve as alias + 'npm:': 'node_modules/' + }, + // map tells the System loader where to look for things + map: { + // our app is within the app folder + 'app': 'app', + + // angular bundles + '@angular/core': 'npm:@angular/core/bundles/core.umd.js', + '@angular/common': 'npm:@angular/common/bundles/common.umd.js', + '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js', + '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js', + '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js', + '@angular/http': 'npm:@angular/http/bundles/http.umd.js', + '@angular/router': 'npm:@angular/router/bundles/router.umd.js', + '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js', + + // other libraries + 'rxjs': 'npm:rxjs', + 'angular-in-memory-web-api': 'npm:angular-in-memory-web-api/bundles/in-memory-web-api.umd.js' + }, + // packages tells the System loader how to load when no filename and/or no extension + packages: { + app: { + defaultExtension: 'js', + meta: { + './*.js': { + loader: 'systemjs-angular-loader.js' + } + } + }, + rxjs: { + defaultExtension: 'js' + } + } + }); +})(this); diff --git a/src/tsconfig.json b/src/tsconfig.json new file mode 100644 index 0000000..2c7260d --- /dev/null +++ b/src/tsconfig.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "target": "es5", + "module": "commonjs", + "moduleResolution": "node", + "sourceMap": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "lib": [ "es2015", "dom" ], + "noImplicitAny": true, + "suppressImplicitAnyIndexErrors": true + } +} diff --git a/tslint.json b/tslint.json new file mode 100644 index 0000000..276453f --- /dev/null +++ b/tslint.json @@ -0,0 +1,93 @@ +{ + "rules": { + "class-name": true, + "comment-format": [ + true, + "check-space" + ], + "curly": true, + "eofline": true, + "forin": true, + "indent": [ + true, + "spaces" + ], + "label-position": true, + "label-undefined": true, + "max-line-length": [ + true, + 140 + ], + "member-access": false, + "member-ordering": [ + true, + "static-before-instance", + "variables-before-functions" + ], + "no-arg": true, + "no-bitwise": true, + "no-console": [ + true, + "debug", + "info", + "time", + "timeEnd", + "trace" + ], + "no-construct": true, + "no-debugger": true, + "no-duplicate-key": true, + "no-duplicate-variable": true, + "no-empty": false, + "no-eval": true, + "no-inferrable-types": true, + "no-shadowed-variable": true, + "no-string-literal": false, + "no-switch-case-fall-through": true, + "no-trailing-whitespace": true, + "no-unused-expression": true, + "no-unused-variable": true, + "no-unreachable": true, + "no-use-before-declare": true, + "no-var-keyword": true, + "object-literal-sort-keys": false, + "one-line": [ + true, + "check-open-brace", + "check-catch", + "check-else", + "check-whitespace" + ], + "quotemark": [ + true, + "single" + ], + "radix": true, + "semicolon": [ + "always" + ], + "triple-equals": [ + true, + "allow-null-check" + ], + "typedef-whitespace": [ + true, + { + "call-signature": "nospace", + "index-signature": "nospace", + "parameter": "nospace", + "property-declaration": "nospace", + "variable-declaration": "nospace" + } + ], + "variable-name": false, + "whitespace": [ + true, + "check-branch", + "check-decl", + "check-operator", + "check-separator", + "check-type" + ] + } +}