diff --git a/README.md b/README.md index 10c68e9..9153a5f 100644 --- a/README.md +++ b/README.md @@ -127,8 +127,12 @@ Generate the form with `{{> quickform}}` or `{{#autoform}}` e.g.: 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). -### Multiple images // not fully supported yet -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) +### Multiple uploads + +#### Manual mode + +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/simple-schema-js#schema-keys). +In this mode each file has to be added manually and there is only one file seletable at a time. ```javascript Schemas.Posts = new SimpleSchema({ @@ -152,6 +156,33 @@ Schemas.Posts = new SimpleSchema({ }) ``` +#### Auto mode + +Use `multiple: "multiple",` option, if you want to select multiple files at once and let them be added to the form automatically: + +```javascript +Schemas.Posts = new SimpleSchema({ + title: { + type: String, + max: 60 + }, + pictures: { + type: Array, + label: 'Choose file' // <- Optional + }, + "pictures.$": { + type: String, + autoform: { + afFieldInput: { + type: 'fileUpload', + collection: 'Images', + multiple: "multiple" + } + } + } +}) +``` + ### Custom file preview Your custom file preview template data context will be: diff --git a/lib/client/autoform.js b/lib/client/autoform.js index 1f80616..5e7865e 100644 --- a/lib/client/autoform.js +++ b/lib/client/autoform.js @@ -12,6 +12,8 @@ AutoForm.addInputType('fileUpload', { } }); +// single file + AutoForm._globalHooks.onSuccess.push(function (type) { if (type === 'insert') { try { diff --git a/lib/client/fileUpload.html b/lib/client/fileUpload.html index 4ce48f4..efb3ff0 100644 --- a/lib/client/fileUpload.html +++ b/lib/client/fileUpload.html @@ -24,7 +24,7 @@   {{progress.get}}% {{else}} - + {{/with}} {{/if}} {{/with}} diff --git a/lib/client/fileUpload.js b/lib/client/fileUpload.js index 7948873..64f1488 100644 --- a/lib/client/fileUpload.js +++ b/lib/client/fileUpload.js @@ -4,6 +4,7 @@ import { AutoForm } from 'meteor/aldeed:autoform'; import { Template } from 'meteor/templating'; import { ReactiveVar } from 'meteor/reactive-var'; import { Mongo } from 'meteor/mongo'; +import { Random } from 'meteor/random' const defaultInsertOpts = { meta: {}, @@ -14,6 +15,8 @@ const defaultInsertOpts = { allowWebWorkers: true }; +const queue = new ReactiveVar([]); + Template.afFileUpload.onCreated(function () { const self = this; if (!this.data) { @@ -70,6 +73,18 @@ Template.afFileUpload.onCreated(function () { this.inputName = this.data.name; this.fileId = new ReactiveVar(this.data.value || false); this.formId = this.data.atts.id; + this.multiple = this.data.atts.multiple + + if (this.multiple) { + this.autorun(() => { + const queued = queue.get(); + if (!this.fileId.get() && !this.currentUpload.get() && queued.length > 0) { + const file = queued.shift(); + uploadFile(file, self); + } + }) + } + return; }); @@ -93,6 +108,9 @@ Template.afFileUpload.helpers({ return null; } return template.collection.findOne({_id}); + }, + multiple() { + return Template.instance().multiple } }); @@ -116,44 +134,65 @@ Template.afFileUpload.events({ return false; }, 'change [data-files-collection-upload]'(e, template) { - if (e.currentTarget.files && e.currentTarget.files[0]) { - const opts = Object.assign({}, defaultInsertOpts, template.insertConfig, { - file: e.currentTarget.files[0] - }); - - const upload = template.collection.insert(opts, false); - let ctx; - try { - ctx = AutoForm.getValidationContext(template.formId); - } catch (exception) { - // Fix: "TypeError: Cannot read property '_resolvedSchema' of undefined" - ctx = AutoForm.getValidationContext(); + if (template.multiple && e.currentTarget.files && e.currentTarget.files.length > 1) { + + const formId = AutoForm.getFormId(); + const {minCount} = template; + const {maxCount} = template; + const schema = AutoForm.getFormSchema(formId); + const inputName = template.inputName.split('.')[0]; + const queued = queue.get(); + + for (let i = 0; i< e.currentTarget.files.length; i++) { + const file = e.currentTarget.files[i]; + queued.push(file); + AutoForm.arrayTracker.addOneToField(formId, inputName, schema, minCount, maxCount); } - upload.on('start', function () { - ctx.reset(); - template.currentUpload.set(this); - return; - }); - - upload.on('error', function (error) { - ctx.reset(); - ctx.addValidationErrors([{name: template.inputName, type: 'uploadError', value: error.reason}]); - template.$(e.currentTarget).val(''); - return; - }); - - upload.on('end', function (error, fileObj) { - if (!error) { - if (template) { - template.fileId.set(fileObj._id); - } - } - template.currentUpload.set(false); - return; - }); - - upload.start(); + queue.set(queued) + return void 0 + } + + if (e.currentTarget.files && e.currentTarget.files[0]) { + uploadFile(e.currentTarget.files[0], template) } } }); + +function uploadFile (file, template) { + const opts = Object.assign({}, defaultInsertOpts, template.insertConfig, {file}); + + const upload = template.collection.insert(opts, false); + let ctx; + try { + ctx = AutoForm.getValidationContext(template.formId); + } catch (exception) { + // Fix: "TypeError: Cannot read property '_resolvedSchema' of undefined" + ctx = AutoForm.getValidationContext(); + } + + upload.on('start', function () { + ctx.reset(); + template.currentUpload.set(this); + return; + }); + + upload.on('error', function (error) { + ctx.reset(); + ctx.addValidationErrors([{name: template.inputName, type: 'uploadError', value: error.reason}]); + template.$("[data-files-collection-upload]").val(''); + return; + }); + + upload.on('end', function (error, fileObj) { + if (!error) { + if (template) { + template.fileId.set(fileObj._id); + } + } + template.currentUpload.set(false); + return; + }); + + upload.start(); +}