├── .bower.json ├── .gitignore ├── LICENSE ├── README.md ├── app.js ├── bower.json ├── dist ├── schema-form-file.js └── schema-form-file.min.js ├── gulpfile.js ├── index.html ├── package.json ├── schema-form-file.css ├── src ├── nwp-file.html └── schema-form-file.js ├── upload_1.png ├── upload_2.png └── upload_3.png /.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular-schema-form-nwp-file-upload", 3 | "homepage": "https://github.com/saburab/angular-schema-form-nwp-file-upload", 4 | "authors": [ 5 | "Sufian Abu-Rab " 6 | ], 7 | "dependencies": { 8 | "angular": ">= 1.3", 9 | "angular-schema-form": ">= 0.8.3", 10 | "ng-file-upload": "^7.2.1" 11 | }, 12 | "devDependencies": { 13 | "bootstrap": "~3.3.5" 14 | }, 15 | "description": "Upload file type for Angular Schema Form", 16 | "keywords": [ 17 | "angular", 18 | "angularjs", 19 | "schema", 20 | "form", 21 | "file", 22 | "upload" 23 | ], 24 | "main": "dist/schema-form-file.min.js", 25 | "license": "MIT", 26 | "ignore": [ 27 | "**/.*", 28 | "node_modules", 29 | "bower_components", 30 | "test", 31 | "tests" 32 | ], 33 | "_release": "6c26056", 34 | "_resolution": { 35 | "type": "branch", 36 | "branch": "master", 37 | "commit": "6c26056fdb9060c45d1d091edd5275fc074d8e16" 38 | }, 39 | "_source": "https://github.com/saburab/angular-schema-form-nwp-file-upload.git", 40 | "_target": "*", 41 | "_originalSource": "https://github.com/saburab/angular-schema-form-nwp-file-upload.git", 42 | "_direct": true 43 | } 44 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | 5 | # Runtime data 6 | pids 7 | *.pid 8 | *.seed 9 | 10 | # Directory for instrumented libs generated by jscoverage/JSCover 11 | lib-cov 12 | 13 | # Coverage directory used by tools like istanbul 14 | coverage 15 | 16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 17 | .grunt 18 | 19 | # node-waf configuration 20 | .lock-wscript 21 | 22 | # Compiled binary addons (http://nodejs.org/api/addons.html) 23 | build/Release 24 | 25 | # Dependency directory 26 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git 27 | node_modules 28 | /nbproject/private/ 29 | bower_components 30 | 31 | .bower.json 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Netzwerkplan GmbH 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 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Angular Schema Form File-Upload add-on by Netzwerkplan GmbH 2 | ================= 3 | 4 | This file upload add-on uses the angular-file-upload plugin by danial farid to provide a file upload interface. [ng-file-upload](https://github.com/danialfarid/ng-file-upload) is used. 5 | 6 | Installation 7 | ------------ 8 | The editor is an add-on to the Bootstrap decorator. To use it, just include 9 | `schema-form-file.min.js`. 10 | 11 | Easiest way is to install is with bower, this will also include dependencies: 12 | ```bash 13 | $ bower install angular-schema-form-nwp-file-upload 14 | ``` 15 | 16 | You'll need to load a few additional files to use the editor: 17 | 18 | **Be sure to load this projects files after you load angular schema form** 19 | 20 | Example 21 | 22 | ```HTML 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | ``` 37 | 38 | When you create your module, be sure to depend on this project's module as well. 39 | 40 | ```javascript 41 | angular.module('yourModule', ['schemaForm','pascalprecht.translate', 'ngSchemaFormFile']); 42 | ``` 43 | 44 | Usage 45 | ----- 46 | The add-on adds three new form type, `datepicker, timepicker, datetimepicker`, and three new default 47 | mappings. 48 | 49 | | Schema | Default Form type | 50 | |:-------------------|:------------:| 51 | | "type": "array" and "format": "singlefile" | nwpFileUpload | 52 | | "type": "array" and "format": "multifile" | nwpFileUpload | 53 | 54 | 55 | Options 56 | ------- 57 | 58 | ### single- and multifile upload 59 | 60 | **Example** 61 | 62 | ```javascript 63 | { 64 | "schema": { 65 | "type": "object", 66 | "title": "Album", 67 | "properties": { 68 | "image": { 69 | "title": "Image", 70 | "type": "array", 71 | "format": "singlefile", 72 | "x-schema-form": { 73 | "type": "array" 74 | }, 75 | "pattern": { 76 | "mimeType": "image/*", 77 | "validationMessage": "Falscher Dateityp: " 78 | }, 79 | "maxSize": { 80 | "maximum": "2MB", 81 | "validationMessage": "Erlaubte Dateigröße überschritten: ", 82 | "validationMessage2": "Aktuelle Dateigröße: " 83 | }, 84 | "maxItems": { 85 | "validationMessage": "Es wurden mehr Dateien hochgeladen als erlaubt." 86 | }, 87 | "minItems": { 88 | "validationMessage": "Sie müssen mindestens eine Datei hochladen" 89 | } 90 | }, 91 | "images": { 92 | "title": "Images", 93 | "type": "array", 94 | "format": "multifile", 95 | "x-schema-form": { 96 | "type": "array" 97 | }, 98 | "pattern": { 99 | "mimeType": "image/*,!.gif", 100 | "validationMessage": "Falscher Dateityp: " 101 | }, 102 | "maxSize": { 103 | "maximum": "2MB", 104 | "validationMessage": "Erlaubte Dateigröße überschritten: ", 105 | "validationMessage2": "Aktuelle Dateigröße: " 106 | }, 107 | "maxItems": { 108 | "validationMessage": "Es wurden mehr Dateien hochgeladen als erlaubt." 109 | }, 110 | "minItems": { 111 | "validationMessage": "Sie müssen mindestens eine Datei hochladen" 112 | } 113 | } 114 | }, 115 | "required": [ 116 | "images" 117 | ] 118 | }, 119 | "form": [ 120 | { 121 | "key": "image", 122 | "type": "nwpFileUpload", 123 | "endpoint": "https://angular-file-upload-cors-srv.appspot.com/upload", 124 | "i18n": { 125 | "add": "Open file browser", 126 | "preview": "Preview Upload", 127 | "filename": "File Name", 128 | "progress": "Progress Status", 129 | "upload": "Upload", 130 | "dragorclick": "Drag and drop your file here or click here" 131 | } 132 | }, 133 | { 134 | "key": "images", 135 | "type": "nwpFileUpload", 136 | "endpoint": "https://angular-file-upload-cors-srv.appspot.com/upload" 137 | } 138 | ] 139 | } 140 | ``` 141 | 142 | Labels 143 | ------ 144 | 145 | ### From the form definition using i18n 146 | 147 | In the above example, the form definition for singleFile upload, labels are defined by using the "i18n" object. 148 | 149 | ### By using the angular translate module 150 | If there is no i18n object defined for the form then angular translate come into play. Label will fallback to the configured translated strings. 151 | 152 | **Example Configuration** 153 | ```javascript 154 | 155 | yourAngularApp.config(['$translateProvider', function($translateProvider) { 156 | $translateProvider.translations('en', { 157 | 'modules.upload.dndNotSupported': 'Drag n drop not surpported by your browser', 158 | 'modules.attribute.fields.required.caption': 'Required', 159 | 'modules.upload.descriptionSinglefile': 'Drop your file here', 160 | 'modules.upload.descriptionMultifile': 'Drop your file(s) here', 161 | 'buttons.add': 'Open file browser', 162 | 'modules.upload.field.filename': 'Filename', 163 | 'modules.upload.field.preview': 'Preview', 164 | 'modules.upload.multiFileUpload': 'Multifile upload', 165 | 'modules.upload.field.progress': 'Progress', 166 | 'buttons.upload': 'Upload' 167 | }); 168 | $translateProvider.preferredLanguage('en'); 169 | 170 | }]); 171 | 172 | ``` 173 | 174 | 175 | Example pictures 176 | ------- 177 | **Initial state** 178 | 179 | ![alt tag](https://raw.githubusercontent.com/saburab/angular-schema-form-nwp-file-upload/master/upload_1.png) 180 | 181 | 182 | **Preview** 183 | 184 | ![alt tag](https://raw.githubusercontent.com/saburab/angular-schema-form-nwp-file-upload/master/upload_2.png) 185 | 186 | 187 | **On error** 188 | 189 | ![alt tag](https://raw.githubusercontent.com/saburab/angular-schema-form-nwp-file-upload/master/upload_3.png) 190 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var myApp = angular.module('formApp', [ 4 | 'schemaForm', 5 | 'pascalprecht.translate', 6 | 'ngSchemaFormFile' 7 | ]) 8 | .controller('formController', ['$scope', '$q', function($scope, $q) { 9 | 10 | $scope.schema = { 11 | "type": "object", 12 | "title": "Album", 13 | "properties": { 14 | "image": { 15 | "title": "Image (Label coming from form definition)", 16 | "type": "array", 17 | "format": "singlefile", 18 | "x-schema-form": { 19 | "type": "array" 20 | }, 21 | "pattern": { 22 | "mimeType": "image/*", 23 | "validationMessage": "Falscher Dateityp: " 24 | }, 25 | "maxSize": { 26 | "maximum": "2MB", 27 | "validationMessage": "Erlaubte Dateigröße überschritten: ", 28 | "validationMessage2": "Aktuelle Dateigröße: " 29 | }, 30 | "maxItems": { 31 | "validationMessage": "Es wurden mehr Dateien hochgeladen als erlaubt." 32 | }, 33 | "minItems": { 34 | "validationMessage": "Sie müssen mindestens eine Datei hochladen" 35 | } 36 | }, 37 | "images": { 38 | "title": "Images (Labels defined using the translate module)", 39 | "type": "array", 40 | "format": "multifile", 41 | "x-schema-form": { 42 | "type": "array" 43 | }, 44 | "pattern": { 45 | "mimeType": "image/*,!.gif", 46 | "validationMessage": "Falscher Dateityp: " 47 | }, 48 | "maxSize": { 49 | "maximum": "2MB", 50 | "validationMessage": "Erlaubte Dateigröße überschritten: ", 51 | "validationMessage2": "Aktuelle Dateigröße: " 52 | }, 53 | "maxItems": { 54 | "validationMessage": "Es wurden mehr Dateien hochgeladen als erlaubt." 55 | }, 56 | "minItems": { 57 | "validationMessage": "Sie müssen mindestens eine Datei hochladen" 58 | } 59 | } 60 | }, 61 | "required": [ 62 | "images" 63 | ] 64 | }; 65 | 66 | $scope.form = [{ 67 | "key": "image", 68 | "type": "nwpFileUpload", 69 | "endpoint": "https://angular-file-upload-cors-srv.appspot.com/upload", 70 | "i18n": { 71 | "add": "Open file browser", 72 | "preview": "Preview Upload", 73 | "filename": "File Name", 74 | "progress": "Progress Status", 75 | "upload": "Upload", 76 | "dragorclick": "Drag and drop your file here or click here" 77 | } 78 | }, { 79 | "key": "images", 80 | "type": "nwpFileUpload", 81 | "endpoint": "https://angular-file-upload-cors-srv.appspot.com/upload" 82 | }]; 83 | 84 | $scope.model = {}; 85 | 86 | $scope.submit = function() { 87 | $scope.$broadcast('schemaFormValidate'); 88 | if ($scope.myForm.$valid) { 89 | console.log('form valid'); 90 | } 91 | }; 92 | 93 | }]) 94 | .config(['$translateProvider', function($translateProvider) { 95 | // Simply register translation table as object hash 96 | $translateProvider.translations('en', { 97 | 'modules.upload.dndNotSupported': 'Drag n drop not surpported by your browser', 98 | 'modules.attribute.fields.required.caption': 'Required', 99 | 'modules.upload.descriptionSinglefile': 'Drop your file here', 100 | 'modules.upload.descriptionMultifile': 'Drop your file(s) here', 101 | 'buttons.add': 'Open file browser', 102 | 'modules.upload.field.filename': 'Filename', 103 | 'modules.upload.field.preview': 'Preview', 104 | 'modules.upload.multiFileUpload': 'Multifile upload', 105 | 'modules.upload.field.progress': 'Progress', 106 | 'buttons.upload': 'Upload' 107 | }); 108 | $translateProvider.preferredLanguage('en'); 109 | 110 | }]); -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular-schema-form-nwp-file-upload", 3 | "version": "0.1.5", 4 | "homepage": "https://github.com/saburab/angular-schema-form-nwp-file-upload", 5 | "authors": [ 6 | "Sufian Abu-Rab " 7 | ], 8 | "dependencies": { 9 | "angular": ">= 1.3", 10 | "angular-schema-form": ">= 0.8.3", 11 | "ng-file-upload": "^7.2.1", 12 | "angular-messages": ">= 1.3", 13 | "angular-translate": "^2.13.1" 14 | }, 15 | "devDependencies": { 16 | "bootstrap": "~3.3.5" 17 | }, 18 | "description": "Upload file type for Angular Schema Form", 19 | "keywords": [ 20 | "angular", 21 | "angularjs", 22 | "schema", 23 | "form", 24 | "file", 25 | "upload" 26 | ], 27 | "main": "dist/schema-form-file.js", 28 | "license": "MIT", 29 | "ignore": [ 30 | "**/.*", 31 | "node_modules", 32 | "bower_components", 33 | "test", 34 | "tests" 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /dist/schema-form-file.js: -------------------------------------------------------------------------------- 1 | /** 2 | * angular-schema-form-nwp-file-upload - Upload file type for Angular Schema Form 3 | * @version v0.1.5 4 | * @link https://github.com/saburab/angular-schema-form-nwp-file-upload 5 | * @license MIT 6 | */ 7 | /** 8 | * angular-schema-form-nwp-file-upload - Upload file type for Angular Schema Form 9 | * @version v0.1.5 10 | * @link https://github.com/saburab/angular-schema-form-nwp-file-upload 11 | * @license MIT 12 | */ 13 | 'use strict'; 14 | 15 | angular 16 | .module('schemaForm') 17 | .config(['schemaFormProvider', 'schemaFormDecoratorsProvider', 'sfPathProvider', 18 | function (schemaFormProvider, schemaFormDecoratorsProvider, sfPathProvider) { 19 | var defaultPatternMsg = 'Wrong file type. Allowed types are ', 20 | defaultMaxSizeMsg1 = 'This file is too large. Maximum size allowed is ', 21 | defaultMaxSizeMsg2 = 'Current file size:', 22 | defaultMinItemsMsg = 'You have to upload at least one file', 23 | defaultMaxItemsMsg = 'You can\'t upload more than one file.'; 24 | 25 | var nwpSinglefileUpload = function (name, schema, options) { 26 | if (schema.type === 'array' && schema.format === 'singlefile') { 27 | if (schema.pattern && schema.pattern.mimeType && !schema.pattern.validationMessage) { 28 | schema.pattern.validationMessage = defaultPatternMsg; 29 | } 30 | if (schema.maxSize && schema.maxSize.maximum && !schema.maxSize.validationMessage) { 31 | schema.maxSize.validationMessage = defaultMaxSizeMsg1; 32 | schema.maxSize.validationMessage2 = defaultMaxSizeMsg2; 33 | } 34 | if (schema.minItems && schema.minItems.minimum && !schema.minItems.validationMessage) { 35 | schema.minItems.validationMessage = defaultMinItemsMsg; 36 | } 37 | if (schema.maxItems && schema.maxItems.maximum && !schema.maxItems.validationMessage) { 38 | schema.maxItems.validationMessage = defaultMaxItemsMsg; 39 | } 40 | 41 | var f = schemaFormProvider.stdFormObj(name, schema, options); 42 | f.key = options.path; 43 | f.type = 'nwpFileUpload'; 44 | options.lookup[sfPathProvider.stringify(options.path)] = f; 45 | return f; 46 | } 47 | }; 48 | 49 | schemaFormProvider.defaults.array.unshift(nwpSinglefileUpload); 50 | 51 | var nwpMultifileUpload = function (name, schema, options) { 52 | if (schema.type === 'array' && schema.format === 'multifile') { 53 | if (schema.pattern && schema.pattern.mimeType && !schema.pattern.validationMessage) { 54 | schema.pattern.validationMessage = defaultPatternMsg; 55 | } 56 | if (schema.maxSize && schema.maxSize.maximum && !schema.maxSize.validationMessage) { 57 | schema.maxSize.validationMessage = defaultMaxSizeMsg1; 58 | schema.maxSize.validationMessage2 = defaultMaxSizeMsg2; 59 | } 60 | if (schema.minItems && schema.minItems.minimum && !schema.minItems.validationMessage) { 61 | schema.minItems.validationMessage = defaultMinItemsMsg; 62 | } 63 | if (schema.maxItems && schema.maxItems.maximum && !schema.maxItems.validationMessage) { 64 | schema.maxItems.validationMessage = defaultMaxItemsMsg; 65 | } 66 | 67 | var f = schemaFormProvider.stdFormObj(name, schema, options); 68 | f.key = options.path; 69 | f.type = 'nwpFileUpload'; 70 | options.lookup[sfPathProvider.stringify(options.path)] = f; 71 | return f; 72 | } 73 | }; 74 | 75 | schemaFormProvider.defaults.array.unshift(nwpMultifileUpload); 76 | 77 | schemaFormDecoratorsProvider.addMapping( 78 | 'bootstrapDecorator', 79 | 'nwpFileUpload', 80 | 'directives/decorators/bootstrap/nwp-file/nwp-file.html' 81 | ); 82 | } 83 | ]); 84 | 85 | angular 86 | .module('ngSchemaFormFile', [ 87 | 'ngFileUpload', 88 | 'ngMessages' 89 | ]) 90 | .directive('ngSchemaFile', ['Upload', '$timeout', '$q', function (Upload, $timeout, $q) { 91 | return { 92 | restrict: 'A', 93 | scope: true, 94 | require: 'ngModel', 95 | link: function (scope, element, attrs, ngModel) { 96 | scope.url = scope.form && scope.form.endpoint; 97 | scope.isSinglefileUpload = scope.form && scope.form.schema && scope.form.schema.format === 'singlefile'; 98 | 99 | scope.selectFile = function (file) { 100 | scope.picFile = file; 101 | }; 102 | scope.selectFiles = function (files) { 103 | scope.picFiles = files; 104 | }; 105 | 106 | scope.uploadFile = function (file) { 107 | file && doUpload(file); 108 | }; 109 | 110 | scope.uploadFiles = function (files) { 111 | files.length && angular.forEach(files, function (file) { 112 | doUpload(file); 113 | }); 114 | }; 115 | 116 | function doUpload(file) { 117 | if (file && !file.$error && scope.url) { 118 | var options = { 119 | url: scope.url, 120 | file: {} 121 | }; 122 | options.file[scope.form.fileName || 'file'] = file; 123 | file.upload = Upload.upload(options); 124 | 125 | file.upload.then(function (response) { 126 | $timeout(function () { 127 | file.result = response.data; 128 | }); 129 | var result = scope.form.post ? scope.form.post(response.data) : response.data; 130 | ngModel.$setViewValue(result); 131 | ngModel.$commitViewValue(); 132 | }, function (response) { 133 | if (response.status > 0) { 134 | scope.errorMsg = response.status + ': ' + response.data; 135 | } 136 | }); 137 | 138 | file.upload.progress(function (evt) { 139 | file.progress = Math.min(100, parseInt(100.0 * 140 | evt.loaded / evt.total)); 141 | }); 142 | } 143 | } 144 | 145 | scope.validateField = function () { 146 | if (scope.uploadForm.file && scope.uploadForm.file.$valid && scope.picFile && !scope.picFile.$error) { 147 | console.log('singlefile-form is invalid'); 148 | } else if (scope.uploadForm.files && scope.uploadForm.files.$valid && scope.picFiles && !scope.picFiles.$error) { 149 | console.log('multifile-form is invalid'); 150 | } else { 151 | console.log('single- and multifile-form are valid'); 152 | } 153 | }; 154 | scope.submit = function () { 155 | if (scope.uploadForm.file && scope.uploadForm.file.$valid && scope.picFile && !scope.picFile.$error) { 156 | scope.uploadFile(scope.picFile); 157 | } else if (scope.uploadForm.files && scope.uploadForm.files.$valid && scope.picFiles && !scope.picFiles.$error) { 158 | scope.uploadFiles(scope.picFiles); 159 | } 160 | }; 161 | scope.$on('schemaFormValidate', scope.validateField); 162 | scope.$on('schemaFormFileUploadSubmit', scope.submit); 163 | } 164 | }; 165 | }]); 166 | 167 | angular.module("schemaForm").run(["$templateCache", function($templateCache) {$templateCache.put("directives/decorators/bootstrap/nwp-file/nwp-file.html","\n \n
\n
\n
\n
    \n
  • \n
    \n
  • \n
