Initial commit
This commit is contained in:
12
.idea/AngularCounterInput.iml
generated
Normal file
12
.idea/AngularCounterInput.iml
generated
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="WEB_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/temp" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/tmp" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/AngularCounterInput.iml" filepath="$PROJECT_DIR$/.idea/AngularCounterInput.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
7
.idea/typescript-compiler.xml
generated
Normal file
7
.idea/typescript-compiler.xml
generated
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="TypeScriptCompiler">
|
||||
<option name="isCompilerEnabled" value="true" />
|
||||
<option name="useConfig" value="true" />
|
||||
</component>
|
||||
</project>
|
||||
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
8
bs-config.json
Normal file
8
bs-config.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"server": {
|
||||
"baseDir": "src",
|
||||
"routes": {
|
||||
"/node_modules": "node_modules"
|
||||
}
|
||||
}
|
||||
}
|
||||
3
node_modules/.gitignore
generated
vendored
Normal file
3
node_modules/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
node_modules/
|
||||
src/**/*.js
|
||||
src/**/*.js.map
|
||||
57
package.json
Normal file
57
package.json
Normal file
@@ -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"
|
||||
}
|
||||
}
|
||||
16
src/app/app.component.ts
Normal file
16
src/app/app.component.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'my-app',
|
||||
template: `<form #form="ngForm">
|
||||
<json-input [(ngModel)]="result" name="res"></json-input>
|
||||
</form>
|
||||
|
||||
<p>form is valid: {{ form.valid ? 'true' : 'false' }}</p>
|
||||
|
||||
<p>Value:</p>
|
||||
<pre>{{ result | json }}</pre>`,
|
||||
})
|
||||
export class AppComponent {
|
||||
public result = 10;
|
||||
}
|
||||
18
src/app/app.module.ts
Normal file
18
src/app/app.module.ts
Normal file
@@ -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 { }
|
||||
73
src/app/json-input.component.ts
Normal file
73
src/app/json-input.component.ts
Normal file
@@ -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:
|
||||
`
|
||||
<button (click)="onChange($event, -1)">-</button>
|
||||
<div>{{value}}</div>
|
||||
<button (click)="onChange($event, 1)">+</button>
|
||||
`,
|
||||
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 = () => { };
|
||||
}
|
||||
20
src/app/json-input.module.ts
Normal file
20
src/app/json-input.module.ts
Normal file
@@ -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 { }
|
||||
25
src/index.html
Normal file
25
src/index.html
Normal file
@@ -0,0 +1,25 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Angular QuickStart</title>
|
||||
<base href="/">
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="styles.css">
|
||||
|
||||
<!-- Polyfill(s) for older browsers -->
|
||||
<script src="node_modules/core-js/client/shim.min.js"></script>
|
||||
|
||||
<script src="node_modules/zone.js/dist/zone.js"></script>
|
||||
<script src="node_modules/systemjs/dist/system.src.js"></script>
|
||||
|
||||
<script src="systemjs.config.js"></script>
|
||||
<script>
|
||||
System.import('main.js').catch(function(err){ console.error(err); });
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<my-app>Loading AppComponent content here ...</my-app>
|
||||
</body>
|
||||
</html>
|
||||
5
src/main.ts
Normal file
5
src/main.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||
|
||||
import { AppModule } from './app/app.module';
|
||||
|
||||
platformBrowserDynamic().bootstrapModule(AppModule);
|
||||
5
src/styles.css
Normal file
5
src/styles.css
Normal file
@@ -0,0 +1,5 @@
|
||||
h1 {
|
||||
color: #369;
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
font-size: 250%;
|
||||
}
|
||||
49
src/systemjs-angular-loader.js
Normal file
49
src/systemjs-angular-loader.js
Normal file
@@ -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;
|
||||
};
|
||||
11
src/systemjs.config.extras.js
Normal file
11
src/systemjs.config.extras.js
Normal file
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* Add barrels and stuff
|
||||
* Adjust as necessary for your application needs.
|
||||
*/
|
||||
// (function (global) {
|
||||
// System.config({
|
||||
// packages: {
|
||||
// // add packages here
|
||||
// }
|
||||
// });
|
||||
// })(this);
|
||||
45
src/systemjs.config.js
Normal file
45
src/systemjs.config.js
Normal file
@@ -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);
|
||||
13
src/tsconfig.json
Normal file
13
src/tsconfig.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node",
|
||||
"sourceMap": true,
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"lib": [ "es2015", "dom" ],
|
||||
"noImplicitAny": true,
|
||||
"suppressImplicitAnyIndexErrors": true
|
||||
}
|
||||
}
|
||||
93
tslint.json
Normal file
93
tslint.json
Normal file
@@ -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"
|
||||
]
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user