├── .gitignore ├── CHANGELOG.md ├── HISTORY.md ├── .github ├── FUNDING.yml ├── PULL_REQUEST_TEMPLATE └── ISSUE_TEMPLATE ├── lib └── client │ ├── uploadFileDemo.html │ ├── uploadImageDemo.html │ ├── autoform.js │ ├── fileUpload.html │ └── fileUpload.js ├── .meteorignore ├── package.js ├── LICENCE ├── LICENSE ├── .versions ├── CONTRIBUTING.md ├── versions.json ├── CODE_OF_CONDUCT.md └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .npm 2 | .DS_Store 3 | .eslintcache 4 | node_modules -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | For full changelog see [releases on GitHub](https://github.com/veliovgroup/meteor-autoform-file/releases) -------------------------------------------------------------------------------- /HISTORY.md: -------------------------------------------------------------------------------- 1 | For full package history see [releases on GitHub](https://github.com/veliovgroup/meteor-autoform-file/releases) -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: dr-dimitru 4 | custom: https://paypal.me/veliovgroup 5 | -------------------------------------------------------------------------------- /lib/client/uploadFileDemo.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/client/uploadImageDemo.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.meteorignore: -------------------------------------------------------------------------------- 1 | .github 2 | .gitignore 3 | .npm 4 | .DS_Store 5 | .eslintcache 6 | node_modules 7 | CHANGELOG.md 8 | CODE_OF_CONDUCT.md 9 | CONTRIBUTING.md 10 | HISTORY.md 11 | LICENCE 12 | LICENSE 13 | README.md -------------------------------------------------------------------------------- /lib/client/autoform.js: -------------------------------------------------------------------------------- 1 | import { AutoForm } from 'meteor/aldeed:autoform'; 2 | 3 | AutoForm.addInputType('fileUpload', { 4 | template: 'afFileUpload', 5 | valueOut() { 6 | return this.val(); 7 | } 8 | }); 9 | 10 | AutoForm._globalHooks.onSuccess.push(function (type) { 11 | if (type === 'insert') { 12 | try { 13 | if (this.template) { 14 | this.template.$('[data-reset-file]').click(); 15 | } 16 | } catch (e) { 17 | // we're good here 18 | } 19 | } 20 | }); 21 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE: -------------------------------------------------------------------------------- 1 | Thank you for contribution. Before you go: 2 | 1. Make sure you're using `spaces` for indentation 3 | 2. Make sure all new code is documented in-code-docs 4 | 3. Make sure new features, or changes in behavior is documented in README.md 5 | 4. Make sure this PR was previously discussed, if not create new issue ticket for your PR 6 | 5. Give an expressive description what you have changed/added and why 7 | 8 | Thank you for making this package better :) 9 | 10 | ## Do not forget to get rid of this default message -------------------------------------------------------------------------------- /package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | name: 'ostrio:autoform-files', 3 | summary: 'File upload for AutoForm using ostrio:files', 4 | description: 'File upload for AutoForm using ostrio:files', 5 | version: '2.5.2', 6 | git: 'https://github.com/veliovgroup/meteor-autoform-file.git' 7 | }); 8 | 9 | Package.onUse((api) => { 10 | api.versionsFrom(['2.0', '3.0-rc.0']); 11 | 12 | api.use([ 13 | 'check', 14 | 'ecmascript', 15 | 'mongo', 16 | 'reactive-var', 17 | 'templating@1.4.2', 18 | 'aldeed:autoform@7.0.0 || 8.0.0-rc', 19 | 'ostrio:files@2.2.0 || 3.0.0-beta.6' 20 | ], 'client'); 21 | 22 | api.addFiles([ 23 | 'lib/client/autoform.js', 24 | 'lib/client/fileUpload.html', 25 | 'lib/client/fileUpload.js', 26 | 'lib/client/uploadImageDemo.html', 27 | 'lib/client/uploadFileDemo.html' 28 | ], 'client'); 29 | }); 30 | -------------------------------------------------------------------------------- /lib/client/fileUpload.html: -------------------------------------------------------------------------------- 1 | 32 | -------------------------------------------------------------------------------- /LICENCE: -------------------------------------------------------------------------------- 1 | DISCLAIMER: THIS IS ORIGINAL LICENSE OF autoform PACKAGE BY Benjamin Peter Jones 2 | WE HAVE BEEN INSPIRED BY HIS WORK, BUT ALMOST NONE OF THE ORIGINAL CODEBASE IS LEFT IN THIS PROJECT. 3 | 4 | The MIT License (MIT) 5 | 6 | Copyright (c) 2015 Benjamin Peter Jones (ben.p.js@gmail.com) 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy 9 | of this software and associated documentation files (the "Software"), to deal 10 | in the Software without restriction, including without limitation the rights 11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | copies of the Software, and to permit persons to whom the Software is 13 | furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in all 16 | copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 | SOFTWARE. 25 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE: -------------------------------------------------------------------------------- 1 | ### I'm having an issue: 2 | - Give an expressive description of what is went wrong 3 | - Version of `ostrio:autoform-files` and `ostrio:files` you're experiencing this issue 4 | - Version of `Meteor` you're experiencing this issue 5 | - Where this issue appears? OS (Mac/Win/Linux)? Browser name and its version? 6 | - Is it *Client* or *Server* issue? 7 | - Post *Client* and/or *Server* logs with enabled `debug` option, you can enable "debug" mode in [*Constructor*](https://github.com/veliovgroup/Meteor-Files/wiki/Constructor) 8 | 9 | ### I had an issue and I've solved it on my own: 10 | - Provide a description of steps that you've followed to solve the problem. 11 | - Provide links to websites and/or pages with the information that helped you (*if there are any*). 12 | 13 | ### I have a suggestion: 14 | - Describe your feature / request 15 | - How you going to use it? Give a usage example(s) 16 | 17 | ### Documentation is missing something or incorrect (have typos, etc.): 18 | - Give an expressive description what you have changed/added and why 19 | - Make sure you're using correct markdown markup 20 | - Make sure all code blocks starts with tripple ``` (*backtick*) and have a syntax tag, for more read [this docs](https://help.github.com/articles/creating-and-highlighting-code-blocks/#syntax-highlighting) 21 | - Post your addition/changes in issue, we will manage it 22 | 23 | ## Thank you, and do not forget to get rid of this default message 24 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2024, dr.dimitru (Dmitry A.; Veliov Group, LLC) 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, 5 | with or without modification, are permitted provided 6 | that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the 9 | above copyright notice, this list of conditions 10 | and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the 13 | above copyright notice, this list of conditions and 14 | the following disclaimer in the documentation and/or 15 | other materials provided with the distribution. 16 | 17 | 3. Neither the name of the copyright holder nor the 18 | names of its contributors may be used to endorse or 19 | promote products derived from this software without 20 | specific prior written permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 23 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 26 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 28 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | -------------------------------------------------------------------------------- /.versions: -------------------------------------------------------------------------------- 1 | aldeed:autoform@7.0.0 2 | allow-deny@1.1.1 3 | babel-compiler@7.10.5 4 | babel-runtime@1.5.1 5 | base64@1.0.12 6 | binary-heap@1.0.11 7 | blaze@2.6.0 8 | blaze-tools@1.1.0 9 | boilerplate-generator@1.7.2 10 | caching-compiler@1.2.2 11 | caching-html-compiler@1.2.0 12 | callback-hook@1.5.1 13 | check@1.3.2 14 | ddp@1.4.1 15 | ddp-client@2.6.1 16 | ddp-common@1.4.0 17 | ddp-server@2.7.0 18 | deps@1.0.12 19 | diff-sequence@1.1.2 20 | dynamic-import@0.7.3 21 | ecmascript@0.16.8 22 | ecmascript-runtime@0.8.1 23 | ecmascript-runtime-client@0.12.1 24 | ecmascript-runtime-server@0.11.0 25 | ejson@1.1.3 26 | fetch@0.1.4 27 | geojson-utils@1.0.11 28 | html-tools@1.1.0 29 | htmljs@1.1.1 30 | id-map@1.1.1 31 | inter-process-messaging@0.1.1 32 | jquery@1.11.10 33 | livedata@1.0.18 34 | logging@1.3.3 35 | meteor@1.11.5 36 | minimongo@1.9.3 37 | modern-browsers@0.1.10 38 | modules@0.20.0 39 | modules-runtime@0.13.1 40 | momentjs:moment@2.10.6 41 | mongo@1.16.8 42 | mongo-decimal@0.1.3 43 | mongo-dev-server@1.1.0 44 | mongo-id@1.0.8 45 | npm-mongo@4.17.2 46 | observe-sequence@1.0.16 47 | ordered-dict@1.1.0 48 | ostrio:autoform-files@2.5.2 49 | ostrio:cookies@2.7.2 50 | ostrio:files@2.2.0 51 | promise@0.12.2 52 | random@1.2.1 53 | react-fast-refresh@0.2.8 54 | reactive-dict@1.3.1 55 | reactive-var@1.0.12 56 | reload@1.3.1 57 | retry@1.1.0 58 | routepolicy@1.1.1 59 | socket-stream-client@0.5.2 60 | spacebars@1.3.0 61 | spacebars-compiler@1.2.0 62 | templating@1.4.2 63 | templating-compiler@1.4.1 64 | templating-runtime@1.6.0 65 | templating-tools@1.2.0 66 | tracker@1.3.3 67 | typescript@4.9.5 68 | ui@1.0.13 69 | underscore@1.6.0 70 | webapp@1.13.8 71 | webapp-hashing@1.1.1 72 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ### I'm having an issue: 2 | 1. Search [issues](https://github.com/veliovgroup/meteor-autoform-file/issues), maybe your issue is already solved 3 | 2. Before submitting an issue make sure it's only related to `Meteor-Files` package 4 | 3. If your issue is not solved: 5 | - Give an expressive description of what is went wrong 6 | - Version of `ostrio:autoform-files` and `ostrio:files` you're experiencing this issue 7 | - Version of `Meteor` you're experiencing this issue 8 | - Is it *Client* or *Server* issue? 9 | - Post *Client* and/or *Server* logs with enabled `debug` option, you can enable "debug" mode in [*Constructor*](https://github.com/veliovgroup/Meteor-Files/wiki/Constructor) 10 | 11 | ### I have a suggestion: 12 | 1. PRs are always welcome - [send a PR](https://github.com/veliovgroup/meteor-autoform-file/compare) 13 | 2. If you're can not send a PR for some reason: 14 | - Create a new issue ticket 15 | - Describe your feature / request 16 | - How you going to use it? Give a usage example(s) 17 | 18 | ### Documentation is missing something or incorrect (have typos, etc.): 19 | 1. PRs are always welcome - [send a PR](https://github.com/veliovgroup/meteor-autoform-file/compare) 20 | 2. If you're can not send a PR to docs for some reason: 21 | - Create a new issue ticket 22 | - Give an expressive description what you have changed/added and why 23 | - Make sure you're using correct markdown markup 24 | - Make sure all code blocks starts with triple ``` (*backtick*) and have a syntax tag, for more read [this docs](https://help.github.com/articles/creating-and-highlighting-code-blocks/#syntax-highlighting) 25 | - Post addition/changes as issue ticket, we will manage it -------------------------------------------------------------------------------- /versions.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": [ 3 | [ 4 | "aldeed:autoform", 5 | "4.2.2" 6 | ], 7 | [ 8 | "aldeed:simple-schema", 9 | "1.1.0" 10 | ], 11 | [ 12 | "base64", 13 | "1.0.1" 14 | ], 15 | [ 16 | "blaze", 17 | "2.0.3" 18 | ], 19 | [ 20 | "check", 21 | "1.0.2" 22 | ], 23 | [ 24 | "coffeescript", 25 | "1.0.4" 26 | ], 27 | [ 28 | "ddp", 29 | "1.0.11" 30 | ], 31 | [ 32 | "deps", 33 | "1.0.5" 34 | ], 35 | [ 36 | "ejson", 37 | "1.0.4" 38 | ], 39 | [ 40 | "geojson-utils", 41 | "1.0.1" 42 | ], 43 | [ 44 | "htmljs", 45 | "1.0.2" 46 | ], 47 | [ 48 | "id-map", 49 | "1.0.1" 50 | ], 51 | [ 52 | "jquery", 53 | "1.0.1" 54 | ], 55 | [ 56 | "json", 57 | "1.0.1" 58 | ], 59 | [ 60 | "less", 61 | "1.0.11" 62 | ], 63 | [ 64 | "livedata", 65 | "1.0.11" 66 | ], 67 | [ 68 | "logging", 69 | "1.0.5" 70 | ], 71 | [ 72 | "meteor", 73 | "1.1.3" 74 | ], 75 | [ 76 | "minimongo", 77 | "1.0.5" 78 | ], 79 | [ 80 | "momentjs:moment", 81 | "2.8.4" 82 | ], 83 | [ 84 | "observe-sequence", 85 | "1.0.3" 86 | ], 87 | [ 88 | "ordered-dict", 89 | "1.0.1" 90 | ], 91 | [ 92 | "random", 93 | "1.0.1" 94 | ], 95 | [ 96 | "reactive-var", 97 | "1.0.3" 98 | ], 99 | [ 100 | "retry", 101 | "1.0.1" 102 | ], 103 | [ 104 | "templating", 105 | "1.0.9" 106 | ], 107 | [ 108 | "tracker", 109 | "1.0.3" 110 | ], 111 | [ 112 | "ui", 113 | "1.0.4" 114 | ], 115 | [ 116 | "underscore", 117 | "1.0.1" 118 | ] 119 | ], 120 | "pluginDependencies": [], 121 | "toolVersion": "meteor-tool@1.0.35", 122 | "format": "1.0" 123 | } -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. 6 | 7 | ## Our Standards 8 | 9 | Examples of behavior that contributes to creating a positive environment include: 10 | 11 | * Using welcoming and inclusive language 12 | * Being respectful of differing viewpoints and experiences 13 | * Gracefully accepting constructive criticism 14 | * Focusing on what is best for the community 15 | * Showing empathy towards other community members 16 | 17 | Examples of unacceptable behavior by participants include: 18 | 19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances 20 | * Trolling, insulting/derogatory comments, and personal or political attacks 21 | * Public or private harassment 22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission 23 | * Other conduct which could reasonably be considered inappropriate in a professional setting 24 | 25 | ## Our Responsibilities 26 | 27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 28 | 29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 30 | 31 | ## Scope 32 | 33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. 34 | 35 | ## Enforcement 36 | 37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at info@veliovgroup.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. 38 | 39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. 40 | 41 | ## Attribution 42 | 43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] 44 | 45 | [homepage]: http://contributor-covenant.org 46 | [version]: http://contributor-covenant.org/version/1/4/ 47 | -------------------------------------------------------------------------------- /lib/client/fileUpload.js: -------------------------------------------------------------------------------- 1 | import { Meteor } from 'meteor/meteor'; 2 | import { AutoForm } from 'meteor/aldeed:autoform'; 3 | import { Template } from 'meteor/templating'; 4 | import { ReactiveVar } from 'meteor/reactive-var'; 5 | import { Mongo } from 'meteor/mongo'; 6 | 7 | const defaultInsertOpts = { 8 | meta: {}, 9 | isBase64: false, 10 | transport: 'ddp', 11 | chunkSize: 'dynamic', 12 | allowWebWorkers: true 13 | }; 14 | 15 | Template.afFileUpload.onCreated(function () { 16 | const self = this; 17 | if (!this.data) { 18 | this.data = { 19 | atts: {} 20 | }; 21 | } 22 | 23 | // primary method: use dburles:mongo-collection-instances 24 | if (Mongo.Collection.get) { 25 | const mongoCollection = Mongo.Collection.get(this.data.atts.collection); 26 | this.collection = mongoCollection && mongoCollection.filesCollection; 27 | } 28 | 29 | // 1. fallback using global scope 30 | if (!this.collection) { 31 | this.collection = global[this.data.atts.collection]; 32 | } 33 | 34 | // 2. fallback using Meteor.connection / local collections 35 | // if the Meteor release is newer than 2016 -> use _stores 36 | // else use older _mongo_livedata_collections 37 | // see https://github.com/meteor/meteor/pull/5845 38 | if (!this.collection) { 39 | const storedCollection = Meteor.connection._stores[this.data.atts.collection]; 40 | this.collection = (storedCollection && storedCollection._getCollection) 41 | ? storedCollection._getCollection().filesCollection 42 | : Meteor.connection._mongo_livedata_collections[this.data.atts.collection]; 43 | } 44 | 45 | if (!this.collection) { 46 | throw new Meteor.Error(404, `[meteor-autoform-files] No collection found by name "${this.data.atts.collection}"`, 47 | 'Collection\'s name is case-sensetive. Please, make sure you\'re using right collection name.'); 48 | } 49 | 50 | this.uploadTemplate = this.data.atts.uploadTemplate || null; 51 | this.previewTemplate = this.data.atts.previewTemplate || null; 52 | this.accept = this.data.atts.accept || null; 53 | this.insertConfig = Object.assign({}, defaultInsertOpts, this.data.atts.insertConfig || {}); 54 | delete this.data.atts.insertConfig; 55 | 56 | if (!isNaN(this.insertConfig.chunkSize)) { 57 | this.insertConfig.chunkSize = parseInt(this.insertConfig.chunkSize); 58 | } else if (this.insertConfig.chunkSize !== 'dynamic') { 59 | this.insertConfig.chunkSize = 'dynamic'; 60 | } 61 | 62 | this.collectionName = function () { 63 | return self.data.atts.collection; 64 | }; 65 | 66 | this.currentUpload = new ReactiveVar(false); 67 | this.inputName = this.data.name; 68 | this.fileId = new ReactiveVar(this.data.value || false); 69 | this.formId = AutoForm.getFormId(); 70 | return; 71 | }); 72 | 73 | Template.afFileUpload.helpers({ 74 | previewTemplate() { 75 | return Template.instance().previewTemplate; 76 | }, 77 | uploadTemplate() { 78 | return Template.instance().uploadTemplate; 79 | }, 80 | uploadTemplateData() { 81 | const instance = Template.instance(); 82 | const currentUpload = instance.currentUpload.get(); 83 | const { accept } = instance; 84 | 85 | // here we can check for upload template configs, that have been added after 2.1.4 and return either 86 | // an object with "config" merged with "currentUpload" to stay backwards compatible as possible 87 | if (accept) { 88 | const config = { config: { accept } }; 89 | return Object.assign({}, config, currentUpload); 90 | } 91 | 92 | return currentUpload; 93 | }, 94 | currentUpload() { 95 | return Template.instance().currentUpload.get(); 96 | }, 97 | fileId() { 98 | return Template.instance().fileId.get() || this.value; 99 | }, 100 | uploadedFile() { 101 | const template = Template.instance(); 102 | const _id = template.fileId.get() || this.value; 103 | if (typeof _id !== 'string' || _id.length === 0) { 104 | return null; 105 | } 106 | return template.collection.findOne({_id}); 107 | }, 108 | accept() { 109 | return Template.instance().accept; 110 | }, 111 | inputAtts(formContext) { 112 | const { atts } = formContext; 113 | if (!atts) return {}; 114 | delete atts.insertConfig; 115 | return atts; 116 | } 117 | }); 118 | 119 | Template.afFileUpload.events({ 120 | 'click [data-reset-file]'(e, template) { 121 | e.preventDefault(); 122 | template.fileId.set(false); 123 | return false; 124 | }, 125 | 'click [data-remove-file]'(e, template) { 126 | e.preventDefault(); 127 | template.fileId.set(false); 128 | if (template.data.value) { 129 | delete template.data.value; 130 | } 131 | try { 132 | this.remove(); 133 | } catch (error) { 134 | // we're good here 135 | } 136 | return false; 137 | }, 138 | 'change [data-files-collection-upload]'(e, template) { 139 | if (e.currentTarget.files && e.currentTarget.files[0]) { 140 | const opts = Object.assign({}, defaultInsertOpts, template.insertConfig, { 141 | file: e.currentTarget.files[0] 142 | }); 143 | 144 | const upload = template.collection.insert(opts, false); 145 | let ctx; 146 | try { 147 | ctx = AutoForm.getValidationContext(template.formId); 148 | } catch (exception) { 149 | // Fix: "TypeError: Cannot read property '_resolvedSchema' of undefined" 150 | ctx = AutoForm.getValidationContext(); 151 | } 152 | 153 | upload.on('start', function () { 154 | ctx.reset(); 155 | template.currentUpload.set(this); 156 | return; 157 | }); 158 | 159 | upload.on('error', function (error) { 160 | ctx.reset(); 161 | ctx.addValidationErrors([{name: template.inputName, type: 'uploadError', value: error.reason}]); 162 | template.$(e.currentTarget).val(''); 163 | return; 164 | }); 165 | 166 | upload.on('end', function (error, fileObj) { 167 | if (!error) { 168 | if (template) { 169 | template.fileId.set(fileObj._id); 170 | } 171 | } 172 | template.currentUpload.set(false); 173 | return; 174 | }); 175 | 176 | upload.start(); 177 | } 178 | } 179 | }); 180 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![support](https://img.shields.io/badge/support-GitHub-white)](https://github.com/sponsors/dr-dimitru) 2 | [![support](https://img.shields.io/badge/support-PayPal-white)](https://paypal.me/veliovgroup) 3 | [![Mentioned in Awesome ostrio:files](https://awesome.re/mentioned-badge.svg)](https://project-awesome.org/Urigo/awesome-meteor#files) 4 | [![GitHub stars](https://img.shields.io/github/stars/veliovgroup/Meteor-Files.svg)](https://github.com/veliovgroup/Meteor-Files/stargazers) 5 | 6 | 7 | 8 | # Autoform File 9 | 10 | ```shell 11 | # meteor@>=1.9 12 | meteor add ostrio:autoform-files 13 | 14 | # meteor@<1.9 15 | meteor add ostrio:autoform-files@2.2.1 16 | ``` 17 | 18 | ## Description 19 | 20 | Upload and manage files with autoForm via [`ostrio:files`](https://github.com/veliovgroup/Meteor-Files). This package was ported from `yogiben:autoform-file` to use with [`ostrio:files`](https://github.com/veliovgroup/Meteor-Files) instead of the already deprecated CollectionFS. 21 | 22 | ## Quick Start: 23 | 24 | 1. Install `meteor add ostrio:autoform-files` 25 | 2. Install `meteor add ostrio:files`, *if not yet installed* 26 | 3. Add this config to `simpl-schema` NPM package (depending of the language that you are using): 27 | 28 | ```js 29 | SimpleSchema.setDefaultMessages({ 30 | initialLanguage: 'en', 31 | messages: { 32 | en: { 33 | uploadError: '{{value}}', //File-upload 34 | }, 35 | } 36 | }); 37 | ``` 38 | 39 | 4. Create your Files Collection (See [`ostrio:files`](https://github.com/veliovgroup/Meteor-Files)) 40 | 41 | ```js 42 | import { Meteor } from 'meteor/meteor'; 43 | import { FilesCollection } from 'meteor/ostrio:files'; 44 | 45 | const imagesCollection = new FilesCollection({ 46 | collectionName: 'images', 47 | allowClientCode: true, // Required to let you remove uploaded file 48 | onBeforeUpload(file) { 49 | // Allow upload files under 10MB, and only in png/jpg/jpeg formats 50 | if (file.size <= 10485760 && /png|jpg|jpeg/i.test(file.ext)) { 51 | return true; 52 | } 53 | return 'Please upload image, with size equal or less than 10MB'; 54 | } 55 | }); 56 | 57 | if (Meteor.isClient) { 58 | Meteor.subscribe('files.images.all'); 59 | } 60 | 61 | if (Meteor.isServer) { 62 | Meteor.publish('files.images.all', () => { 63 | return imagesCollection.collection.find({}); 64 | }); 65 | } 66 | ``` 67 | 68 | __Note:__ If you don't use Mongo Collection instances (`dburles:mongo-collection-instances`), then the `imagesCollection` variable must be attached to *Global* scope. And has same name (*case-sensitive*) as `collectionName` option passed into `FilesCollection#insert({collectionName: 'images'})` method, `images` in our case. 69 | 70 | To start using `dburles:mongo-collection-instances` simply install it: 71 | 72 | ```shell 73 | meteor add dburles:mongo-collection-instances 74 | ``` 75 | 76 | 5. Define your schema and set the `autoform` property like in the example below 77 | 78 | ```js 79 | Schemas = {}; 80 | Posts = new Meteor.Collection('posts'); 81 | Schemas.Posts = new SimpleSchema({ 82 | title: { 83 | type: String, 84 | max: 60 85 | }, 86 | picture: { 87 | type: String, 88 | autoform: { 89 | afFieldInput: { 90 | type: 'fileUpload', 91 | collection: 'images', 92 | uploadTemplate: 'uploadField', // <- Optional 93 | previewTemplate: 'uploadPreview', // <- Optional 94 | insertConfig: { // <- Optional, .insert() method options, see: https://github.com/veliovgroup/Meteor-Files/blob/master/docs/insert.md 95 | meta: {}, 96 | isBase64: false, 97 | transport: 'ddp', 98 | chunkSize: 'dynamic', 99 | allowWebWorkers: true 100 | } 101 | } 102 | } 103 | } 104 | }); 105 | 106 | Posts.attachSchema(Schemas.Posts); 107 | ``` 108 | 109 | The `collection` property must be the same as name of your *FilesCollection* (*case-sensitive*), `images` in our case. 110 | 111 | Generate the form with `{{> quickform}}` or `{{#autoform}}` e.g.: 112 | 113 | ## Insert mode: 114 | 115 | ```handlebars 116 | {{> quickForm id="postsInsertForm" collection="Posts" type="insert"}} 117 | 118 | {{#autoForm id="postsInsertForm" collection="Posts" type="insert"}} 119 | {{> afQuickField name="title"}} 120 | {{> afQuickField name="picture"}} 121 | 122 | {{/autoForm}} 123 | 124 | 125 | 126 | {{#autoForm id="postsInsertForm" collection="Posts" type="insert"}} 127 | {{> afQuickField name="title"}} 128 | {{> afQuickField name="picture" transport="http" allowWebWorkers="false"}} 129 | 130 | {{/autoForm}} 131 | ``` 132 | 133 | ## Update mode: 134 | 135 | ```handlebars 136 | {{#if Template.subscriptionsReady }} 137 | {{> quickForm id="postsUpdateForm" collection="Posts" type="update" doc=getPost}} 138 | {{/if}} 139 | 140 | {{#if Template.subscriptionsReady }} 141 | {{#autoForm id="postsUpdateForm" collection="Posts" type="update" doc=getPost}} 142 | {{> afQuickField name="title"}} 143 | {{> afQuickField name="picture"}} 144 | 145 | {{/autoForm}} 146 | {{/if}} 147 | ``` 148 | 149 | Autoform should be wrapped in `{{#if Template.subscriptionsReady }}` which makes sure that template level subscription is ready. Without it the picture preview won't be shown. You can see update mode example [here](https://github.com/veliovgroup/meteor-autoform-file/issues/9). 150 | 151 | ## Accept configuration 152 | 153 | ### Usage 154 | 155 | You can configure the file selector, to only allow certain types of files using the `accept` property: 156 | 157 | ```js 158 | Schemas.Posts = new SimpleSchema({ 159 | title: { 160 | type: String, 161 | max: 60 162 | }, 163 | picture: { 164 | type: String, 165 | autoform: { 166 | afFieldInput: { 167 | type: 'fileUpload', 168 | collection: 'images', 169 | accept: 'image/*' // or use explicit ext names like .png,.jpg 170 | } 171 | } 172 | } 173 | }); 174 | ``` 175 | 176 | The accept values works makes use of the native HTML `accept` attribute. Read more at the [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#Unique_file_type_specifiers). 177 | 178 | Please read the section on __custom upload templates__ and how to integrate configs like *accept* to your custom template. 179 | 180 | ## Multiple images 181 | 182 | Multiple images — __not fully supported yet__ 183 | 184 | If you want to use an array of images inside you have to define the autoform on on the [schema key](https://github.com/aldeed/meteor-simple-schema#schema-keys) 185 | 186 | ```js 187 | Schemas.Posts = new SimpleSchema({ 188 | title: { 189 | type: String, 190 | max: 60 191 | }, 192 | pictures: { 193 | type: Array, 194 | label: 'Choose file' // <- Optional 195 | }, 196 | 'pictures.$': { 197 | type: String, 198 | autoform: { 199 | afFieldInput: { 200 | type: 'fileUpload', 201 | collection: 'images' 202 | } 203 | } 204 | } 205 | }); 206 | ``` 207 | 208 | ## Custom file preview 209 | 210 | Your custom file preview template data context will be: 211 | 212 | - *file* - fileObj instance 213 | 214 | ```js 215 | ({ 216 | picture: { 217 | type: String, 218 | autoform: { 219 | afFieldInput: { 220 | type: 'fileUpload', 221 | collection: 'images', 222 | previewTemplate: 'myFilePreview' 223 | } 224 | } 225 | } 226 | }); 227 | ``` 228 | 229 | ```handlebars 230 | 233 | ``` 234 | 235 | ## Custom upload template 236 | 237 | Your custom file upload template data context will be: 238 | 239 | - *file* - FS.File instance 240 | - *progress* 241 | - *status* 242 | - *config* an object containing several configs to upload behavior, such as `accept` 243 | - Other fields from [`FileUpload` instance](https://github.com/veliovgroup/Meteor-Files/wiki/Insert-(Upload)#fileupload-methods-and-properties) 244 | 245 | ```js 246 | ({ 247 | picture: { 248 | type: String, 249 | autoform: { 250 | afFieldInput: { 251 | type: 'fileUpload', 252 | collection: 'images', 253 | uploadTemplate: 'myFileUpload' 254 | } 255 | } 256 | } 257 | }); 258 | ``` 259 | 260 | ```handlebars 261 | 274 | ``` 275 | 276 | ### Note on upload configs: 277 | 278 | If you pass any config, like `accept` your upload data won't be falsy anymore, 279 | so you should update your template to the example above and check for each of the given properties. 280 | This is however backwards-compatible and will not break your older templates if you don't need any of the upload config 281 | introduced in > 2.1.4 releases. 282 | 283 | ## Support this project: 284 | 285 | - Upload and share files using [☄️ meteor-files.com](https://meteor-files.com/?ref=github-mail-time-repo-footer) — Continue interrupted file uploads without losing any progress. There is nothing that will stop Meteor from delivering your file to the desired destination 286 | - Use [▲ ostr.io](https://ostr.io?ref=github-mail-time-repo-footer) for [Server Monitoring](https://snmp-monitoring.com), [Web Analytics](https://ostr.io/info/web-analytics?ref=github-mail-time-repo-footer), [WebSec](https://domain-protection.info), [Web-CRON](https://web-cron.info) and [SEO Pre-rendering](https://prerendering.com) of a website 287 | - Star on [GitHub](https://github.com/veliovgroup/meteor-autoform-file) 288 | - Star on [Atmosphere](https://atmospherejs.com/ostrio/autoform-files) 289 | - [Sponsor via GitHub](https://github.com/sponsors/dr-dimitru) — support open source contributions on a regular basis 290 | - [Support via PayPal](https://paypal.me/veliovgroup) — support our open source contributions 291 | --------------------------------------------------------------------------------