├── examples ├── minimal │ ├── example.css │ ├── .jscsrc │ ├── .coveralls.yml │ ├── .travis.yml │ ├── .gitignore │ ├── .jshintrc │ ├── angular-schema-form-minimal.min.js │ ├── bower.json │ ├── package.json │ ├── LICENSE │ ├── src │ │ ├── angular-schema-form-minimal.html │ │ └── angular-schema-form-minimal.js │ ├── test │ │ └── tests.js │ ├── README.md │ ├── example.html │ ├── gulpfile.js │ ├── example.js │ ├── angular-schema-form-minimal.js │ └── karma.conf.js ├── camelcase │ ├── example.css │ ├── .coveralls.yml │ ├── .jscsrc │ ├── .travis.yml │ ├── .gitignore │ ├── .jshintrc │ ├── bower.json │ ├── package.json │ ├── LICENSE │ ├── test │ │ └── tests.js │ ├── angular-schema-form-camelcase.min.js │ ├── example.html │ ├── README.md │ ├── gulpfile.js │ ├── src │ │ ├── angular-schema-form-camelcase.html │ │ └── angular-schema-form-camelcase.js │ ├── example.js │ ├── karma.conf.js │ └── angular-schema-form-camelcase.js ├── typescript │ ├── example.css │ ├── .coveralls.yml │ ├── .jscsrc │ ├── .travis.yml │ ├── .gitignore │ ├── .jshintrc │ ├── tsd.json │ ├── bower.json │ ├── package.json │ ├── LICENSE │ ├── test │ │ └── tests.js │ ├── gulpfile.js │ ├── angular-schema-form-typescript.min.js │ ├── example.js │ ├── example.html │ ├── README.md │ ├── src │ │ ├── angular-schema-form-typescript.html │ │ └── angular-schema-form-typescript.ts │ ├── karma.conf.js │ └── angular-schema-form-typescript.js └── README.md ├── tools ├── lib │ ├── __init__.py │ └── mass_replace.py ├── README.md ├── README_new_add_on.md └── create_new_add_on.py ├── documentation ├── README.md └── extending.md ├── .gitignore └── README.md /examples/minimal/example.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/camelcase/example.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/typescript/example.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tools/lib/__init__.py: -------------------------------------------------------------------------------- 1 | __author__ = 'nibo' 2 | -------------------------------------------------------------------------------- /examples/minimal/.jscsrc: -------------------------------------------------------------------------------- 1 | { 2 | // "preset": "google" 3 | } 4 | -------------------------------------------------------------------------------- /examples/camelcase/.coveralls.yml: -------------------------------------------------------------------------------- 1 | service_name: travis-ci 2 | 3 | -------------------------------------------------------------------------------- /examples/camelcase/.jscsrc: -------------------------------------------------------------------------------- 1 | { 2 | // "preset": "google" 3 | } 4 | -------------------------------------------------------------------------------- /examples/minimal/.coveralls.yml: -------------------------------------------------------------------------------- 1 | service_name: travis-ci 2 | 3 | -------------------------------------------------------------------------------- /examples/typescript/.coveralls.yml: -------------------------------------------------------------------------------- 1 | service_name: travis-ci 2 | 3 | -------------------------------------------------------------------------------- /examples/typescript/.jscsrc: -------------------------------------------------------------------------------- 1 | { 2 | // "preset": "google" 3 | } 4 | -------------------------------------------------------------------------------- /examples/camelcase/.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - 0.10 4 | 5 | before_script: 6 | - npm install -g bower 7 | - bower install 8 | -------------------------------------------------------------------------------- /examples/minimal/.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - 0.10 4 | 5 | before_script: 6 | - npm install -g bower 7 | - bower install 8 | -------------------------------------------------------------------------------- /examples/typescript/.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - 0.10 4 | 5 | before_script: 6 | - npm install -g bower 7 | - bower install 8 | -------------------------------------------------------------------------------- /examples/minimal/.gitignore: -------------------------------------------------------------------------------- 1 | # Minimal .gitignore, you'd probably want to add project folders and so on. 2 | # Perhaps the common dev-folder should be added. 3 | 4 | bower_components 5 | node_modules -------------------------------------------------------------------------------- /examples/camelcase/.gitignore: -------------------------------------------------------------------------------- 1 | # Minimal .gitignore, you'd probably want to add project folders and so on. 2 | # Perhaps the common dev-folder should be added. 3 | 4 | bower_components 5 | node_modules -------------------------------------------------------------------------------- /examples/typescript/.gitignore: -------------------------------------------------------------------------------- 1 | # Minimal .gitignore, you'd probably want to add project folders and so on. 2 | # Perhaps the common dev-folder should be added. 3 | 4 | bower_components 5 | node_modules -------------------------------------------------------------------------------- /examples/camelcase/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "undef": true, 3 | "unused": true, 4 | "browser": true, 5 | "globals": { 6 | "console":false, 7 | "jQuery": false, 8 | "$":false, 9 | "assertEquals": false, 10 | "jstestdriver": false, 11 | "assertTrue": false, 12 | "assertFalse": false, 13 | "describe": false, 14 | "it":false, 15 | "expect": false, 16 | "sinon":false, 17 | "beforeEach": false, 18 | "afterEach": false, 19 | "angular": false, 20 | "module": false, 21 | "inject": false, 22 | "chai": false, 23 | "should": false, 24 | "Jed": false, 25 | "tws": false 26 | } 27 | } -------------------------------------------------------------------------------- /examples/minimal/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "undef": true, 3 | "unused": true, 4 | "browser": true, 5 | "globals": { 6 | "console":false, 7 | "jQuery": false, 8 | "$":false, 9 | "assertEquals": false, 10 | "jstestdriver": false, 11 | "assertTrue": false, 12 | "assertFalse": false, 13 | "describe": false, 14 | "it":false, 15 | "expect": false, 16 | "sinon":false, 17 | "beforeEach": false, 18 | "afterEach": false, 19 | "angular": false, 20 | "module": false, 21 | "inject": false, 22 | "chai": false, 23 | "should": false, 24 | "Jed": false, 25 | "tws": false 26 | } 27 | } -------------------------------------------------------------------------------- /examples/typescript/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "undef": true, 3 | "unused": true, 4 | "browser": true, 5 | "globals": { 6 | "console":false, 7 | "jQuery": false, 8 | "$":false, 9 | "assertEquals": false, 10 | "jstestdriver": false, 11 | "assertTrue": false, 12 | "assertFalse": false, 13 | "describe": false, 14 | "it":false, 15 | "expect": false, 16 | "sinon":false, 17 | "beforeEach": false, 18 | "afterEach": false, 19 | "angular": false, 20 | "module": false, 21 | "inject": false, 22 | "chai": false, 23 | "should": false, 24 | "Jed": false, 25 | "tws": false 26 | } 27 | } -------------------------------------------------------------------------------- /examples/typescript/tsd.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "v4", 3 | "repo": "borisyankov/DefinitelyTyped", 4 | "ref": "master", 5 | "path": "typings", 6 | "bundle": "typings/tsd.d.ts", 7 | "installed": { 8 | "angularjs/angular.d.ts": { 9 | "commit": "3fc1377ce29dd9670975cb68615edf1b819fc4a5" 10 | }, 11 | "jquery/jquery.d.ts": { 12 | "commit": "3fc1377ce29dd9670975cb68615edf1b819fc4a5" 13 | }, 14 | "angularjs/angular-route.d.ts": { 15 | "commit": "d0adccc436197cc7c3559322721e9df86b892bd6" 16 | }, 17 | "angularjs/angular-cookies.d.ts": { 18 | "commit": "3fc1377ce29dd9670975cb68615edf1b819fc4a5" 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /documentation/README.md: -------------------------------------------------------------------------------- 1 | [![Join the chat at https://gitter.im/OptimalBPM/angular-schema-form-add-ons](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/OptimalBPM/angular-schema-form-add-ons?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) 2 | 3 | ## Angular schema form add-ons - Documentation 4 | 5 | This folder contains documentation of all of the ASF add-on architecture. 6 | 7 | The [extending](https://github.com/OptimalBPM/angular-schema-form-add-ons/blob/master/documentation/extending.md)-document is a guide to extending ASF. 8 | 9 | However, if you are new to creating add-on:s, it is recommended to first read the [creating a new add-on](https://github.com/OptimalBPM/angular-schema-form-add-ons/wiki/Creating-a-new-add-on)-article on the wiki. -------------------------------------------------------------------------------- /examples/minimal/angular-schema-form-minimal.min.js: -------------------------------------------------------------------------------- 1 | angular.module("schemaForm").run(["$templateCache",function(r){r.put("directives/decorators/bootstrap/minimal/angular-schema-form-minimal.html",'
<-- this="" is="" the="" minimal="" editor<="" span="">
{{ (hasError() && errorMessage(schemaError())) || form.description}}
')}]),angular.module("schemaForm").config(["schemaFormProvider","schemaFormDecoratorsProvider","sfPathProvider",function(r,a,i){var o=function(a,o,e){if("string"===o.type&&"minimal"==o.format){var s=r.stdFormObj(a,o,e);return s.key=e.path,s.type="minimal",e.lookup[i.stringify(e.path)]=s,s}};r.defaults.string.unshift(o),a.addMapping("bootstrapDecorator","minimal","directives/decorators/bootstrap/minimal/angular-schema-form-minimal.html")}]); -------------------------------------------------------------------------------- /examples/minimal/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular-schema-form-minimal", 3 | "main": [ 4 | "minimal.min.js" 5 | ], 6 | "version": "0.1.0", 7 | "authors": [ 8 | "Optimal BPM", 9 | "Nicklas Börjesson ", 10 | "Textalk", 11 | "Denis Dervisevic ", 12 | "David Jensen " 13 | ], 14 | "moduleType": [ 15 | "globals" 16 | ], 17 | "keywords": [ 18 | "angular-schema-form", 19 | "schema-form", 20 | "form", 21 | "json", 22 | "json-schema", 23 | "schema", 24 | "add-on", 25 | "example" 26 | ], 27 | "license": "MIT", 28 | "ignore": [ 29 | "**/.*", 30 | "node_modules", 31 | "bower_components", 32 | "test", 33 | "coverage" 34 | ], 35 | "dependencies": { 36 | "angular-schema-form": ">= 0.7" 37 | }, 38 | "devDependencies": { 39 | "angular-schema-form": ">= 0.7", 40 | "angular-mocks": ">= 1.2" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /examples/camelcase/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular-schema-form-camelcase", 3 | "main": [ 4 | "camelcase.min.js" 5 | ], 6 | "version": "0.1.0", 7 | "authors": [ 8 | "Optimal BPM", 9 | "Nicklas Börjesson ", 10 | "Textalk", 11 | "Denis Dervisevic ", 12 | "David Jensen " 13 | ], 14 | "moduleType": [ 15 | "globals" 16 | ], 17 | "keywords": [ 18 | "angular-schema-form", 19 | "schema-form", 20 | "form", 21 | "json", 22 | "json-schema", 23 | "schema", 24 | "add-on", 25 | "example" 26 | ], 27 | "license": "MIT", 28 | "ignore": [ 29 | "**/.*", 30 | "node_modules", 31 | "bower_components", 32 | "test", 33 | "coverage" 34 | ], 35 | "dependencies": { 36 | "angular-schema-form": ">= 0.7" 37 | }, 38 | "devDependencies": { 39 | "angular-schema-form": ">= 0.7", 40 | "angular-mocks": ">= 1.2" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /examples/typescript/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular-schema-form-typescript", 3 | "main": [ 4 | "angular-schema-form-typescript.min.js" 5 | ], 6 | "version": "0.1.0", 7 | "authors": [ 8 | "Optimal BPM", 9 | "Nicklas Börjesson ", 10 | "Textalk", 11 | "Denis Dervisevic ", 12 | "David Jensen " 13 | ], 14 | "moduleType": [ 15 | "globals" 16 | ], 17 | "keywords": [ 18 | "angular-schema-form", 19 | "schema-form", 20 | "form", 21 | "json", 22 | "json-schema", 23 | "schema", 24 | "add-on", 25 | "example" 26 | ], 27 | "license": "MIT", 28 | "ignore": [ 29 | "**/.*", 30 | "node_modules", 31 | "bower_components", 32 | "test", 33 | "coverage" 34 | ], 35 | "dependencies": { 36 | "angular-schema-form": ">= 0.7" 37 | }, 38 | "devDependencies": { 39 | "angular-schema-form": ">= 0.7", 40 | "angular-mocks": ">= 1.2" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /tools/README.md: -------------------------------------------------------------------------------- 1 | [![Join the chat at https://gitter.im/OptimalBPM/angular-schema-form-add-ons](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/OptimalBPM/angular-schema-form-add-ons?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) 2 | 3 | ## Angular schema form add-ons - Tools 4 | 5 | This folder contains tools for add-on development. 6 | 7 | ## create_new_add_on.py 8 | 9 | This is a python script that copies and renames the ["minimal" example add-on](https://github.com/OptimalBPM/angular-schema-form-add-ons/tree/master/examples/minimal) and its references to create a new add-on. 10 | 11 | Arguments: 12 | 13 | --dest - The destination folder where the add-on creates a folder named after the --name
14 | --name - The name of the new add-on
15 | --author - The author of the new add-on
16 | 17 | 18 | Usage: `create_new_add_on.py [-h] [--dest DEST] --name NAME --author AUTHOR` 19 | 20 | Example that creates an add-on at "~/development/test": 21 | 22 | ```bash 23 | python3.4 create_new_add_on.py --dest=~/development --name="test" --author="Author Name" 24 | ``` 25 | -------------------------------------------------------------------------------- /examples/minimal/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular-schema-form-minimal", 3 | "version": "0.1.0", 4 | "description": "Minimal add-on for schema form", 5 | "scripts": { 6 | "test": "rm -fr coverage && ./node_modules/karma/bin/karma start --single-run --browsers PhantomJS karma.conf.js" 7 | }, 8 | "author": "Optimal BPM", 9 | "license": "MIT", 10 | "devDependencies": { 11 | "chai": "^1.9.0", 12 | "coveralls": "^2.11.0", 13 | "gulp": "^3.5.6", 14 | "gulp-angular-templatecache": "^1.2.1", 15 | "gulp-concat": "^2.2.0", 16 | "gulp-jscs": "^1.1.0", 17 | "gulp-minify-html": "^0.1.1", 18 | "gulp-uglify": "^0.2.1", 19 | "gulp-webserver": "^0.9.1", 20 | "karma": "^0.12.0", 21 | "karma-chai-sinon": "^0.1.3", 22 | "karma-coverage": "^0.2.1", 23 | "karma-growler-reporter": "0.0.1", 24 | "karma-mocha": "^0.1.3", 25 | "karma-ng-html2js-preprocessor": "^0.1.0", 26 | "karma-phantomjs-launcher": "^0.1.4", 27 | "mocha": "^1.18.0", 28 | "mocha-lcov-reporter": "0.0.1", 29 | "sinon": "^1.9.0", 30 | "sinon-chai": "^2.5.0", 31 | "streamqueue": "0.0.5" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /examples/camelcase/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular-schema-form-camelcase", 3 | "version": "0.1.0", 4 | "description": "camelCase add-on for schema form", 5 | "scripts": { 6 | "test": "rm -fr coverage && ./node_modules/karma/bin/karma start --single-run --browsers PhantomJS karma.conf.js" 7 | }, 8 | "author": "Optimal BPM", 9 | "license": "MIT", 10 | "devDependencies": { 11 | "chai": "^1.9.0", 12 | "coveralls": "^2.11.0", 13 | "gulp": "^3.5.6", 14 | "gulp-angular-templatecache": "^1.2.1", 15 | "gulp-concat": "^2.2.0", 16 | "gulp-jscs": "^1.1.0", 17 | "gulp-minify-html": "^0.1.1", 18 | "gulp-uglify": "^0.2.1", 19 | "gulp-webserver": "^0.9.1", 20 | "karma": "^0.12.0", 21 | "karma-chai-sinon": "^0.1.3", 22 | "karma-coverage": "^0.2.1", 23 | "karma-growler-reporter": "0.0.1", 24 | "karma-mocha": "^0.1.3", 25 | "karma-ng-html2js-preprocessor": "^0.1.0", 26 | "karma-phantomjs-launcher": "^0.1.4", 27 | "mocha": "^1.18.0", 28 | "mocha-lcov-reporter": "0.0.1", 29 | "sinon": "^1.9.0", 30 | "sinon-chai": "^2.5.0", 31 | "streamqueue": "0.0.5" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /examples/typescript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular-schema-form-camelcase", 3 | "version": "0.1.0", 4 | "description": "camelCase add-on for schema form", 5 | "scripts": { 6 | "test": "rm -fr coverage && ./node_modules/karma/bin/karma start --single-run --browsers PhantomJS karma.conf.js" 7 | }, 8 | "author": "Optimal BPM", 9 | "license": "MIT", 10 | "devDependencies": { 11 | "chai": "^1.9.0", 12 | "coveralls": "^2.11.0", 13 | "gulp": "^3.5.6", 14 | "gulp-angular-templatecache": "^1.2.1", 15 | "gulp-concat": "^2.2.0", 16 | "gulp-tsc": "^1.1.4", 17 | "gulp-minify-html": "^0.1.1", 18 | "gulp-uglify": "^0.2.1", 19 | "gulp-webserver": "^0.9.1", 20 | "karma": "^0.12.0", 21 | "karma-chai-sinon": "^0.1.3", 22 | "karma-coverage": "^0.2.1", 23 | "karma-growler-reporter": "0.0.1", 24 | "karma-mocha": "^0.1.3", 25 | "karma-ng-html2js-preprocessor": "^0.1.0", 26 | "karma-phantomjs-launcher": "^0.1.4", 27 | "mocha": "^1.18.0", 28 | "mocha-lcov-reporter": "0.0.1", 29 | "sinon": "^1.9.0", 30 | "sinon-chai": "^2.5.0", 31 | "streamqueue": "0.0.5" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### JetBrains template 3 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion 4 | 5 | *.iml 6 | 7 | ## Directory-based project format: 8 | .idea/ 9 | # if you remove the above rule, at least ignore the following: 10 | 11 | # User-specific stuff: 12 | # .idea/workspace.xml 13 | # .idea/tasks.xml 14 | # .idea/dictionaries 15 | 16 | # Sensitive or high-churn files: 17 | # .idea/dataSources.ids 18 | # .idea/dataSources.xml 19 | # .idea/sqlDataSources.xml 20 | # .idea/dynamic.xml 21 | # .idea/uiDesigner.xml 22 | 23 | # Gradle: 24 | # .idea/gradle.xml 25 | # .idea/libraries 26 | 27 | # Mongo Explorer plugin: 28 | # .idea/mongoSettings.xml 29 | 30 | ## File-based project format: 31 | *.ipr 32 | *.iws 33 | 34 | ## Plugin-specific files: 35 | 36 | # IntelliJ 37 | /out/ 38 | 39 | # mpeltonen/sbt-idea plugin 40 | .idea_modules/ 41 | 42 | # JIRA plugin 43 | atlassian-ide-plugin.xml 44 | 45 | # Crashlytics plugin (for Android Studio and IntelliJ) 46 | com_crashlytics_export_strings.xml 47 | crashlytics.properties 48 | crashlytics-build.properties 49 | 50 | 51 | 52 | .gitignore -------------------------------------------------------------------------------- /examples/minimal/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Optimal BPM 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 | -------------------------------------------------------------------------------- /examples/camelcase/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Optimal BPM 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 | -------------------------------------------------------------------------------- /examples/typescript/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Optimal BPM 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 | -------------------------------------------------------------------------------- /examples/minimal/src/angular-schema-form-minimal.html: -------------------------------------------------------------------------------- 1 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 |
17 | 18 | <-- This is the minimal editor 19 |
20 | 22 | {{ (hasError() && errorMessage(schemaError())) || form.description}} 23 |
24 | -------------------------------------------------------------------------------- /examples/minimal/test/tests.js: -------------------------------------------------------------------------------- 1 | /* jshint expr: true */ 2 | chai.should(); 3 | 4 | describe('Schema form', function() { 5 | 6 | describe('directive', function() { 7 | beforeEach(module('templates')); 8 | beforeEach(module('schemaForm')); 9 | beforeEach( 10 | //We don't need no sanitation. We don't need no though control. 11 | module(function($sceProvider) { 12 | $sceProvider.enabled(false); 13 | }) 14 | ); 15 | 16 | it('should return correct form type for format "camelcase"',function(){ 17 | inject(function($compile,$rootScope, schemaForm){ 18 | var string_schema = { 19 | type: "object", 20 | properties: { 21 | color: { 22 | type: "string", 23 | } 24 | } 25 | }; 26 | 27 | var color_schema = { 28 | type: "object", 29 | properties: { 30 | color: { 31 | type: "string", 32 | format: "color" 33 | } 34 | } 35 | }; 36 | 37 | schemaForm.defaults(string_schema).form[0].type.should.be.eq("text"); 38 | schemaForm.defaults(color_schema).form[0].type.should.be.eq("basic"); 39 | }); 40 | }); 41 | 42 | }); 43 | }); 44 | -------------------------------------------------------------------------------- /examples/camelcase/test/tests.js: -------------------------------------------------------------------------------- 1 | /* jshint expr: true */ 2 | chai.should(); 3 | 4 | describe('Schema form', function() { 5 | 6 | describe('directive', function() { 7 | beforeEach(module('templates')); 8 | beforeEach(module('schemaForm')); 9 | beforeEach( 10 | //We don't need no sanitation. We don't need no though control. 11 | module(function($sceProvider) { 12 | $sceProvider.enabled(false); 13 | }) 14 | ); 15 | 16 | it('should return correct form type for format "camelcase"',function(){ 17 | inject(function($compile,$rootScope, schemaForm){ 18 | var string_schema = { 19 | type: "object", 20 | properties: { 21 | color: { 22 | type: "string", 23 | } 24 | } 25 | }; 26 | 27 | var color_schema = { 28 | type: "object", 29 | properties: { 30 | color: { 31 | type: "string", 32 | format: "color" 33 | } 34 | } 35 | }; 36 | 37 | schemaForm.defaults(string_schema).form[0].type.should.be.eq("text"); 38 | schemaForm.defaults(color_schema).form[0].type.should.be.eq("basic"); 39 | }); 40 | }); 41 | 42 | }); 43 | }); 44 | -------------------------------------------------------------------------------- /examples/typescript/test/tests.js: -------------------------------------------------------------------------------- 1 | /* jshint expr: true */ 2 | chai.should(); 3 | 4 | describe('Schema form', function() { 5 | 6 | describe('directive', function() { 7 | beforeEach(module('templates')); 8 | beforeEach(module('schemaForm')); 9 | beforeEach( 10 | //We don't need no sanitation. We don't need no though control. 11 | module(function($sceProvider) { 12 | $sceProvider.enabled(false); 13 | }) 14 | ); 15 | 16 | it('should return correct form type for format "camelcase"',function(){ 17 | inject(function($compile,$rootScope, schemaForm){ 18 | var string_schema = { 19 | type: "object", 20 | properties: { 21 | color: { 22 | type: "string", 23 | } 24 | } 25 | }; 26 | 27 | var color_schema = { 28 | type: "object", 29 | properties: { 30 | color: { 31 | type: "string", 32 | format: "color" 33 | } 34 | } 35 | }; 36 | 37 | schemaForm.defaults(string_schema).form[0].type.should.be.eq("text"); 38 | schemaForm.defaults(color_schema).form[0].type.should.be.eq("basic"); 39 | }); 40 | }); 41 | 42 | }); 43 | }); 44 | -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | [![Join the chat at https://gitter.im/OptimalBPM/angular-schema-form-add-ons](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/OptimalBPM/angular-schema-form-add-ons?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) 2 | 3 | ## Angular schema form add-ons - Examples 4 | 5 | This folder contains examples of add-ons showcasing different aspects of the ASF add-on architecture. 6 | 7 | To play around with these, you need to clone this repository: 8 | 9 | git clone https://github.com/OptimalBPM/angular-schema-form-add-ons.git 10 | 11 | This will create a local clone in the angular-schema-form-add-ons subfolder. 12 | 13 | Both examples will look better if you install them with bootstrap(the demos have bootstrap installed). 14 | 15 | ## Minimal 16 | 17 | The [minimal example](https://github.com/OptimalBPM/angular-schema-form-add-ons/tree/master/examples/minimal) simply 18 | uses an input to edit the model. It has a short text proving that it is the actual add-on being displayed. 19 | 20 | ## camelCase 21 | 22 | The [camelCase example](https://github.com/OptimalBPM/angular-schema-form-add-ons/tree/master/examples/camelcase) uses 23 | a normal input, and a button that changes whatever string has been entered into camelCase. 24 | 25 | -------------------------------------------------------------------------------- /examples/minimal/src/angular-schema-form-minimal.js: -------------------------------------------------------------------------------- 1 | angular.module('schemaForm').config(['schemaFormProvider', 2 | 'schemaFormDecoratorsProvider', 'sfPathProvider', 3 | function(schemaFormProvider, schemaFormDecoratorsProvider, sfPathProvider) { 4 | 5 | // First, we want this to be the default for a combination of schema parameters 6 | var minimal = function (name, schema, options) { 7 | if (schema.type === 'string' && schema.format == 'minimal') { 8 | // Initiate a form provider 9 | var f = schemaFormProvider.stdFormObj(name, schema, options); 10 | f.key = options.path; 11 | f.type = 'minimal'; 12 | // Add it to the lookup dict (for internal use) 13 | options.lookup[sfPathProvider.stringify(options.path)] = f; 14 | return f; 15 | } 16 | }; 17 | // Add our default to the defaults array 18 | schemaFormProvider.defaults.string.unshift(minimal); 19 | 20 | // Second, we want it to show if someone have explicitly set the form type 21 | schemaFormDecoratorsProvider.addMapping('bootstrapDecorator', 'minimal', 22 | 'directives/decorators/bootstrap/minimal/angular-schema-form-minimal.html'); 23 | }]); 24 | 25 | 26 | -------------------------------------------------------------------------------- /examples/camelcase/angular-schema-form-camelcase.min.js: -------------------------------------------------------------------------------- 1 | angular.module("schemaForm").run(["$templateCache",function(e){e.put("directives/decorators/bootstrap/camelcase/angular-schema-form-camelcase.html",'
{{ (hasError() && errorMessage(schemaError())) || form.description}}
The some setting-setting is true for the model at $$value$$!
')}]),angular.module("schemaForm").config(["schemaFormProvider","schemaFormDecoratorsProvider","sfPathProvider",function(e,a,r){var o=function(a,o,t){if("string"===o.type&&"camelcase"==o.format){var s=e.stdFormObj(a,o,t);return s.key=t.path,s.type="camelcase",t.lookup[r.stringify(t.path)]=s,s}};e.defaults.string.unshift(o),a.addMapping("bootstrapDecorator","camelcase","directives/decorators/bootstrap/camelcase/angular-schema-form-camelcase.html")}]);var camelCaseControllerFunction=function(e){e.camelCase=function(e){return e.toLowerCase().replace(/[- ](.)/g,function(e,a){return a.toUpperCase()})},e.makeCamelCase=function(){var a=e.ngModel[e.ngModel.length-1];a.$modelValue&&a.$setViewValue(e.camelCase(a.$modelValue))}};angular.module("schemaForm").directive("camelCaseDirective",function(){return{require:["ngModel"],restrict:"A",scope:!1,controller:["$scope",camelCaseControllerFunction],link:function(e,a,r,o){e.ngModel=o}}}); -------------------------------------------------------------------------------- /tools/README_new_add_on.md: -------------------------------------------------------------------------------- 1 | 2 | Minimal add-on 3 | ================= 4 | 5 | ### About 6 | 7 | ***This README has been automatically generated by the [create_new_add_on.py-script](https://github.com/OptimalBPM/angular-schema-form-add-ons/tree/master/tools) 8 | at [angular-schema-form-add-ons](https://github.com/OptimalBPM/angular-schema-form-add-ons), remove this row before publishing.*** 9 | 10 | This add-on presents a normal input field. 11 | 12 | 13 | ### Installation 14 | To use the provided example, make sure npm is installed, enter the destination_folder folder, and run(Linux): 15 | 16 | sudo npm install bower 17 | node_modules/bower/bin/bower install 18 | 19 | This will first locally install bower, and then used that bower to install the project dependencies. 20 | 21 | 22 | ### Running 23 | 24 | You should now be able to open the example.html in the browser. 25 | 26 | 27 | ### Building 28 | 29 | First, install all build tools, in the destination_folder folder, run 30 | 31 | sudo npm install 32 | 33 | 34 | The cycle for development is change and then build. 35 | If you want to make any changes, you should make them in the /src-files and then build, otherwise your changes 36 | will not be included in the example. 37 | 38 | From the installation, gulp should be installed, so therefore, in the destination_folder folder, just run: 39 | 40 | gulp default 41 | 42 | This starts a build and generates destination_folder/angular-schema-form-minimal.js and destination_folder/angular-schema-form-minimal.min.js. 43 | To observe your changes, just refresh the example.html-page. -------------------------------------------------------------------------------- /tools/lib/mass_replace.py: -------------------------------------------------------------------------------- 1 | # Written by Steve R. Hastings, on stack overflow: http://stackoverflow.com/a/1597755/4072379 2 | 3 | import os 4 | import re 5 | import sys 6 | import shutil 7 | 8 | # list of extensions to replace 9 | DEFAULT_REPLACE_EXTENSIONS = None 10 | # example: uncomment next line to only replace *.c, *.h, and/or *.txt 11 | # DEFAULT_REPLACE_EXTENSIONS = (".c", ".h", ".txt") 12 | 13 | def try_to_replace(fname, replace_extensions=DEFAULT_REPLACE_EXTENSIONS): 14 | if replace_extensions: 15 | return fname.lower().endswith(replace_extensions) 16 | return True 17 | 18 | 19 | def file_replace(fname, pat, s_after): 20 | # first, see if the pattern is even in the file. 21 | with open(fname) as f: 22 | if not any(re.search(pat, line) for line in f): 23 | return # pattern does not occur in file so we are done. 24 | 25 | # pattern is in the file, so perform replace operation. 26 | with open(fname) as f: 27 | out_fname = fname + ".tmp" 28 | out = open(out_fname, "w") 29 | for line in f: 30 | out.write(re.sub(pat, s_after, line)) 31 | out.close() 32 | shutil.move(out_fname, fname) 33 | 34 | 35 | def mass_replace(dir_name, s_before, s_after, replace_extensions=DEFAULT_REPLACE_EXTENSIONS): 36 | pat = re.compile(s_before) 37 | for dirpath, dirnames, filenames in os.walk(dir_name): 38 | for fname in filenames: 39 | if try_to_replace(fname, replace_extensions): 40 | fullname = os.path.join(dirpath, fname) 41 | file_replace(fullname, pat, s_after) 42 | -------------------------------------------------------------------------------- /examples/minimal/README.md: -------------------------------------------------------------------------------- 1 | 2 | Minimal add-on 3 | ================= 4 | 5 | ### About 6 | 7 | This example presents a normal input field. 8 | 9 | There is a demo, basically just the published html with bootstrap installed, running at:
10 | http://demo.optimalbpm.se/angular-schema-form-add-ons/examples/minimal/example.html 11 | 12 | These might not be needed if you do not need any local logic, but are here for the example. 13 | 14 | Look at the source for more information on how it works, it is overly documented. 15 | 16 | 17 | ### Installation 18 | To use the example, enter the examples/minimal folder and run 19 | 20 | sudo npm install bower 21 | node_modules/bower/bin/bower install 22 | 23 | This will first locally install bower, and then used that bower to install the project dependencies. 24 | 25 | 26 | ### Running 27 | 28 | You should now be able to open the example.html in the browser. 29 | 30 | 31 | ### Building 32 | 33 | First, install all build tools, in the examples/minimal folder, run 34 | 35 | sudo npm install 36 | 37 | 38 | The cycle for development is change and then build. 39 | If you want to make any changes, you should make them in the /src-files and then build, otherwise your changes 40 | will not be included in the example. 41 | 42 | From the installation, gulp should be installed, so therefore, in the examples/minimal folder, just run: 43 | 44 | gulp default 45 | 46 | This starts a build and generates examples/basic/angular-schema-form-minimal.js and examples/basic/angular-schema-form-minimal.min.js. 47 | To observe your changes, just refresh the example.html-page. -------------------------------------------------------------------------------- /examples/typescript/gulpfile.js: -------------------------------------------------------------------------------- 1 | /* global require */ 2 | 3 | var gulp = require('gulp'); 4 | 5 | var templateCache = require('gulp-angular-templatecache'); 6 | var minifyHtml = require('gulp-minify-html'); 7 | var concat = require('gulp-concat'); 8 | var uglify = require('gulp-uglify'); 9 | var streamqueue = require('streamqueue'); 10 | var jscs = require('gulp-jscs'); 11 | var tsc = require('gulp-tsc'); 12 | 13 | gulp.task('build', function () { 14 | var stream = streamqueue({objectMode: true}); 15 | stream.queue( 16 | gulp.src('./src/*.html') 17 | .pipe(minifyHtml({ 18 | empty: true, 19 | spare: true, 20 | quotes: true 21 | })) 22 | .pipe(templateCache({ 23 | module: 'schemaForm', 24 | root: 'directives/decorators/bootstrap/typescript/' 25 | })) 26 | ); 27 | 28 | stream.queue( 29 | gulp.src(['src/**/*.ts']) 30 | .pipe(tsc()) 31 | ); 32 | 33 | 34 | stream.done() 35 | .pipe(concat('angular-schema-form-typescript.js')) 36 | .pipe(gulp.dest('.')); 37 | }); 38 | 39 | gulp.task('minify', function () { 40 | var stream = streamqueue({objectMode: true}); 41 | stream.queue(gulp.src('angular-schema-form-typescript.js')); 42 | stream.done() 43 | .pipe(uglify()) 44 | .pipe(concat('angular-schema-form-typescript.min.js')) 45 | .pipe(gulp.dest('.')) 46 | }); 47 | 48 | gulp.task('default', [ 49 | 'build', 50 | 'minify' 51 | ]); 52 | 53 | gulp.task('watch', function () { 54 | gulp.watch('./src/**/*', ['default']); 55 | }); 56 | -------------------------------------------------------------------------------- /examples/typescript/angular-schema-form-typescript.min.js: -------------------------------------------------------------------------------- 1 | angular.module("schemaForm").run(["$templateCache",function(e){e.put("directives/decorators/bootstrap/typescript/angular-schema-form-typescript.html",'
{{ (hasError() && errorMessage(schemaError())) || form.description}}
The some setting-setting is true for the model at $$value$$!
')}]),angular.module("schemaForm").config(["schemaFormProvider","schemaFormDecoratorsProvider","sfPathProvider",function(e,t,r){var o=function(t,o,i){if("string"===o.type&&"typescript"==o.format){var s=e.stdFormObj(t,o,i);return s.key=i.path,s.type="typescript",i.lookup[r.stringify(i.path)]=s,s}};e.defaults.string.unshift(o),t.addMapping("bootstrapDecorator","typescript","directives/decorators/bootstrap/typescript/angular-schema-form-typescript.html")}]);var typescriptController=function(){function e(e,t){var r=this;this.$scope=e,this.camelCase=function(e){return e.toLowerCase().replace(/[- ](.)/g,function(e,t){return t.toUpperCase()})},this.makeCamelCase=function(){var e=r.directiveScope.ngModel[r.directiveScope.ngModel.length-1];e.$modelValue&&e.$setViewValue(r.camelCase(e.$modelValue))},console.log("Initiating the process controller"+e.toString()),this.directiveScope=e}return e}();angular.module("schemaForm").directive("typeScriptDirective",function(){return{require:["ngModel"],restrict:"A",scope:!1,controller:["$scope",typescriptController],link:function(e,t,r,o){e.ngModel=o}}}); -------------------------------------------------------------------------------- /examples/typescript/example.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Nicklas B on 2016-01-13. 3 | */ 4 | 5 | /*global angular */ 6 | "use strict"; 7 | 8 | /** 9 | * The main app module 10 | * @name exampleApp 11 | * @type {angular.Module} 12 | */ 13 | 14 | var exampleApp = angular.module("exampleApp", ["schemaForm"]); 15 | 16 | exampleApp.controller("exampleController", ["$scope", function ($scope) { 17 | 18 | 19 | // This is the schema definition, note that the title, even though it is possible to, isn't defined here. 20 | // This to make the schema more portable, schemas are for validation and definition and can be used everywhere. 21 | $scope.schema = { 22 | type: "object", 23 | title: "Typescript camelCase", 24 | properties: { 25 | camelCaseFormat: { 26 | type: "string", 27 | format: "typescript", 28 | description: "When you edit this, the value will become automatically camelCase:d." 29 | } 30 | 31 | }, 32 | required: ["camelCaseFormat"] 33 | }; 34 | 35 | // Define all UI aspects of the form 36 | $scope.form = [ 37 | 38 | { 39 | "key": "camelCaseFormat", 40 | "title": "Example of camelCase editor via format" 41 | }, 42 | { 43 | type: "submit", 44 | style: "btn-info", 45 | title: "OK" 46 | } 47 | ]; 48 | // Initiate the model 49 | $scope.model = {}; 50 | // Initiate one of the inputs 51 | $scope.model.camelCaseFormat = "default value"; 52 | 53 | // This is called by asf on submit, specified in example.html, ng-submit. 54 | $scope.submitted = function (form) { 55 | $scope.$broadcast("schemaFormValidate"); 56 | console.log($scope.model); 57 | }; 58 | }]); 59 | 60 | -------------------------------------------------------------------------------- /examples/minimal/example.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | ASF Add-on example - Minimal 24 | 25 | 26 | 27 |

Minimal

28 | 29 |

This is an example of an angular-schema-form add-on.

30 | 31 |
32 | 33 | 34 | -------------------------------------------------------------------------------- /examples/camelcase/example.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | ASF Add-on example - camelCase 24 | 25 | 26 | 27 |

camelCase

28 | 29 |

This is an example of an angular-schema-form add-on.

30 | 31 |
32 | 33 | 34 | -------------------------------------------------------------------------------- /examples/typescript/example.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | ASF Add-on example - typeScript 24 | 25 | 26 | 27 |

camelCase

28 | 29 |

This is an example of an angular-schema-form add-on.

30 | 31 |
32 | 33 | 34 | -------------------------------------------------------------------------------- /examples/camelcase/README.md: -------------------------------------------------------------------------------- 1 | 2 | camelCase add-on 3 | ================= 4 | ### About 5 | 6 | This example presents a normal input field and a button that changes whatever string has been entered into camelCase. 7 | 8 | There is a demo, basically just the published html with bootstrap installed, running at:
9 | http://demo.optimalbpm.se/angular-schema-form-add-ons/examples/camelcase/example.html 10 | 11 | It uses: 12 | * a directive to access the model and expose the controller to the child elements 13 | * a controller to handle the logic of the camel-casing 14 | 15 | These might not be needed if you do not need any local logic, but are here for the example. 16 | 17 | Look at the source for more information on how it works, it is overly documented. 18 | 19 | 20 | ### Installation 21 | To use the example, enter the examples/camelcase folder and run 22 | 23 | sudo npm install bower 24 | node_modules/bower/bin/bower install 25 | 26 | This will first locally install bower, and then used that bower to install the project dependencies. 27 | 28 | 29 | ### Running 30 | 31 | You should now be able to open the example.html in the browser. 32 | 33 | 34 | ### Building 35 | 36 | First, install all build tools, in the examples/camelcase folder, run 37 | 38 | sudo npm install 39 | 40 | 41 | The cycle for development is change and then build. 42 | If you want to make any changes, you should make them in the /src-files and then build, otherwise your changes 43 | will not be included in the example. 44 | 45 | From the installation, gulp should be installed, so therefore, in the examples/camelcase folder, just run: 46 | 47 | gulp default 48 | 49 | This starts a build and generates examples/basic/angular-schema-form-camelcase.js and examples/basic/angular-schema-form-camelcase.min.js. 50 | To observe your changes, just refresh the example.html-page. -------------------------------------------------------------------------------- /examples/typescript/README.md: -------------------------------------------------------------------------------- 1 | 2 | Typescript (ported camelCase) add-on 3 | ================= 4 | ### About 5 | 6 | This example presents a normal input field and a button that changes whatever string has been entered into camelCase. 7 | 8 | There is a demo, basically just the published html with bootstrap installed, running at:
9 | http://demo.optimalbpm.se/angular-schema-form-add-ons/examples/typescript/example.html 10 | 11 | It uses: 12 | * a directive to access the model and expose the controller to the child elements 13 | * a controller to handle the logic of the camel-casing 14 | 15 | These might not be needed if you do not need any local logic, but are here for the example. 16 | 17 | Look at the source for more information on how it works, it is overly documented. 18 | 19 | 20 | ### Installation 21 | To use the example, enter the examples/camelcase folder and run 22 | 23 | sudo npm install bower 24 | node_modules/bower/bin/bower install 25 | 26 | This will first locally install bower, and then used that bower to install the project dependencies. 27 | 28 | 29 | ### Running 30 | 31 | You should now be able to open the example.html in the browser. 32 | 33 | 34 | ### Building 35 | 36 | First, install all build tools, in the examples/camelcase folder, run 37 | 38 | sudo npm install 39 | 40 | 41 | The cycle for development is change and then build. 42 | If you want to make any changes, you should make them in the /src-files and then build, otherwise your changes 43 | will not be included in the example. 44 | 45 | From the installation, gulp should be installed, so therefore, in the examples/camelcase folder, just run: 46 | 47 | gulp default 48 | 49 | This starts a build and generates examples/basic/angular-schema-form-camelcase.js and examples/basic/angular-schema-form-camelcase.min.js. 50 | To observe your changes, just refresh the example.html-page. -------------------------------------------------------------------------------- /examples/minimal/gulpfile.js: -------------------------------------------------------------------------------- 1 | /* global require */ 2 | 3 | var gulp = require('gulp'); 4 | 5 | var templateCache = require('gulp-angular-templatecache'); 6 | var minifyHtml = require('gulp-minify-html'); 7 | var concat = require('gulp-concat'); 8 | var uglify = require('gulp-uglify'); 9 | var streamqueue = require('streamqueue'); 10 | var jscs = require('gulp-jscs'); 11 | 12 | gulp.task('minify', function() { 13 | var stream = streamqueue({objectMode: true}); 14 | stream.queue( 15 | gulp.src('./src/*.html') 16 | .pipe(minifyHtml({ 17 | empty: true, 18 | spare: true, 19 | quotes: true 20 | })) 21 | .pipe(templateCache({ 22 | module: 'schemaForm', 23 | root: 'directives/decorators/bootstrap/minimal/' 24 | })) 25 | ); 26 | stream.queue(gulp.src('./src/*.js')); 27 | 28 | stream.done() 29 | .pipe(concat('angular-schema-form-minimal.min.js')) 30 | .pipe(uglify()) 31 | .pipe(gulp.dest('.')); 32 | 33 | }); 34 | 35 | gulp.task('non-minified-dist', function() { 36 | var stream = streamqueue({objectMode: true}); 37 | stream.queue( 38 | gulp.src('./src/*.html') 39 | .pipe(templateCache({ 40 | module: 'schemaForm', 41 | root: 'directives/decorators/bootstrap/minimal/' 42 | })) 43 | ); 44 | stream.queue(gulp.src('./src/*.js')); 45 | 46 | stream.done() 47 | .pipe(concat('angular-schema-form-minimal.js')) 48 | .pipe(gulp.dest('.')); 49 | 50 | }); 51 | 52 | gulp.task('jscs', function() { 53 | gulp.src('./src/**/*.js') 54 | .pipe(jscs()); 55 | }); 56 | 57 | gulp.task('default', [ 58 | 'minify', 59 | 'non-minified-dist', 60 | 'jscs' 61 | ]); 62 | 63 | gulp.task('watch', function() { 64 | gulp.watch('./src/**/*', ['default']); 65 | }); 66 | -------------------------------------------------------------------------------- /examples/camelcase/gulpfile.js: -------------------------------------------------------------------------------- 1 | /* global require */ 2 | 3 | var gulp = require('gulp'); 4 | 5 | var templateCache = require('gulp-angular-templatecache'); 6 | var minifyHtml = require('gulp-minify-html'); 7 | var concat = require('gulp-concat'); 8 | var uglify = require('gulp-uglify'); 9 | var streamqueue = require('streamqueue'); 10 | var jscs = require('gulp-jscs'); 11 | 12 | gulp.task('minify', function() { 13 | var stream = streamqueue({objectMode: true}); 14 | stream.queue( 15 | gulp.src('./src/*.html') 16 | .pipe(minifyHtml({ 17 | empty: true, 18 | spare: true, 19 | quotes: true 20 | })) 21 | .pipe(templateCache({ 22 | module: 'schemaForm', 23 | root: 'directives/decorators/bootstrap/camelcase/' 24 | })) 25 | ); 26 | stream.queue(gulp.src('./src/*.js')); 27 | 28 | stream.done() 29 | .pipe(concat('angular-schema-form-camelcase.min.js')) 30 | .pipe(uglify()) 31 | .pipe(gulp.dest('.')); 32 | 33 | }); 34 | 35 | gulp.task('non-minified-dist', function() { 36 | var stream = streamqueue({objectMode: true}); 37 | stream.queue( 38 | gulp.src('./src/*.html') 39 | .pipe(templateCache({ 40 | module: 'schemaForm', 41 | root: 'directives/decorators/bootstrap/camelcase/' 42 | })) 43 | ); 44 | stream.queue(gulp.src('./src/*.js')); 45 | 46 | stream.done() 47 | .pipe(concat('angular-schema-form-camelcase.js')) 48 | .pipe(gulp.dest('.')); 49 | 50 | }); 51 | 52 | gulp.task('jscs', function() { 53 | gulp.src('./src/**/*.js') 54 | .pipe(jscs()); 55 | }); 56 | 57 | gulp.task('default', [ 58 | 'minify', 59 | 'non-minified-dist', 60 | 'jscs' 61 | ]); 62 | 63 | gulp.task('watch', function() { 64 | gulp.watch('./src/**/*', ['default']); 65 | }); 66 | -------------------------------------------------------------------------------- /examples/camelcase/src/angular-schema-form-camelcase.html: -------------------------------------------------------------------------------- 1 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 |
21 | 22 | 23 | 24 | 25 |
26 | 28 | {{ (hasError() && errorMessage(schemaError())) || form.description}} 29 |
30 | 31 | The some setting-setting is true for the model at $$value$$! 32 |
33 | -------------------------------------------------------------------------------- /examples/typescript/src/angular-schema-form-typescript.html: -------------------------------------------------------------------------------- 1 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 |
21 | 22 | 23 | 24 | 25 |
26 | 28 | {{ (hasError() && errorMessage(schemaError())) || form.description}} 29 |
30 | 31 | The some setting-setting is true for the model at $$value$$! 32 |
33 | -------------------------------------------------------------------------------- /examples/minimal/example.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Nicklas B on 2015-06-21. 3 | */ 4 | 5 | /*global angular */ 6 | "use strict"; 7 | 8 | /** 9 | * The main app module 10 | * @name exampleApp 11 | * @type {angular.Module} 12 | */ 13 | 14 | var exampleApp = angular.module("exampleApp", ["schemaForm"]); 15 | 16 | exampleApp.controller("exampleController", ["$scope", function ($scope) { 17 | 18 | 19 | // This is the schema definition, note that the title, even though it is possible to, isn't defined here. 20 | // This to make the schema more portable, schemas are for validation and definition and can be used everywhere. 21 | $scope.schema = { 22 | type: "object", 23 | title: "Minimal", 24 | properties: { 25 | minimalFormat: { 26 | type: "string", 27 | format: "minimal", 28 | description: "When you edit this, it is in the add-ons input box." 29 | }, 30 | minimalFormType: { 31 | type: "string", 32 | description: "When you edit this, which is required, it is equally in the add-ons input box" 33 | } 34 | }, 35 | required: ["minimalFormType"] 36 | }; 37 | 38 | // Define all UI aspects of the form 39 | $scope.form = [ 40 | 41 | { 42 | "key": "minimalFormat", 43 | "title": "Example of minimal editor via format" 44 | }, 45 | { 46 | "key": "minimalFormType", 47 | "title": "Example of minimal editor via form type", 48 | "type": "minimal", 49 | "some_setting": "true" 50 | }, 51 | { 52 | type: "submit", 53 | style: "btn-info", 54 | title: "OK" 55 | } 56 | ]; 57 | // Initiate the model 58 | $scope.model = {}; 59 | // Initiate one of the inputs 60 | $scope.model.minimalFormat = "default value"; 61 | 62 | // This is called by asf on submit, specified in example.html, ng-submit. 63 | $scope.submitted = function (form) { 64 | $scope.$broadcast("schemaFormValidate"); 65 | console.log($scope.model); 66 | }; 67 | }]); 68 | 69 | -------------------------------------------------------------------------------- /examples/camelcase/example.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Nicklas B on 2015-06-21. 3 | */ 4 | 5 | /*global angular */ 6 | "use strict"; 7 | 8 | /** 9 | * The main app module 10 | * @name exampleApp 11 | * @type {angular.Module} 12 | */ 13 | 14 | var exampleApp = angular.module("exampleApp", ["schemaForm"]); 15 | 16 | exampleApp.controller("exampleController", ["$scope", function ($scope) { 17 | 18 | 19 | // This is the schema definition, note that the title, even though it is possible to, isn't defined here. 20 | // This to make the schema more portable, schemas are for validation and definition and can be used everywhere. 21 | $scope.schema = { 22 | type: "object", 23 | title: "camelCase", 24 | properties: { 25 | camelCaseFormat: { 26 | type: "string", 27 | format: "camelcase", 28 | description: "When you edit this, the value will become automatically camelCase:d." 29 | }, 30 | camelCaseFormType: { 31 | type: "string", 32 | description: "When you edit this, which is required, the value will become equally camelCase:d." 33 | } 34 | }, 35 | required: ["camelCaseFormType"] 36 | }; 37 | 38 | // Define all UI aspects of the form 39 | $scope.form = [ 40 | 41 | { 42 | "key": "camelCaseFormat", 43 | "title": "Example of camelCase editor via format" 44 | }, 45 | { 46 | "key": "camelCaseFormType", 47 | "title": "Example of camelCase editor via form type", 48 | "type": "camelcase", 49 | "some_setting": "true" 50 | }, 51 | { 52 | type: "submit", 53 | style: "btn-info", 54 | title: "OK" 55 | } 56 | ]; 57 | // Initiate the model 58 | $scope.model = {}; 59 | // Initiate one of the inputs 60 | $scope.model.camelCaseFormat = "default value"; 61 | 62 | // This is called by asf on submit, specified in example.html, ng-submit. 63 | $scope.submitted = function (form) { 64 | $scope.$broadcast("schemaFormValidate"); 65 | console.log($scope.model); 66 | }; 67 | }]); 68 | 69 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Join the chat at https://gitter.im/OptimalBPM/angular-schema-form-addons](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/OptimalBPM/angular-schema-form-add-ons?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) 2 | 3 | # Angular schema form add-ons 4 | 5 | ***New to creating ASF add-ons? This is where to go: [Creating a new add-on](https://github.com/OptimalBPM/angular-schema-form-add-ons/wiki/Creating-a-new-add-on).*** 6 | 7 | Where is everything? This is how it is organized: 8 | 9 | ### [WIKI](https://github.com/OptimalBPM/angular-schema-form-add-ons/wiki) 10 | **ASF version independent information, recommendations, guidelines, tutorials, tips & tricks** 11 | 12 | For that, please browse the articles at the [wiki](https://github.com/OptimalBPM/angular-schema-form-add-ons/wiki). 13 | 14 | ### [Gitter chat room](https://gitter.im/OptimalBPM/angular-schema-form-add-ons) 15 | **Discussions and questions about ASF plugin development in general** 16 | 17 | These are conducted in the [gitter chat room ](https://gitter.im/OptimalBPM/angular-schema-form-add-ons) [![ASFAO gitter room https://gitter.im/OptimalBPM/angular-schema-form-add-ons](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/OptimalBPM/angular-schema-form-add-ons?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge). 18 | 19 | ### [HERE in the source repository](https://github.com/OptimalBPM/angular-schema-form-add-ons) 20 | **ASF add-on [documentation](https://github.com/OptimalBPM/angular-schema-form-add-ons/tree/master/documentation), [examples](https://github.com/OptimalBPM/angular-schema-form-add-ons/tree/master/examples) and [tools](https://github.com/OptimalBPM/angular-schema-form-add-ons/tree/master/tools)** 21 | 22 | These are stored here, in this documentation and the files of this repository. 23 | For each ASF major version, the previous version gets its own branch. 24 | 25 | The original "Extending Schema Form"-article is located [here](https://github.com/OptimalBPM/angular-schema-form-add-ons/blob/master/documentation/extending.md). 26 | 27 | ### [ISSUES](https://github.com/OptimalBPM/angular-schema-form-add-ons/issues) 28 | **News, information and news relevant for ASF add-on-development** 29 | 30 | These are posted as [issues](https://github.com/OptimalBPM/angular-schema-form-add-ons/issues) for this project. 31 | Follow them to get the neccessary information. 32 | 33 | (not sure if that works well, though, we'll see) 34 | 35 | 36 | -------------------------------------------------------------------------------- /examples/minimal/angular-schema-form-minimal.js: -------------------------------------------------------------------------------- 1 | angular.module("schemaForm").run(["$templateCache", function($templateCache) {$templateCache.put("directives/decorators/bootstrap/minimal/angular-schema-form-minimal.html","\n\n\n
\n \n \n\n \n
\n \n <-- This is the minimal editor\n
\n \n {{ (hasError() && errorMessage(schemaError())) || form.description}}\n
\n");}]); 2 | angular.module('schemaForm').config(['schemaFormProvider', 3 | 'schemaFormDecoratorsProvider', 'sfPathProvider', 4 | function(schemaFormProvider, schemaFormDecoratorsProvider, sfPathProvider) { 5 | 6 | // First, we want this to be the default for a combination of schema parameters 7 | var minimal = function (name, schema, options) { 8 | if (schema.type === 'string' && schema.format == 'minimal') { 9 | // Initiate a form provider 10 | var f = schemaFormProvider.stdFormObj(name, schema, options); 11 | f.key = options.path; 12 | f.type = 'minimal'; 13 | // Add it to the lookup dict (for internal use) 14 | options.lookup[sfPathProvider.stringify(options.path)] = f; 15 | return f; 16 | } 17 | }; 18 | // Add our default to the defaults array 19 | schemaFormProvider.defaults.string.unshift(minimal); 20 | 21 | // Second, we want it to show if someone have explicitly set the form type 22 | schemaFormDecoratorsProvider.addMapping('bootstrapDecorator', 'minimal', 23 | 'directives/decorators/bootstrap/minimal/angular-schema-form-minimal.html'); 24 | }]); 25 | 26 | 27 | -------------------------------------------------------------------------------- /examples/camelcase/karma.conf.js: -------------------------------------------------------------------------------- 1 | 2 | module.exports = function(config) { 3 | config.set({ 4 | 5 | // base path, that will be used to resolve files and exclude 6 | basePath: '.', 7 | 8 | // frameworks to use 9 | frameworks: ['mocha', 'chai-sinon'], 10 | 11 | // list of files / patterns to load in the browser 12 | files: [ 13 | 'bower_components/jquery/dist/jquery.min.js', 14 | 'bower_components/angular/angular.js', 15 | 'bower_components/angular-mocks/angular-mocks.js', 16 | 'bower_components/angular-schema-form/dist/schema-form.js', 17 | 'bower_components/angular-schema-form/dist/bootstrap-decorator.min.js', 18 | 'bower_components/objectpath/lib/ObjectPath.js', 19 | 'src/*.js', 20 | 'src/**/*.html', 21 | 'test/tests.js' 22 | ], 23 | 24 | // list of files to exclude 25 | exclude: [ 26 | 27 | ], 28 | 29 | // test results reporter to use 30 | // possible values: 'dots', 'progress', 'junit', 'growl', 'coverage' 31 | reporters: ['progress', 'coverage', 'growler'], 32 | 33 | preprocessors: { 34 | 'src/**/*.js': ['coverage'], 35 | 'src/**/*.html': ['ng-html2js'] 36 | }, 37 | 38 | // optionally, configure the reporter 39 | coverageReporter: { 40 | type : 'lcov', 41 | dir : 'coverage/' 42 | }, 43 | 44 | ngHtml2JsPreprocessor: { 45 | cacheIdFromPath: function(filepath) { 46 | return 'directives/decorators/bootstrap/camelcase/' + filepath.substr(4); 47 | }, 48 | moduleName: 'templates' 49 | }, 50 | 51 | // web server port 52 | port: 9876, 53 | 54 | // enable / disable colors in the output (reporters and logs) 55 | colors: true, 56 | 57 | // level of logging 58 | // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG 59 | logLevel: config.LOG_INFO, 60 | 61 | 62 | // enable / disable watching file and executing tests whenever any file changes 63 | autoWatch: true, 64 | 65 | 66 | // Start these browsers, currently available: 67 | // - Chrome 68 | // - ChromeCanary 69 | // - Firefox 70 | // - Opera (has to be installed with `npm install karma-opera-launcher`) 71 | // - Safari (only Mac; has to be installed with `npm install karma-safari-launcher`) 72 | // - PhantomJS 73 | // - IE (only Windows; has to be installed with `npm install karma-ie-launcher`) 74 | browsers: ['PhantomJS'], 75 | 76 | 77 | // If browser does not capture in given timeout [ms], kill it 78 | captureTimeout: 60000, 79 | 80 | 81 | // Continuous Integration mode 82 | // if true, it capture browsers, run tests and exit 83 | singleRun: false 84 | }); 85 | }; 86 | -------------------------------------------------------------------------------- /examples/minimal/karma.conf.js: -------------------------------------------------------------------------------- 1 | 2 | module.exports = function(config) { 3 | config.set({ 4 | 5 | // base path, that will be used to resolve files and exclude 6 | basePath: '.', 7 | 8 | // frameworks to use 9 | frameworks: ['mocha', 'chai-sinon'], 10 | 11 | // list of files / patterns to load in the browser 12 | files: [ 13 | 'bower_components/jquery/dist/jquery.min.js', 14 | 'bower_components/angular/angular.js', 15 | 'bower_components/angular-mocks/angular-mocks.js', 16 | 'bower_components/angular-schema-form/dist/schema-form.js', 17 | 'bower_components/angular-schema-form/dist/bootstrap-decorator.min.js', 18 | 'bower_components/objectpath/lib/ObjectPath.js', 19 | 'src/*.js', 20 | 'src/**/*.html', 21 | 'test/tests.js' 22 | ], 23 | 24 | // list of files to exclude 25 | exclude: [ 26 | 27 | ], 28 | 29 | // test results reporter to use 30 | // possible values: 'dots', 'progress', 'junit', 'growl', 'coverage' 31 | reporters: ['progress', 'coverage', 'growler'], 32 | 33 | preprocessors: { 34 | 'src/**/*.js': ['coverage'], 35 | 'src/**/*.html': ['ng-html2js'] 36 | }, 37 | 38 | // optionally, configure the reporter 39 | coverageReporter: { 40 | type : 'lcov', 41 | dir : 'coverage/' 42 | }, 43 | 44 | ngHtml2JsPreprocessor: { 45 | cacheIdFromPath: function(filepath) { 46 | return 'directives/decorators/bootstrap/minimal/' + filepath.substr(4); 47 | }, 48 | moduleName: 'templates' 49 | }, 50 | 51 | // web server port 52 | port: 9876, 53 | 54 | // enable / disable colors in the output (reporters and logs) 55 | colors: true, 56 | 57 | // level of logging 58 | // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG 59 | logLevel: config.LOG_INFO, 60 | 61 | 62 | // enable / disable watching file and executing tests whenever any file changes 63 | autoWatch: true, 64 | 65 | 66 | // Start these browsers, currently available: 67 | // - Chrome 68 | // - ChromeCanary 69 | // - Firefox 70 | // - Opera (has to be installed with `npm install karma-opera-launcher`) 71 | // - Safari (only Mac; has to be installed with `npm install karma-safari-launcher`) 72 | // - PhantomJS 73 | // - IE (only Windows; has to be installed with `npm install karma-ie-launcher`) 74 | browsers: ['PhantomJS'], 75 | 76 | 77 | // If browser does not capture in given timeout [ms], kill it 78 | captureTimeout: 60000, 79 | 80 | 81 | // Continuous Integration mode 82 | // if true, it capture browsers, run tests and exit 83 | singleRun: false 84 | }); 85 | }; 86 | -------------------------------------------------------------------------------- /examples/typescript/karma.conf.js: -------------------------------------------------------------------------------- 1 | 2 | module.exports = function(config) { 3 | config.set({ 4 | 5 | // base path, that will be used to resolve files and exclude 6 | basePath: '.', 7 | 8 | // frameworks to use 9 | frameworks: ['mocha', 'chai-sinon'], 10 | 11 | // list of files / patterns to load in the browser 12 | files: [ 13 | 'bower_components/jquery/dist/jquery.min.js', 14 | 'bower_components/angular/angular.js', 15 | 'bower_components/angular-mocks/angular-mocks.js', 16 | 'bower_components/angular-schema-form/dist/schema-form.js', 17 | 'bower_components/angular-schema-form/dist/bootstrap-decorator.min.js', 18 | 'bower_components/objectpath/lib/ObjectPath.js', 19 | 'src/*.js', 20 | 'src/**/*.html', 21 | 'test/tests.js' 22 | ], 23 | 24 | // list of files to exclude 25 | exclude: [ 26 | 27 | ], 28 | 29 | // test results reporter to use 30 | // possible values: 'dots', 'progress', 'junit', 'growl', 'coverage' 31 | reporters: ['progress', 'coverage', 'growler'], 32 | 33 | preprocessors: { 34 | 'src/**/*.js': ['coverage'], 35 | 'src/**/*.html': ['ng-html2js'] 36 | }, 37 | 38 | // optionally, configure the reporter 39 | coverageReporter: { 40 | type : 'lcov', 41 | dir : 'coverage/' 42 | }, 43 | 44 | ngHtml2JsPreprocessor: { 45 | cacheIdFromPath: function(filepath) { 46 | return 'directives/decorators/bootstrap/camelcase/' + filepath.substr(4); 47 | }, 48 | moduleName: 'templates' 49 | }, 50 | 51 | // web server port 52 | port: 9876, 53 | 54 | // enable / disable colors in the output (reporters and logs) 55 | colors: true, 56 | 57 | // level of logging 58 | // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG 59 | logLevel: config.LOG_INFO, 60 | 61 | 62 | // enable / disable watching file and executing tests whenever any file changes 63 | autoWatch: true, 64 | 65 | 66 | // Start these browsers, currently available: 67 | // - Chrome 68 | // - ChromeCanary 69 | // - Firefox 70 | // - Opera (has to be installed with `npm install karma-opera-launcher`) 71 | // - Safari (only Mac; has to be installed with `npm install karma-safari-launcher`) 72 | // - PhantomJS 73 | // - IE (only Windows; has to be installed with `npm install karma-ie-launcher`) 74 | browsers: ['PhantomJS'], 75 | 76 | 77 | // If browser does not capture in given timeout [ms], kill it 78 | captureTimeout: 60000, 79 | 80 | 81 | // Continuous Integration mode 82 | // if true, it capture browsers, run tests and exit 83 | singleRun: false 84 | }); 85 | }; 86 | -------------------------------------------------------------------------------- /examples/camelcase/src/angular-schema-form-camelcase.js: -------------------------------------------------------------------------------- 1 | angular.module('schemaForm').config(['schemaFormProvider', 2 | 'schemaFormDecoratorsProvider', 'sfPathProvider', 3 | function(schemaFormProvider, schemaFormDecoratorsProvider, sfPathProvider) { 4 | 5 | // First, we want this to be the default for a combination of schema parameters 6 | var camelcase = function (name, schema, options) { 7 | if (schema.type === 'string' && schema.format == 'camelcase') { 8 | // Initiate a form provider 9 | var f = schemaFormProvider.stdFormObj(name, schema, options); 10 | f.key = options.path; 11 | f.type = 'camelcase'; 12 | // Add it to the lookup dict (for internal use) 13 | options.lookup[sfPathProvider.stringify(options.path)] = f; 14 | return f; 15 | } 16 | }; 17 | // Add our default to the defaults array 18 | schemaFormProvider.defaults.string.unshift(camelcase); 19 | 20 | // Second, we want it to show if someone have explicitly set the form type 21 | schemaFormDecoratorsProvider.addMapping('bootstrapDecorator', 'camelcase', 22 | 'directives/decorators/bootstrap/camelcase/angular-schema-form-camelcase.html'); 23 | }]); 24 | 25 | 26 | // Declare a controller, this is used in the camelcaseDirective below 27 | var camelCaseControllerFunction = function($scope) { 28 | 29 | $scope.camelCase = function (input) { 30 | // Turn the input value into camelCase and return it. 31 | return input.toLowerCase().replace(/[- ](.)/g, function(match, group1) { 32 | return group1.toUpperCase(); 33 | }); 34 | }; 35 | 36 | $scope.makeCamelCase = function () { 37 | // This is invoked by the ng-click 38 | // The ngModel in ASF is an array, we want to access the actual value 39 | var leaf_model = $scope.ngModel[$scope.ngModel.length - 1]; 40 | if (leaf_model.$modelValue) { 41 | // If there is something to camelCase, do it! 42 | leaf_model.$setViewValue($scope.camelCase(leaf_model.$modelValue)); 43 | }; 44 | }; 45 | }; 46 | 47 | // Create a directive to properly access the ngModel set in the view (src/angular-schema-form-camelcase.html) 48 | angular.module('schemaForm').directive('camelCaseDirective', function() { 49 | return { 50 | // The directive needs the ng-model to be set, look at the
51 | require: ['ngModel'], 52 | restrict: 'A', 53 | // Do not create a isolate scope, makeCamelCase should be available to the button element 54 | scope: false, 55 | // Define a controller, use the function from above, inject the scope 56 | controller : ['$scope', camelCaseControllerFunction], 57 | // Use the link function to initiate the ngModel in the controller scope 58 | link: function(scope, iElement, iAttrs, ngModelCtrl) { 59 | scope.ngModel = ngModelCtrl; 60 | } 61 | }; 62 | }); 63 | -------------------------------------------------------------------------------- /examples/typescript/src/angular-schema-form-typescript.ts: -------------------------------------------------------------------------------- 1 | 2 | /// 3 | /// 4 | 5 | angular.module('schemaForm').config(['schemaFormProvider', 6 | 'schemaFormDecoratorsProvider', 'sfPathProvider', 7 | function (schemaFormProvider, schemaFormDecoratorsProvider, sfPathProvider) { 8 | 9 | // First, we want this to be the default for a combination of schema parameters 10 | var typescript = function (name, schema, options) { 11 | if (schema.type === 'string' && schema.format == 'typescript') { 12 | // Initiate a form provider 13 | var f = schemaFormProvider.stdFormObj(name, schema, options); 14 | f.key = options.path; 15 | f.type = 'typescript'; 16 | // Add it to the lookup dict (for internal use) 17 | options.lookup[sfPathProvider.stringify(options.path)] = f; 18 | return f; 19 | } 20 | }; 21 | // Add our default to the defaults array 22 | schemaFormProvider.defaults.string.unshift(typescript); 23 | 24 | // Second, we want it to show if someone have explicitly set the form type 25 | schemaFormDecoratorsProvider.addMapping('bootstrapDecorator', 'typescript', 26 | 'directives/decorators/bootstrap/typescript/angular-schema-form-typescript.html'); 27 | }]); 28 | 29 | 30 | interface DirectiveScope extends ng.IScope { 31 | ngModel : any[]; 32 | controller : typescriptController; 33 | } 34 | 35 | // Declare a controller, this is used in the typescriptDirective below 36 | class typescriptController { 37 | 38 | directiveScope : DirectiveScope; 39 | 40 | camelCase = (input:string):string => { 41 | // Turn the input value into typescript and return it. 42 | return input.toLowerCase().replace(/[- ](.)/g, function(match, group1) { 43 | return group1.toUpperCase(); 44 | }); 45 | }; 46 | 47 | makeCamelCase = () => { 48 | // This is invoked by the ng-click 49 | // The ngModel in ASF is an array, we want to access the actual value 50 | var leaf_model = this.directiveScope.ngModel[this.directiveScope.ngModel.length - 1]; 51 | if (leaf_model.$modelValue) { 52 | // If there is something to camel case, do it! 53 | leaf_model.$setViewValue(this.camelCase(leaf_model.$modelValue)); 54 | }; 55 | }; 56 | 57 | constructor(private $scope:DirectiveScope, element:JQuery) { 58 | console.log("Initiating the process controller" + $scope.toString()); 59 | $scope.controller = this 60 | this.directiveScope = $scope; 61 | } 62 | }; 63 | 64 | // Create a directive to properly access the ngModel set in the view (src/angular-schema-form-typescript.html) 65 | angular.module('schemaForm').directive('typeScriptDirective', ():ng.IDirective => { 66 | return { 67 | // The directive needs the ng-model to be set, look at the
68 | require: ['ngModel'], 69 | restrict: 'A', 70 | // Do not create a isolate scope, makeCamelCase should be available to the button element 71 | scope: false, 72 | // Define a controller, use the function from above, inject the scope 73 | controller : ['$scope', typescriptController], 74 | link: function(scope: DirectiveScope, iElement, iAttrs, ngModelCtrl) { 75 | scope.ngModel = ngModelCtrl; 76 | } 77 | } 78 | 79 | }); 80 | 81 | 82 | -------------------------------------------------------------------------------- /tools/create_new_add_on.py: -------------------------------------------------------------------------------- 1 | import os 2 | import shutil 3 | import argparse 4 | from shutil import ignore_patterns 5 | from lib.mass_replace import mass_replace 6 | 7 | __author__ = 'Nicklas Boerjesson' 8 | 9 | script_dir = os.path.dirname(__file__) 10 | 11 | parser = argparse.ArgumentParser(description='Creates a new add-on with the supplied name and author', 12 | epilog="") 13 | parser.add_argument('--dest', required=False, help='Destination folder') 14 | parser.add_argument('--name', required=True, help='Project name') 15 | parser.add_argument('--author', required=True, help='The name of the author') 16 | 17 | _arguments = vars(parser.parse_args()) 18 | 19 | _destination = _arguments["dest"] 20 | _add_on_name = _arguments["name"] 21 | _add_on_author = _arguments["author"] 22 | 23 | if _destination is None: 24 | _destination = os.getcwd() 25 | else: 26 | _destination = os.path.expanduser(_destination) 27 | 28 | _destination = os.path.join(_destination, _add_on_name) 29 | 30 | if os.path.exists(_destination): 31 | raise Exception("The destination already exists.") 32 | 33 | _source_folder = os.path.join(script_dir, "..", "examples", "minimal") 34 | 35 | 36 | 37 | # Copy to destination 38 | shutil.copytree(src=_source_folder, dst=_destination, 39 | ignore=ignore_patterns('bower_components', 'node_modules', "README.md")) 40 | 41 | # Add README 42 | shutil.copy(src=os.path.join(script_dir, "README_new_add_on.md"), dst=os.path.join(_destination,"README.md")) 43 | 44 | # Create needed variations of the add-on name: 45 | 46 | # First, the add-on name should only be word-separated by "-". 47 | _add_on_name = _add_on_name.replace(" ", "-").replace("_", "-") 48 | 49 | # JS names should be camelCase:d and contain no "-" 50 | _cc_tmp = ''.join(x for x in _add_on_name.title() if x.isalpha()) 51 | _camelCased_add_on_name = (_cc_tmp[0].lower() + _cc_tmp[1:]).replace("-", "") 52 | 53 | # References cannot contain any "-" 54 | _references_add_on_name = _add_on_name.replace("_", "").replace("-", "") 55 | 56 | # Actually replace the strings in all the files 57 | 58 | # Replace all the capitalized Minimal mentions 59 | mass_replace(_destination, "Minimal", _add_on_name.capitalize()) 60 | 61 | # Replace all the minimalForm type references minimal mentions with camelCase:d _add_on_name 62 | mass_replace(_destination, "minimalForm", _camelCased_add_on_name + "Form") 63 | 64 | # Replace all the html file references with lowercase _add_on_name 65 | mass_replace(_destination, "angular-schema-form-minimal", "angular-schema-form-" + _add_on_name.lower()) 66 | 67 | # Replace all the destination_folders references with lowercase _add_on_name 68 | mass_replace(_destination, "destination_folder", _add_on_name.lower()) 69 | 70 | 71 | # Replace all the remaining lowercase(references) minimal mentions 72 | mass_replace(_destination, "minimal", _references_add_on_name.lower()) 73 | 74 | # Replace all the Optimal BPM mentions 75 | mass_replace(_destination, "Optimal BPM", _add_on_author) 76 | 77 | # Rename all the files 78 | shutil.move(src=os.path.join(_destination, "src", "angular-schema-form-minimal.html"), 79 | dst=os.path.join(_destination, "src", "angular-schema-form-" + _add_on_name.lower() + ".html")) 80 | shutil.move(src=os.path.join(_destination, "src", "angular-schema-form-minimal.js"), 81 | dst=os.path.join(_destination, "src", "angular-schema-form-" + _add_on_name.lower() + ".js")) 82 | shutil.move(src=os.path.join(_destination, "angular-schema-form-minimal.js"), 83 | dst=os.path.join(_destination, "angular-schema-form-" + _add_on_name.lower() + ".js")) 84 | shutil.move(src=os.path.join(_destination, "angular-schema-form-minimal.min.js"), 85 | dst=os.path.join(_destination, "angular-schema-form-" + _add_on_name.lower() + ".min.js")) 86 | 87 | 88 | print("If you want to, you can initialize the add on using these commands:") 89 | print("cd " + _destination) 90 | print("sudo npm install bower") 91 | print("node_modules/bower/bin/bower install") 92 | print("\nTo install the build tools like this:") 93 | print("sudo npm install") 94 | -------------------------------------------------------------------------------- /examples/typescript/angular-schema-form-typescript.js: -------------------------------------------------------------------------------- 1 | angular.module("schemaForm").run(["$templateCache", function($templateCache) {$templateCache.put("directives/decorators/bootstrap/typescript/angular-schema-form-typescript.html","
{{ (hasError() && errorMessage(schemaError())) || form.description}}
The some setting-setting is true for the model at $$value$$!
");}]); 2 | /// 3 | /// 4 | angular.module('schemaForm').config(['schemaFormProvider', 5 | 'schemaFormDecoratorsProvider', 'sfPathProvider', 6 | function (schemaFormProvider, schemaFormDecoratorsProvider, sfPathProvider) { 7 | // First, we want this to be the default for a combination of schema parameters 8 | var typescript = function (name, schema, options) { 9 | if (schema.type === 'string' && schema.format == 'typescript') { 10 | // Initiate a form provider 11 | var f = schemaFormProvider.stdFormObj(name, schema, options); 12 | f.key = options.path; 13 | f.type = 'typescript'; 14 | // Add it to the lookup dict (for internal use) 15 | options.lookup[sfPathProvider.stringify(options.path)] = f; 16 | return f; 17 | } 18 | }; 19 | // Add our default to the defaults array 20 | schemaFormProvider.defaults.string.unshift(typescript); 21 | // Second, we want it to show if someone have explicitly set the form type 22 | schemaFormDecoratorsProvider.addMapping('bootstrapDecorator', 'typescript', 'directives/decorators/bootstrap/typescript/angular-schema-form-typescript.html'); 23 | }]); 24 | // Declare a controller, this is used in the typescriptDirective below 25 | var typescriptController = (function () { 26 | function typescriptController($scope, element) { 27 | var _this = this; 28 | this.$scope = $scope; 29 | this.camelCase = function (input) { 30 | // Turn the input value into typescript and return it. 31 | return input.toLowerCase().replace(/[- ](.)/g, function (match, group1) { 32 | return group1.toUpperCase(); 33 | }); 34 | }; 35 | this.makeCamelCase = function () { 36 | // This is invoked by the ng-click 37 | // The ngModel in ASF is an array, we want to access the actual value 38 | var leaf_model = _this.directiveScope.ngModel[_this.directiveScope.ngModel.length - 1]; 39 | if (leaf_model.$modelValue) { 40 | // If there is something to camel case, do it! 41 | leaf_model.$setViewValue(_this.camelCase(leaf_model.$modelValue)); 42 | } 43 | ; 44 | }; 45 | console.log("Initiating the process controller" + $scope.toString()); 46 | $scope.controller = this; 47 | this.directiveScope = $scope; 48 | } 49 | return typescriptController; 50 | })(); 51 | ; 52 | // Create a directive to properly access the ngModel set in the view (src/angular-schema-form-typescript.html) 53 | angular.module('schemaForm').directive('typeScriptDirective', function () { 54 | return { 55 | // The directive needs the ng-model to be set, look at the
56 | require: ['ngModel'], 57 | restrict: 'A', 58 | // Do not create a isolate scope, makeCamelCase should be available to the button element 59 | scope: false, 60 | // Define a controller, use the function from above, inject the scope 61 | controller: ['$scope', typescriptController], 62 | link: function (scope, iElement, iAttrs, ngModelCtrl) { 63 | scope.ngModel = ngModelCtrl; 64 | } 65 | }; 66 | }); 67 | -------------------------------------------------------------------------------- /examples/camelcase/angular-schema-form-camelcase.js: -------------------------------------------------------------------------------- 1 | angular.module("schemaForm").run(["$templateCache", function($templateCache) {$templateCache.put("directives/decorators/bootstrap/camelcase/angular-schema-form-camelcase.html","\n\n\n
\n \n \n\n \n
\n \n \n \n \n
\n \n {{ (hasError() && errorMessage(schemaError())) || form.description}}\n
\n \n The some setting-setting is true for the model at $$value$$!\n
\n");}]); 2 | angular.module('schemaForm').config(['schemaFormProvider', 3 | 'schemaFormDecoratorsProvider', 'sfPathProvider', 4 | function(schemaFormProvider, schemaFormDecoratorsProvider, sfPathProvider) { 5 | 6 | // First, we want this to be the default for a combination of schema parameters 7 | var camelcase = function (name, schema, options) { 8 | if (schema.type === 'string' && schema.format == 'camelcase') { 9 | // Initiate a form provider 10 | var f = schemaFormProvider.stdFormObj(name, schema, options); 11 | f.key = options.path; 12 | f.type = 'camelcase'; 13 | // Add it to the lookup dict (for internal use) 14 | options.lookup[sfPathProvider.stringify(options.path)] = f; 15 | return f; 16 | } 17 | }; 18 | // Add our default to the defaults array 19 | schemaFormProvider.defaults.string.unshift(camelcase); 20 | 21 | // Second, we want it to show if someone have explicitly set the form type 22 | schemaFormDecoratorsProvider.addMapping('bootstrapDecorator', 'camelcase', 23 | 'directives/decorators/bootstrap/camelcase/angular-schema-form-camelcase.html'); 24 | }]); 25 | 26 | 27 | // Declare a controller, this is used in the camelcaseDirective below 28 | var camelCaseControllerFunction = function($scope) { 29 | 30 | $scope.camelCase = function (input) { 31 | // Turn the input value into camelCase and return it. 32 | return input.toLowerCase().replace(/[- ](.)/g, function(match, group1) { 33 | return group1.toUpperCase(); 34 | }); 35 | }; 36 | 37 | $scope.makeCamelCase = function () { 38 | // This is invoked by the ng-click 39 | // The ngModel in ASF is an array, we want to access the actual value 40 | var leaf_model = $scope.ngModel[$scope.ngModel.length - 1]; 41 | if (leaf_model.$modelValue) { 42 | // If there is something to camelCase, do it! 43 | leaf_model.$setViewValue($scope.camelCase(leaf_model.$modelValue)); 44 | }; 45 | }; 46 | }; 47 | 48 | // Create a directive to properly access the ngModel set in the view (src/angular-schema-form-camelcase.html) 49 | angular.module('schemaForm').directive('camelCaseDirective', function() { 50 | return { 51 | // The directive needs the ng-model to be set, look at the
52 | require: ['ngModel'], 53 | restrict: 'A', 54 | // Do not create a isolate scope, makeCamelCase should be available to the button element 55 | scope: false, 56 | // Define a controller, use the function from above, inject the scope 57 | controller : ['$scope', camelCaseControllerFunction], 58 | // Use the link function to initiate the ngModel in the controller scope 59 | link: function(scope, iElement, iAttrs, ngModelCtrl) { 60 | scope.ngModel = ngModelCtrl; 61 | } 62 | }; 63 | }); 64 | -------------------------------------------------------------------------------- /documentation/extending.md: -------------------------------------------------------------------------------- 1 | Extending Angular Schema Form(ASF) 2 | ===================== 3 | ASF is designed to be easily extended and there are two ways to do it: 4 | 5 | 1. Add a new field type, for example, to make add-ons like the [date picker](https://github.com/Textalk/angular-schema-form-datepicker). 6 | 2. Add a new decorator, when you need to make general behavioral changes for your application(?) 7 | 8 | *In this text, an "ASF user" does not mean an end-user, but a developer using ASF.* 9 | 10 | ## Adding a field type 11 | 12 | ### What is a field type? 13 | 14 | A ASF field type consists of the following parts: 15 | 16 | 1. A HTML template that define the UI 17 | 2. An AngularJS config file that adds the extra configuration to ASF 18 | 3. Optionally: Additional controllers and directives. 19 | 20 | The minimal configuration for implementing a new field type is 1 and 2, and is represented by the 21 | [minimal example](https://github.com/OptimalBPM/angular-schema-form-add-ons/tree/master/examples/minimal). 22 | 23 | More advanced functionality is shown in the [camelCase example](https://github.com/OptimalBPM/angular-schema-form-add-ons/tree/master/examples/camelcase) 24 | 25 | ### Creating a field type/add-on 26 | 27 | *Before you embark on creating a new field type, please read the [creating a new add-on](https://github.com/OptimalBPM/angular-schema-form-add-ons/wiki/Creating-a-new-add-on) article.* 28 | 29 | #### The HTML template 30 | The HTML template defines the UI(view) of the field type, what the user sees. 31 | The ["minimal" example](https://github.com/OptimalBPM/angular-schema-form-add-ons/blob/master/examples/minimal/src/angular-schema-form-minimal.html) 32 | shows a very basic implementation. 33 | 34 | Basically, ASF shows the template instead of the built-in UI when it encounters either a specified combination of schema types, or a "type" field type setting in the form. 35 | 36 | There is more on what the template can do later on, in the [Scope and helper functions](https://github.com/OptimalBPM/angular-schema-form-add-ons/blob/New_Extending/documentation/extending.md#Scope)-section. 37 | 38 | #### Make ASF show my field type when it is supposed to 39 | 40 | Just creating a template is not enough, ASF needs to know when to use it. 41 | ASF provides two ways to decide when to show a field type, implicitly or explicitly. 42 | 43 | To configure ASF for this, module.config is used. 44 | This document will use the [configuration of the "minimal" example](https://github.com/OptimalBPM/angular-schema-form-add-ons/blob/master/examples/minimal/src/angular-schema-form-minimal.js) 45 | to demonstrate these and try to explain it. It is recommended to open the example in another tab for reference. 46 | 47 | In it, the configuration is applied to schema form as a function definition: 48 | ```javascript 49 | angular.module('schemaForm').config(['schemaFormProvider', 'schemaFormDecoratorsProvider', 'sfPathProvider', 50 | function(schemaFormProvider, schemaFormDecoratorsProvider, sfPathProvider) { 51 | 52 | // Default mappings goes in here.. 53 | 54 | // Explicit type mappings also.. 55 | 56 | // Register it as a directive 57 | }]); 58 | ``` 59 | 60 | So first, how to show it as as per default: 61 | 62 | ##### Implicitly, default UI for a schema field 63 | 64 | Let's assume that the schema specifies a combination of data type(not to be confused with the "type" in the form) and format that 65 | should get "our" field type as default: 66 | ```javascript 67 | minimal_format: { 68 | type: "string", 69 | format: "minimal", 70 | description: "When you edit this, it is in the add-ons input box." 71 | }, 72 | ``` 73 | We want our field type to be use in this situation. 74 | You achieve this by adding it to the `schemaFormProvider.defaults` object. The `schemaFormProvider.defaults` 75 | is an object with a key for each type *in JSON Schema* with a array of functions as its value. 76 | 77 | ```javascript 78 | var defaults = { 79 | string: [], 80 | object: [], 81 | number: [], 82 | integer: [], 83 | boolean: [], 84 | array: [] 85 | }; 86 | ``` 87 | 88 | When ASF traverses the JSON Schema to create default form definitions it first checks the 89 | *JSON Schema type* and then calls on each function in the corresponding list *in order* until a 90 | function actually returns something. That is then used as a default. 91 | 92 | So, to make ASF show the "minimal" field type, a callback function is registered in the defaults array: 93 | 94 | ```javascript 95 | // First, we want this to be the default for a combination of schema parameters 96 | var minimal = function (name, schema, options) { 97 | if (schema.type === 'string' && schema.format == 'minimal') { 98 | // Initiate a form provider 99 | var f = schemaFormProvider.stdFormObj(name, schema, options); 100 | f.key = options.path; 101 | f.type = 'minimal'; 102 | // Add it to the lookup dict (for internal use) 103 | options.lookup[sfPathProvider.stringify(options.path)] = f; 104 | return f; 105 | } 106 | }; 107 | 108 | // Add our default to the defaults array 109 | schemaFormProvider.defaults.string.unshift(minimal); 110 | ``` 111 | 112 | Now, when ASF loops the defaults-array for "string", one entry will return a form instance when the type is "string" and schema.format is "minimal". 113 | ASF will the use that form, hopefully only the "minimal"-form to display the field type template. 114 | 115 | The condition for the "minimal" field type default could be any condition, for example, if the schema.format condition was removed, 116 | all "string" type fields would get the "minimal" field type UI. 117 | 118 | ##### Explicitly specified field type 119 | 120 | The there is the case where a ASF user explicitly specifies the field type in the form definition: 121 | ```javascript 122 | { 123 | "key": "minimal_form_type", 124 | "title": "Example of minimal editor via form type", 125 | "type": "minimal" 126 | } 127 | ``` 128 | 129 | To show a field type when the type is specified, the field type has to be registered. 130 | That mapping is then made like this: 131 | ```javascript 132 | schemaFormDecoratorsProvider.addMapping('bootstrapDecorator', 'minimal', 133 | 'directives/decorators/bootstrap/minimal/angular-schema-form-minimal.html'); 134 | ``` 135 | 136 | The first argument is the name of the decorator, usually `bootstrapDecorator`. Use that unless you know what you are doing. 137 | The second argument is the name of your new form type, in this case `minimal` 138 | The third is the template we bind to it. 139 | 140 | *Note: The createDirective step has been deprecated and is no longer necessary* 141 | 142 | At this stage, we might have a working add-on. However, normally, the template needs to be developed further: 143 | 144 | ### Scope and helper functions 145 | 146 | It is up to the template to use directives, controllers and any other angular trick to implement whatever it want to implement. 147 | 148 | Each form field will be rendered inside a decorator directive, created by the 149 | `schemaFormDecorators` factory service, *do* 150 | [check the source](https://github.com/Textalk/angular-schema-form/blob/master/src/services/decorators.js#L33). 151 | 152 | This means you have several helper functions and values on scope, most important of them, `form`. The 153 | `form` variable contains the merged form definition for that field, i.e. your supplied form object + 154 | the defaults from the schema (it also has its part of the schema under *form.schema*). 155 | This is how you define and use new form field options, whatever is set on the form object is 156 | available here for you to act on. 157 | 158 | | Name | What it does | 159 | |----------|----------------| 160 | | form | Form definition object | 161 | | showTitle() | Shorthand for `form && form.notitle !== true && form.title` | 162 | | ngModel | The ngModel controller, this will be on scope if you use either the directive `schema-validate` or `sf-array` | 163 | | evalInScope(expr, locals) | Eval supplied expression, ie scope.$eval | 164 | | evalExpr(expr, locals) | Eval an expression in the parent scope of the main `sf-schema` directive. | 165 | | interp(expr, locals) | Interpolate an expression which may or may not contain expression `{{ }}` sequences | 166 | | buttonClick($event, form) | Use this with ng-click to execute form.onClick | 167 | | hasSuccess() | Shorthand for `ngModel.$valid && (!ngModel.$pristine || !ngModel.$isEmpty(ngModel.$modelValue))` | 168 | | hasError() | Shorthand for `ngModel.$invalid && !ngModel.$pristine` | 169 | 170 | ### The magic $$value$$ 171 | ASF wants to play nice with the built in Angular directives for form. 172 | 173 | Especially `ng-model`, which we want to handle the two way binding against our model value. Also by using `ng-model` we 174 | get all the nice validation states from the `ngModelController` and `FormController` that we all 175 | know and love. 176 | 177 | To get that working properly we had to resort to a bit of trickery, right before we let Angular 178 | compile the field template we do a simple string replacement of `$$value$$` and replace that 179 | with the path to the current form field on the model, i.e. `form.key`. 180 | 181 | So `ng-model="$$value$$"` becomes something like `ng-model="model['person']['address']['street']"`, 182 | you can see this if you inspect the final form in the browser. 183 | 184 | *Hint: The [camelCase example demo](http://demo.optimalbpm.se/angular-schema-form-add-ons/examples/camelcase/example.html) actually prints out the value of $$value$$ in the second field.* 185 | 186 | So basically, you always have a `ng-model="$$value$$"` (Pro tip: ng-model is fine on any element, put 187 | it on the same div as your custom directive and require the ngModelController for full control). 188 | 189 | #### Deprecation warning 190 | There is still a `errorMessage` function on scope but it's been deprecated. Please use the 191 | `sf-message` directive instead. 192 | 193 | ### schema-validate directive 194 | `schema-validate` is a directive that you should put on the same element as your `ng-model`. It is 195 | responsible for validating the value against the schema using [tv4js](https://github.com/geraintluff/tv4) 196 | It takes the form definition as an argument. 197 | 198 | 199 | ### sf-message directive 200 | Error messages are nice, and the best way to get them is via the `sf-message` directive. It usually 201 | takes `form.description` as an argument so it can show that until an error occurs. 202 | 203 | 204 | ### Sharing your add-on with the world 205 | 206 | If you now have a working add-on, it is time to share it with the rest of us. 207 | 208 | The [publishing the add-on](https://github.com/OptimalBPM/angular-schema-form-add-ons/wiki/Publishing-the-add-on) article details how this is done. 209 | 210 | 211 | Decorators 212 | ---------- 213 | Decorators are a second way to extend Schema Form, the thought being that you should easily be able 214 | to change *every* field. Maybe you like it old school and want to use bootstrap 2. Or maybe you like 215 | to generate a table with the data instead? Right now there are no other decorators than bootstrap 3. 216 | 217 | Basically a *decorator* sets up all the mappings between form types and their respective templates 218 | using the `schemaFormDecoratorsProvider.createDecorator()` function. 219 | 220 | ```javascript 221 | var base = 'directives/decorators/bootstrap/'; 222 | 223 | schemaFormDecoratorsProvider.createDecorator('bootstrapDecorator', { 224 | textarea: base + 'textarea.html', 225 | fieldset: base + 'fieldset.html', 226 | array: base + 'array.html', 227 | tabarray: base + 'tabarray.html', 228 | tabs: base + 'tabs.html', 229 | section: base + 'section.html', 230 | conditional: base + 'section.html', 231 | actions: base + 'actions.html', 232 | select: base + 'select.html', 233 | checkbox: base + 'checkbox.html', 234 | checkboxes: base + 'checkboxes.html', 235 | number: base + 'default.html', 236 | password: base + 'default.html', 237 | submit: base + 'submit.html', 238 | button: base + 'submit.html', 239 | radios: base + 'radios.html', 240 | 'radios-inline': base + 'radios-inline.html', 241 | radiobuttons: base + 'radio-buttons.html', 242 | help: base + 'help.html', 243 | 'default': base + 'default.html' 244 | }, [ 245 | function(form) { 246 | if (form.readonly && form.key && form.type !== 'fieldset') { 247 | return base + 'readonly.html'; 248 | } 249 | } 250 | ]); 251 | ``` 252 | `schemaFormDecoratorsProvider.createDecorator(name, mapping, rules)` takes a name argument, a mapping object 253 | (type -> template) and an optional list of rule functions. 254 | 255 | When the decorator is trying to match a form type against a tempate it first executes all the rules 256 | in order. If one returns that is used as template, otherwise it checks the mappings. 257 | --------------------------------------------------------------------------------