\n
\n \n
\n
\n
{{ \'modules.attribute.fields.required.caption\' | translate }}
\n
\n
\n
\n\n\n");}]); 168 | //# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNjaGVtYS1mb3JtLWZpbGUuanMiLCJ0ZW1wbGF0ZXMuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OEVDL0pBIiwiZmlsZSI6InNjaGVtYS1mb3JtLWZpbGUuanMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIGFuZ3VsYXItc2NoZW1hLWZvcm0tbndwLWZpbGUtdXBsb2FkIC0gVXBsb2FkIGZpbGUgdHlwZSBmb3IgQW5ndWxhciBTY2hlbWEgRm9ybVxuICogQHZlcnNpb24gdjAuMS41XG4gKiBAbGluayBodHRwczovL2dpdGh1Yi5jb20vc2FidXJhYi9hbmd1bGFyLXNjaGVtYS1mb3JtLW53cC1maWxlLXVwbG9hZFxuICogQGxpY2Vuc2UgTUlUXG4gKi9cbid1c2Ugc3RyaWN0JztcblxuYW5ndWxhclxuICAgLm1vZHVsZSgnc2NoZW1hRm9ybScpXG4gICAuY29uZmlnKFsnc2NoZW1hRm9ybVByb3ZpZGVyJywgJ3NjaGVtYUZvcm1EZWNvcmF0b3JzUHJvdmlkZXInLCAnc2ZQYXRoUHJvdmlkZXInLFxuICAgICAgZnVuY3Rpb24gKHNjaGVtYUZvcm1Qcm92aWRlciwgc2NoZW1hRm9ybURlY29yYXRvcnNQcm92aWRlciwgc2ZQYXRoUHJvdmlkZXIpIHtcbiAgICAgICAgIHZhciBkZWZhdWx0UGF0dGVybk1zZyAgPSAnV3JvbmcgZmlsZSB0eXBlLiBBbGxvd2VkIHR5cGVzIGFyZSAnLFxuICAgICAgICAgICAgIGRlZmF1bHRNYXhTaXplTXNnMSA9ICdUaGlzIGZpbGUgaXMgdG9vIGxhcmdlLiBNYXhpbXVtIHNpemUgYWxsb3dlZCBpcyAnLFxuICAgICAgICAgICAgIGRlZmF1bHRNYXhTaXplTXNnMiA9ICdDdXJyZW50IGZpbGUgc2l6ZTonLFxuICAgICAgICAgICAgIGRlZmF1bHRNaW5JdGVtc01zZyA9ICdZb3UgaGF2ZSB0byB1cGxvYWQgYXQgbGVhc3Qgb25lIGZpbGUnLFxuICAgICAgICAgICAgIGRlZmF1bHRNYXhJdGVtc01zZyA9ICdZb3UgY2FuXFwndCB1cGxvYWQgbW9yZSB0aGFuIG9uZSBmaWxlLic7XG5cbiAgICAgICAgIHZhciBud3BTaW5nbGVmaWxlVXBsb2FkID0gZnVuY3Rpb24gKG5hbWUsIHNjaGVtYSwgb3B0aW9ucykge1xuICAgICAgICAgICAgaWYgKHNjaGVtYS50eXBlID09PSAnYXJyYXknICYmIHNjaGVtYS5mb3JtYXQgPT09ICdzaW5nbGVmaWxlJykge1xuICAgICAgICAgICAgICAgaWYgKHNjaGVtYS5wYXR0ZXJuICYmIHNjaGVtYS5wYXR0ZXJuLm1pbWVUeXBlICYmICFzY2hlbWEucGF0dGVybi52YWxpZGF0aW9uTWVzc2FnZSkge1xuICAgICAgICAgICAgICAgICAgc2NoZW1hLnBhdHRlcm4udmFsaWRhdGlvbk1lc3NhZ2UgPSBkZWZhdWx0UGF0dGVybk1zZztcbiAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgIGlmIChzY2hlbWEubWF4U2l6ZSAmJiBzY2hlbWEubWF4U2l6ZS5tYXhpbXVtICYmICFzY2hlbWEubWF4U2l6ZS52YWxpZGF0aW9uTWVzc2FnZSkge1xuICAgICAgICAgICAgICAgICAgc2NoZW1hLm1heFNpemUudmFsaWRhdGlvbk1lc3NhZ2UgID0gZGVmYXVsdE1heFNpemVNc2cxO1xuICAgICAgICAgICAgICAgICAgc2NoZW1hLm1heFNpemUudmFsaWRhdGlvbk1lc3NhZ2UyID0gZGVmYXVsdE1heFNpemVNc2cyO1xuICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgaWYgKHNjaGVtYS5taW5JdGVtcyAmJiBzY2hlbWEubWluSXRlbXMubWluaW11bSAmJiAhc2NoZW1hLm1pbkl0ZW1zLnZhbGlkYXRpb25NZXNzYWdlKSB7XG4gICAgICAgICAgICAgICAgICBzY2hlbWEubWluSXRlbXMudmFsaWRhdGlvbk1lc3NhZ2UgPSBkZWZhdWx0TWluSXRlbXNNc2c7XG4gICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICBpZiAoc2NoZW1hLm1heEl0ZW1zICYmIHNjaGVtYS5tYXhJdGVtcy5tYXhpbXVtICYmICFzY2hlbWEubWF4SXRlbXMudmFsaWRhdGlvbk1lc3NhZ2UpIHtcbiAgICAgICAgICAgICAgICAgIHNjaGVtYS5tYXhJdGVtcy52YWxpZGF0aW9uTWVzc2FnZSA9IGRlZmF1bHRNYXhJdGVtc01zZztcbiAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgdmFyIGYgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gc2NoZW1hRm9ybVByb3ZpZGVyLnN0ZEZvcm1PYmoobmFtZSwgc2NoZW1hLCBvcHRpb25zKTtcbiAgICAgICAgICAgICAgIGYua2V5ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IG9wdGlvbnMucGF0aDtcbiAgICAgICAgICAgICAgIGYudHlwZSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9ICdud3BGaWxlVXBsb2FkJztcbiAgICAgICAgICAgICAgIG9wdGlvbnMubG9va3VwW3NmUGF0aFByb3ZpZGVyLnN0cmluZ2lmeShvcHRpb25zLnBhdGgpXSA9IGY7XG4gICAgICAgICAgICAgICByZXR1cm4gZjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgIH07XG5cbiAgICAgICAgIHNjaGVtYUZvcm1Qcm92aWRlci5kZWZhdWx0cy5hcnJheS51bnNoaWZ0KG53cFNpbmdsZWZpbGVVcGxvYWQpO1xuXG4gICAgICAgICB2YXIgbndwTXVsdGlmaWxlVXBsb2FkID0gZnVuY3Rpb24gKG5hbWUsIHNjaGVtYSwgb3B0aW9ucykge1xuICAgICAgICAgICAgaWYgKHNjaGVtYS50eXBlID09PSAnYXJyYXknICYmIHNjaGVtYS5mb3JtYXQgPT09ICdtdWx0aWZpbGUnKSB7XG4gICAgICAgICAgICAgICBpZiAoc2NoZW1hLnBhdHRlcm4gJiYgc2NoZW1hLnBhdHRlcm4ubWltZVR5cGUgJiYgIXNjaGVtYS5wYXR0ZXJuLnZhbGlkYXRpb25NZXNzYWdlKSB7XG4gICAgICAgICAgICAgICAgICBzY2hlbWEucGF0dGVybi52YWxpZGF0aW9uTWVzc2FnZSA9IGRlZmF1bHRQYXR0ZXJuTXNnO1xuICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgaWYgKHNjaGVtYS5tYXhTaXplICYmIHNjaGVtYS5tYXhTaXplLm1heGltdW0gJiYgIXNjaGVtYS5tYXhTaXplLnZhbGlkYXRpb25NZXNzYWdlKSB7XG4gICAgICAgICAgICAgICAgICBzY2hlbWEubWF4U2l6ZS52YWxpZGF0aW9uTWVzc2FnZSAgPSBkZWZhdWx0TWF4U2l6ZU1zZzE7XG4gICAgICAgICAgICAgICAgICBzY2hlbWEubWF4U2l6ZS52YWxpZGF0aW9uTWVzc2FnZTIgPSBkZWZhdWx0TWF4U2l6ZU1zZzI7XG4gICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICBpZiAoc2NoZW1hLm1pbkl0ZW1zICYmIHNjaGVtYS5taW5JdGVtcy5taW5pbXVtICYmICFzY2hlbWEubWluSXRlbXMudmFsaWRhdGlvbk1lc3NhZ2UpIHtcbiAgICAgICAgICAgICAgICAgIHNjaGVtYS5taW5JdGVtcy52YWxpZGF0aW9uTWVzc2FnZSA9IGRlZmF1bHRNaW5JdGVtc01zZztcbiAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgIGlmIChzY2hlbWEubWF4SXRlbXMgJiYgc2NoZW1hLm1heEl0ZW1zLm1heGltdW0gJiYgIXNjaGVtYS5tYXhJdGVtcy52YWxpZGF0aW9uTWVzc2FnZSkge1xuICAgICAgICAgICAgICAgICAgc2NoZW1hLm1heEl0ZW1zLnZhbGlkYXRpb25NZXNzYWdlID0gZGVmYXVsdE1heEl0ZW1zTXNnO1xuICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICB2YXIgZiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSBzY2hlbWFGb3JtUHJvdmlkZXIuc3RkRm9ybU9iaihuYW1lLCBzY2hlbWEsIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgZi5rZXkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gb3B0aW9ucy5wYXRoO1xuICAgICAgICAgICAgICAgZi50eXBlICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gJ253cEZpbGVVcGxvYWQnO1xuICAgICAgICAgICAgICAgb3B0aW9ucy5sb29rdXBbc2ZQYXRoUHJvdmlkZXIuc3RyaW5naWZ5KG9wdGlvbnMucGF0aCldID0gZjtcbiAgICAgICAgICAgICAgIHJldHVybiBmO1xuICAgICAgICAgICAgfVxuICAgICAgICAgfTtcblxuICAgICAgICAgc2NoZW1hRm9ybVByb3ZpZGVyLmRlZmF1bHRzLmFycmF5LnVuc2hpZnQobndwTXVsdGlmaWxlVXBsb2FkKTtcblxuICAgICAgICAgc2NoZW1hRm9ybURlY29yYXRvcnNQcm92aWRlci5hZGRNYXBwaW5nKFxuICAgICAgICAgICAgJ2Jvb3RzdHJhcERlY29yYXRvcicsXG4gICAgICAgICAgICAnbndwRmlsZVVwbG9hZCcsXG4gICAgICAgICAgICAnZGlyZWN0aXZlcy9kZWNvcmF0b3JzL2Jvb3RzdHJhcC9ud3AtZmlsZS9ud3AtZmlsZS5odG1sJ1xuICAgICAgICAgKTtcbiAgICAgIH1cbiAgIF0pO1xuXG5hbmd1bGFyXG4gICAubW9kdWxlKCduZ1NjaGVtYUZvcm1GaWxlJywgW1xuICAgICAgJ25nRmlsZVVwbG9hZCcsXG4gICAgICAnbmdNZXNzYWdlcydcbiAgIF0pXG4gICAuZGlyZWN0aXZlKCduZ1NjaGVtYUZpbGUnLCBbJ1VwbG9hZCcsICckdGltZW91dCcsICckcScsIGZ1bmN0aW9uIChVcGxvYWQsICR0aW1lb3V0LCAkcSkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgIHJlc3RyaWN0OiAnQScsXG4gICAgICAgICBzY29wZTogICAgdHJ1ZSxcbiAgICAgICAgIHJlcXVpcmU6ICAnbmdNb2RlbCcsXG4gICAgICAgICBsaW5rOiAgICAgZnVuY3Rpb24gKHNjb3BlLCBlbGVtZW50LCBhdHRycywgbmdNb2RlbCkge1xuICAgICAgICAgICAgc2NvcGUudXJsID0gc2NvcGUuZm9ybSAmJiBzY29wZS5mb3JtLmVuZHBvaW50O1xuICAgICAgICAgICAgc2NvcGUuaXNTaW5nbGVmaWxlVXBsb2FkID0gc2NvcGUuZm9ybSAmJiBzY29wZS5mb3JtLnNjaGVtYSAmJiBzY29wZS5mb3JtLnNjaGVtYS5mb3JtYXQgPT09ICdzaW5nbGVmaWxlJztcblxuICAgICAgICAgICAgc2NvcGUuc2VsZWN0RmlsZSAgPSBmdW5jdGlvbiAoZmlsZSkge1xuICAgICAgICAgICAgICAgc2NvcGUucGljRmlsZSA9IGZpbGU7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgc2NvcGUuc2VsZWN0RmlsZXMgPSBmdW5jdGlvbiAoZmlsZXMpIHtcbiAgICAgICAgICAgICAgIHNjb3BlLnBpY0ZpbGVzID0gZmlsZXM7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBzY29wZS51cGxvYWRGaWxlID0gZnVuY3Rpb24gKGZpbGUpIHtcbiAgICAgICAgICAgICAgIGZpbGUgJiYgZG9VcGxvYWQoZmlsZSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBzY29wZS51cGxvYWRGaWxlcyA9IGZ1bmN0aW9uIChmaWxlcykge1xuICAgICAgICAgICAgICAgZmlsZXMubGVuZ3RoICYmIGFuZ3VsYXIuZm9yRWFjaChmaWxlcywgZnVuY3Rpb24gKGZpbGUpIHtcbiAgICAgICAgICAgICAgICAgIGRvVXBsb2FkKGZpbGUpO1xuICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBmdW5jdGlvbiBkb1VwbG9hZChmaWxlKSB7XG4gICAgICAgICAgICAgICBpZiAoZmlsZSAmJiAhZmlsZS4kZXJyb3IgJiYgc2NvcGUudXJsKSB7XG4gICAgICAgICAgICAgICAgICB2YXIgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICAgICAgIHVybDogc2NvcGUudXJsLFxuICAgICAgICAgICAgICAgICAgICAgZmlsZToge31cbiAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICBvcHRpb25zLmZpbGVbc2NvcGUuZm9ybS5maWxlTmFtZSB8fCAnZmlsZSddID0gZmlsZTtcbiAgICAgICAgICAgICAgICAgIGZpbGUudXBsb2FkID0gVXBsb2FkLnVwbG9hZChvcHRpb25zKTtcblxuICAgICAgICAgICAgICAgICAgZmlsZS51cGxvYWQudGhlbihmdW5jdGlvbiAocmVzcG9uc2UpIHtcbiAgICAgICAgICAgICAgICAgICAgICR0aW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZpbGUucmVzdWx0ID0gcmVzcG9uc2UuZGF0YTtcbiAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgdmFyIHJlc3VsdCA9IHNjb3BlLmZvcm0ucG9zdCA/IHNjb3BlLmZvcm0ucG9zdChyZXNwb25zZS5kYXRhKSA6IHJlc3BvbnNlLmRhdGE7XG4gICAgICAgICAgICAgICAgICAgICBuZ01vZGVsLiRzZXRWaWV3VmFsdWUocmVzdWx0KTtcbiAgICAgICAgICAgICAgICAgICAgIG5nTW9kZWwuJGNvbW1pdFZpZXdWYWx1ZSgpO1xuICAgICAgICAgICAgICAgICAgfSwgZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG4gICAgICAgICAgICAgICAgICAgICBpZiAocmVzcG9uc2Uuc3RhdHVzID4gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2NvcGUuZXJyb3JNc2cgPSByZXNwb25zZS5zdGF0dXMgKyAnOiAnICsgcmVzcG9uc2UuZGF0YTtcbiAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICBmaWxlLnVwbG9hZC5wcm9ncmVzcyhmdW5jdGlvbiAoZXZ0KSB7XG4gICAgICAgICAgICAgICAgICAgICBmaWxlLnByb2dyZXNzID0gTWF0aC5taW4oMTAwLCBwYXJzZUludCgxMDAuMCAqXG4gICAgICAgICAgICAgICAgICAgICAgICBldnQubG9hZGVkIC8gZXZ0LnRvdGFsKSk7XG4gICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgc2NvcGUudmFsaWRhdGVGaWVsZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgIGlmIChzY29wZS51cGxvYWRGb3JtLmZpbGUgJiYgc2NvcGUudXBsb2FkRm9ybS5maWxlLiR2YWxpZCAmJiBzY29wZS5waWNGaWxlICYmICFzY29wZS5waWNGaWxlLiRlcnJvcikge1xuICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ3NpbmdsZWZpbGUtZm9ybSBpcyBpbnZhbGlkJyk7XG4gICAgICAgICAgICAgICB9IGVsc2UgaWYgKHNjb3BlLnVwbG9hZEZvcm0uZmlsZXMgJiYgc2NvcGUudXBsb2FkRm9ybS5maWxlcy4kdmFsaWQgJiYgc2NvcGUucGljRmlsZXMgJiYgIXNjb3BlLnBpY0ZpbGVzLiRlcnJvcikge1xuICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ211bHRpZmlsZS1mb3JtIGlzICBpbnZhbGlkJyk7XG4gICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ3NpbmdsZS0gYW5kIG11bHRpZmlsZS1mb3JtIGFyZSB2YWxpZCcpO1xuICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHNjb3BlLnN1Ym1pdCAgICAgICAgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICBpZiAoc2NvcGUudXBsb2FkRm9ybS5maWxlICYmIHNjb3BlLnVwbG9hZEZvcm0uZmlsZS4kdmFsaWQgJiYgc2NvcGUucGljRmlsZSAmJiAhc2NvcGUucGljRmlsZS4kZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgIHNjb3BlLnVwbG9hZEZpbGUoc2NvcGUucGljRmlsZSk7XG4gICAgICAgICAgICAgICB9IGVsc2UgaWYgKHNjb3BlLnVwbG9hZEZvcm0uZmlsZXMgJiYgc2NvcGUudXBsb2FkRm9ybS5maWxlcy4kdmFsaWQgJiYgc2NvcGUucGljRmlsZXMgJiYgIXNjb3BlLnBpY0ZpbGVzLiRlcnJvcikge1xuICAgICAgICAgICAgICAgICAgc2NvcGUudXBsb2FkRmlsZXMoc2NvcGUucGljRmlsZXMpO1xuICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHNjb3BlLiRvbignc2NoZW1hRm9ybVZhbGlkYXRlJywgc2NvcGUudmFsaWRhdGVGaWVsZCk7XG4gICAgICAgICAgICBzY29wZS4kb24oJ3NjaGVtYUZvcm1GaWxlVXBsb2FkU3VibWl0Jywgc2NvcGUuc3VibWl0KTtcbiAgICAgICAgIH1cbiAgICAgIH07XG4gICB9XSk7XG4iLG51bGxdfQ== 169 | -------------------------------------------------------------------------------- /dist/schema-form-file.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * angular-schema-form-nwp-file-upload - Upload file type for Angular Schema Form 3 | * @version v0.1.5 4 | * @link https://github.com/saburab/angular-schema-form-nwp-file-upload 5 | * @license MIT 6 | */ 7 | "use strict";angular.module("schemaForm").config(["schemaFormProvider","schemaFormDecoratorsProvider","sfPathProvider",function(e,i,a){var r="Wrong file type. Allowed types are ",l="This file is too large. Maximum size allowed is ",n="Current file size:",s="You have to upload at least one file",t="You can't upload more than one file.",o=function(i,o,m){if("array"===o.type&&"singlefile"===o.format){o.pattern&&o.pattern.mimeType&&!o.pattern.validationMessage&&(o.pattern.validationMessage=r),o.maxSize&&o.maxSize.maximum&&!o.maxSize.validationMessage&&(o.maxSize.validationMessage=l,o.maxSize.validationMessage2=n),o.minItems&&o.minItems.minimum&&!o.minItems.validationMessage&&(o.minItems.validationMessage=s),o.maxItems&&o.maxItems.maximum&&!o.maxItems.validationMessage&&(o.maxItems.validationMessage=t);var d=e.stdFormObj(i,o,m);return d.key=m.path,d.type="nwpFileUpload",m.lookup[a.stringify(m.path)]=d,d}};e.defaults.array.unshift(o);var m=function(i,o,m){if("array"===o.type&&"multifile"===o.format){o.pattern&&o.pattern.mimeType&&!o.pattern.validationMessage&&(o.pattern.validationMessage=r),o.maxSize&&o.maxSize.maximum&&!o.maxSize.validationMessage&&(o.maxSize.validationMessage=l,o.maxSize.validationMessage2=n),o.minItems&&o.minItems.minimum&&!o.minItems.validationMessage&&(o.minItems.validationMessage=s),o.maxItems&&o.maxItems.maximum&&!o.maxItems.validationMessage&&(o.maxItems.validationMessage=t);var d=e.stdFormObj(i,o,m);return d.key=m.path,d.type="nwpFileUpload",m.lookup[a.stringify(m.path)]=d,d}};e.defaults.array.unshift(m),i.addMapping("bootstrapDecorator","nwpFileUpload","directives/decorators/bootstrap/nwp-file/nwp-file.html")}]),angular.module("ngSchemaFormFile",["ngFileUpload","ngMessages"]).directive("ngSchemaFile",["Upload","$timeout","$q",function(e,i,a){return{restrict:"A",scope:!0,require:"ngModel",link:function(a,r,l,n){function s(r){if(r&&!r.$error&&a.url){var l={url:a.url,file:{}};l.file[a.form.fileName||"file"]=r,r.upload=e.upload(l),r.upload.then(function(e){i(function(){r.result=e.data});var l=a.form.post?a.form.post(e.data):e.data;n.$setViewValue(l),n.$commitViewValue()},function(e){e.status>0&&(a.errorMsg=e.status+": "+e.data)}),r.upload.progress(function(e){r.progress=Math.min(100,parseInt(100*e.loaded/e.total))})}}a.url=a.form&&a.form.endpoint,a.isSinglefileUpload=a.form&&a.form.schema&&"singlefile"===a.form.schema.format,a.selectFile=function(e){a.picFile=e},a.selectFiles=function(e){a.picFiles=e},a.uploadFile=function(e){e&&s(e)},a.uploadFiles=function(e){e.length&&angular.forEach(e,function(e){s(e)})},a.validateField=function(){a.uploadForm.file&&a.uploadForm.file.$valid&&a.picFile&&!a.picFile.$error?console.log("singlefile-form is invalid"):a.uploadForm.files&&a.uploadForm.files.$valid&&a.picFiles&&!a.picFiles.$error?console.log("multifile-form is invalid"):console.log("single- and multifile-form are valid")},a.submit=function(){a.uploadForm.file&&a.uploadForm.file.$valid&&a.picFile&&!a.picFile.$error?a.uploadFile(a.picFile):a.uploadForm.files&&a.uploadForm.files.$valid&&a.picFiles&&!a.picFiles.$error&&a.uploadFiles(a.picFiles)},a.$on("schemaFormValidate",a.validateField),a.$on("schemaFormFileUploadSubmit",a.submit)}}}]),angular.module("schemaForm").run(["$templateCache",function(e){e.put("directives/decorators/bootstrap/nwp-file/nwp-file.html",'\n \n
\n
\n
\n
    \n
  • \n
    \n
  • \n
\n
\n \n
\n
\n
{{ \'modules.attribute.fields.required.caption\' | translate }}
\n
\n
\n
\n\n\n')}]); -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'); 2 | 3 | var addStream = require('add-stream'); 4 | var angularTemplatecache = require('gulp-angular-templatecache'); 5 | var concat = require('gulp-concat'); 6 | var connect = require('gulp-connect'); 7 | var header = require('gulp-header'); 8 | var sourcemaps = require('gulp-sourcemaps'); 9 | var uglify = require('gulp-uglify'); 10 | 11 | var bower = require('./bower.json'); 12 | var banner = ['/**', 13 | ' * <%= bower.name %> - <%= bower.description %>', 14 | ' * @version v<%= bower.version %>', 15 | ' * @link <%= bower.homepage %>', 16 | ' * @license <%= bower.license %>', 17 | ' */', 18 | ''].join('\n'); 19 | 20 | function prepareTemplates() { 21 | return gulp.src('./src/*.html') 22 | //.pipe(minify and preprocess the template html here) 23 | .pipe(angularTemplatecache({ 24 | module: 'schemaForm', 25 | root: 'directives/decorators/bootstrap/nwp-file/' 26 | })); 27 | } 28 | 29 | gulp.task('build-app-dev', function() { 30 | return gulp.src('./src/schema-form-file.js') 31 | //.pipe(concat your app js files somehow) 32 | .pipe(sourcemaps.init()) 33 | 34 | // append the template js onto one file 35 | .pipe(addStream.obj(prepareTemplates())) 36 | .pipe(concat('schema-form-file.js')) 37 | 38 | .pipe(sourcemaps.write()) 39 | .pipe(header(banner, { bower : bower } )) 40 | .pipe(gulp.dest('./dist')); 41 | }); 42 | 43 | 44 | gulp.task('build-app-prod', function() { 45 | return gulp.src('./src/schema-form-file.js') 46 | //.pipe(concat your app js files somehow) 47 | 48 | // append the template js onto one file 49 | .pipe(addStream.obj(prepareTemplates())) 50 | .pipe(concat('schema-form-file.min.js')) 51 | 52 | .pipe(uglify()) 53 | .pipe(header(banner, { bower : bower } )) 54 | .pipe(gulp.dest('./dist')); 55 | }); 56 | 57 | gulp.task('default', ['build-app-dev', 'build-app-prod']); -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Angular Schema Form NWP File Upload 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 |

Form with file Demo

14 |
15 |
22 |
23 |
24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular-schema-form-nwp-file-upload", 3 | "version": "0.1.5", 4 | "description": "Upload file type for Angular Schema Form", 5 | "main": "dist/schema-form-file.min.js", 6 | "devDependencies": { 7 | "add-stream": "^1.0.0", 8 | "gulp": "^3.9.0", 9 | "gulp-angular-templatecache": "^1.8.0", 10 | "gulp-concat": "^2.6.0", 11 | "gulp-connect": "^3.2.2", 12 | "gulp-header": "^1.7.1", 13 | "gulp-sourcemaps": "^1.6.0", 14 | "gulp-uglify": "^1.5.3" 15 | }, 16 | "scripts": { 17 | "test": "echo \"Error: no test specified\" && exit 1" 18 | }, 19 | "repository": { 20 | "type": "git", 21 | "url": "git+https://github.com/saburab/angular-schema-form-nwp-file-upload.git" 22 | }, 23 | "keywords": [ 24 | "angular", 25 | "angularjs", 26 | "schema", 27 | "form", 28 | "file", 29 | "upload" 30 | ], 31 | "author": { 32 | "name": "Sufian Abu-Rab", 33 | "email": "s.aburab@gmail.com", 34 | "url": "" 35 | }, 36 | "contributors": [ 37 | { 38 | "name": "Steve Rasch", 39 | "email": "rasch@netzwerkplan.de", 40 | "url": "" 41 | }, 42 | { 43 | "name": "Florian Berthel", 44 | "email": "berthel@netzwerkplan.de", 45 | "url": "" 46 | } 47 | ], 48 | "license": "MIT", 49 | "bugs": { 50 | "url": "https://github.com/saburab/angular-schema-form-nwp-file-upload/issues" 51 | }, 52 | "homepage": "https://github.com/saburab/angular-schema-form-nwp-file-upload#readme" 53 | } 54 | -------------------------------------------------------------------------------- /schema-form-file.css: -------------------------------------------------------------------------------- 1 | .file-upload { 2 | margin-bottom: 15px; 3 | } 4 | .file-upload .dragAndDropDescription { 5 | border: 3px dashed #e1e2e3; 6 | vertical-align: middle; 7 | padding: 0 20px; 8 | } 9 | 10 | .file-upload .dragAndDropDescription p { 11 | vertical-align: middle; 12 | color: #1567ce; 13 | font-weight: 400; 14 | line-height: 1.3em; 15 | margin: 40px auto 40px; 16 | display: block; 17 | } 18 | 19 | .file-upload .progress-bar { 20 | min-width: 2em; 21 | } 22 | 23 | .file-upload label { 24 | display: block; 25 | text-overflow: ellipsis; 26 | white-space: nowrap; 27 | overflow: hidden; 28 | } 29 | 30 | .file-upload .filename { 31 | text-overflow: ellipsis; 32 | white-space: nowrap; 33 | overflow: hidden; 34 | } 35 | 36 | .file-upload .errorMsg { 37 | display: block; 38 | margin-bottom: 5px; 39 | } 40 | 41 | .file-upload > .row { 42 | margin-bottom: 10px; 43 | } 44 | .file-upload > .list-group > .list-group-item { 45 | margin: 0; 46 | } 47 | .file-upload > .list-group > .list-group-item .mb-sm{ 48 | margin: 0; 49 | } 50 | .file-upload #fileInputButton { 51 | margin-top: 15px; 52 | } 53 | .has-error.border-danger { 54 | border-color: #f05050; 55 | } 56 | .mb0 { 57 | margin-bottom: 0 !important; 58 | } 59 | .mb { 60 | margin-bottom: 10px !important; 61 | } 62 | -------------------------------------------------------------------------------- /src/nwp-file.html: -------------------------------------------------------------------------------- 1 | 2 | 5 |
6 |
7 |
8 |
    9 |
  • 10 |
    11 |
  • 12 |
13 |
14 | 15 |
16 |
17 |
{{ 'modules.attribute.fields.required.caption' | translate }}
18 |
19 |
20 |
21 | 52 | 62 | -------------------------------------------------------------------------------- /src/schema-form-file.js: -------------------------------------------------------------------------------- 1 | /** 2 | * angular-schema-form-nwp-file-upload - Upload file type for Angular Schema Form 3 | * @version v0.1.5 4 | * @link https://github.com/saburab/angular-schema-form-nwp-file-upload 5 | * @license MIT 6 | */ 7 | 'use strict'; 8 | 9 | angular 10 | .module('schemaForm') 11 | .config(['schemaFormProvider', 'schemaFormDecoratorsProvider', 'sfPathProvider', 12 | function (schemaFormProvider, schemaFormDecoratorsProvider, sfPathProvider) { 13 | var defaultPatternMsg = 'Wrong file type. Allowed types are ', 14 | defaultMaxSizeMsg1 = 'This file is too large. Maximum size allowed is ', 15 | defaultMaxSizeMsg2 = 'Current file size:', 16 | defaultMinItemsMsg = 'You have to upload at least one file', 17 | defaultMaxItemsMsg = 'You can\'t upload more than one file.'; 18 | 19 | var nwpSinglefileUpload = function (name, schema, options) { 20 | if (schema.type === 'array' && schema.format === 'singlefile') { 21 | if (schema.pattern && schema.pattern.mimeType && !schema.pattern.validationMessage) { 22 | schema.pattern.validationMessage = defaultPatternMsg; 23 | } 24 | if (schema.maxSize && schema.maxSize.maximum && !schema.maxSize.validationMessage) { 25 | schema.maxSize.validationMessage = defaultMaxSizeMsg1; 26 | schema.maxSize.validationMessage2 = defaultMaxSizeMsg2; 27 | } 28 | if (schema.minItems && schema.minItems.minimum && !schema.minItems.validationMessage) { 29 | schema.minItems.validationMessage = defaultMinItemsMsg; 30 | } 31 | if (schema.maxItems && schema.maxItems.maximum && !schema.maxItems.validationMessage) { 32 | schema.maxItems.validationMessage = defaultMaxItemsMsg; 33 | } 34 | 35 | var f = schemaFormProvider.stdFormObj(name, schema, options); 36 | f.key = options.path; 37 | f.type = 'nwpFileUpload'; 38 | options.lookup[sfPathProvider.stringify(options.path)] = f; 39 | return f; 40 | } 41 | }; 42 | 43 | schemaFormProvider.defaults.array.unshift(nwpSinglefileUpload); 44 | 45 | var nwpMultifileUpload = function (name, schema, options) { 46 | if (schema.type === 'array' && schema.format === 'multifile') { 47 | if (schema.pattern && schema.pattern.mimeType && !schema.pattern.validationMessage) { 48 | schema.pattern.validationMessage = defaultPatternMsg; 49 | } 50 | if (schema.maxSize && schema.maxSize.maximum && !schema.maxSize.validationMessage) { 51 | schema.maxSize.validationMessage = defaultMaxSizeMsg1; 52 | schema.maxSize.validationMessage2 = defaultMaxSizeMsg2; 53 | } 54 | if (schema.minItems && schema.minItems.minimum && !schema.minItems.validationMessage) { 55 | schema.minItems.validationMessage = defaultMinItemsMsg; 56 | } 57 | if (schema.maxItems && schema.maxItems.maximum && !schema.maxItems.validationMessage) { 58 | schema.maxItems.validationMessage = defaultMaxItemsMsg; 59 | } 60 | 61 | var f = schemaFormProvider.stdFormObj(name, schema, options); 62 | f.key = options.path; 63 | f.type = 'nwpFileUpload'; 64 | options.lookup[sfPathProvider.stringify(options.path)] = f; 65 | return f; 66 | } 67 | }; 68 | 69 | schemaFormProvider.defaults.array.unshift(nwpMultifileUpload); 70 | 71 | schemaFormDecoratorsProvider.addMapping( 72 | 'bootstrapDecorator', 73 | 'nwpFileUpload', 74 | 'directives/decorators/bootstrap/nwp-file/nwp-file.html' 75 | ); 76 | } 77 | ]); 78 | 79 | angular 80 | .module('ngSchemaFormFile', [ 81 | 'ngFileUpload', 82 | 'ngMessages' 83 | ]) 84 | .directive('ngSchemaFile', ['Upload', '$timeout', '$q', function (Upload, $timeout, $q) { 85 | return { 86 | restrict: 'A', 87 | scope: true, 88 | require: 'ngModel', 89 | link: function (scope, element, attrs, ngModel) { 90 | scope.url = scope.form && scope.form.endpoint; 91 | scope.isSinglefileUpload = scope.form && scope.form.schema && scope.form.schema.format === 'singlefile'; 92 | 93 | scope.selectFile = function (file) { 94 | scope.picFile = file; 95 | }; 96 | scope.selectFiles = function (files) { 97 | scope.picFiles = files; 98 | }; 99 | 100 | scope.uploadFile = function (file) { 101 | file && doUpload(file); 102 | }; 103 | 104 | scope.uploadFiles = function (files) { 105 | files.length && angular.forEach(files, function (file) { 106 | doUpload(file); 107 | }); 108 | }; 109 | 110 | function doUpload(file) { 111 | if (file && !file.$error && scope.url) { 112 | var options = { 113 | url: scope.url, 114 | file: {} 115 | }; 116 | options.file[scope.form.fileName || 'file'] = file; 117 | file.upload = Upload.upload(options); 118 | 119 | file.upload.then(function (response) { 120 | $timeout(function () { 121 | file.result = response.data; 122 | }); 123 | var result = scope.form.post ? scope.form.post(response.data) : response.data; 124 | ngModel.$setViewValue(result); 125 | ngModel.$commitViewValue(); 126 | }, function (response) { 127 | if (response.status > 0) { 128 | scope.errorMsg = response.status + ': ' + response.data; 129 | } 130 | }); 131 | 132 | file.upload.progress(function (evt) { 133 | file.progress = Math.min(100, parseInt(100.0 * 134 | evt.loaded / evt.total)); 135 | }); 136 | } 137 | } 138 | 139 | scope.validateField = function () { 140 | if (scope.uploadForm.file && scope.uploadForm.file.$valid && scope.picFile && !scope.picFile.$error) { 141 | console.log('singlefile-form is invalid'); 142 | } else if (scope.uploadForm.files && scope.uploadForm.files.$valid && scope.picFiles && !scope.picFiles.$error) { 143 | console.log('multifile-form is invalid'); 144 | } else { 145 | console.log('single- and multifile-form are valid'); 146 | } 147 | }; 148 | scope.submit = function () { 149 | if (scope.uploadForm.file && scope.uploadForm.file.$valid && scope.picFile && !scope.picFile.$error) { 150 | scope.uploadFile(scope.picFile); 151 | } else if (scope.uploadForm.files && scope.uploadForm.files.$valid && scope.picFiles && !scope.picFiles.$error) { 152 | scope.uploadFiles(scope.picFiles); 153 | } 154 | }; 155 | scope.$on('schemaFormValidate', scope.validateField); 156 | scope.$on('schemaFormFileUploadSubmit', scope.submit); 157 | } 158 | }; 159 | }]); 160 | -------------------------------------------------------------------------------- /upload_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saburab/angular-schema-form-nwp-file-upload/9e0e2771924ed2748bc69f192918f492375e7846/upload_1.png -------------------------------------------------------------------------------- /upload_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saburab/angular-schema-form-nwp-file-upload/9e0e2771924ed2748bc69f192918f492375e7846/upload_2.png -------------------------------------------------------------------------------- /upload_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saburab/angular-schema-form-nwp-file-upload/9e0e2771924ed2748bc69f192918f492375e7846/upload_3.png --------------------------------------------------------------------------------