Any code showing the use in Meteor 1.3 with React, jsx files?
No samples for React.
But I can answer on more specific questions.
BTW PRs is always welcome
@maitrid You can try this one. First put the < template > code on your main.html file then try this in your component.jsx:
import React, {Component} from 'react';
import ReactDOM from 'react-dom';
import { Template } from 'meteor/templating';
import { Blaze } from 'meteor/blaze';
export default class ComponentName extends Component {
componentDidMount() {
// Use Meteor Blaze to render
this.view = Blaze.render(Template.uploadForm,
ReactDOM.findDOMNode(this.refs.uploadContainer));
}
componentWillUnmount() {
// Clean up Blaze view
Blaze.remove(this.view);
}
render() {
...
}
}
Template.uploadForm.onCreated(function () {
this.currentUpload = new ReactiveVar(false);
});
Template.uploadForm.helpers({
currentUpload: function () {
return Template.instance().currentUpload.get();
}
});
Template.uploadForm.events({
//....
});
I admit this is not the best code sample for React but let me know if this works for you :)
Is this code should be considered as docs/wiki candidate?
Well it's based from Meteor's docs about using Blaze templates in React. I have tested it and it seems to be working fine. I think you can consider it but I really hope someone else would come and improve this code :)
Got it, will set appropriate tags/labels
Thank you, dsmalicsi! I'll try it. 2 days ago, i took a different route, using the npm package react-dropzone, and then some custom script to handle the upload. i've yet to figure out result handling and progress bar. If this works, that would be great!
Here are my react components (two of them, put the individualfile in a separate file to make it cleaner). One is for the upload portion and one displays each file. I have methods for renaming and deleting on the server where you should do lots of validation.. Also has a progress bar for uploading.
I wasn't able to get this to work with the web workers enabled, but I saw some recent work in that area so it might be fixed, so set that to true if you need it.
This is using the older mixin method for meteor data. I also added console logs so you can put different things in the node events and see whats going on.
Thanks for the awesome work btw!
import React from 'react';
import {Meteor} from 'meteor/meteor';
import IndividualFile from './FIleIndividualFile.jsx';
import {_} from 'meteor/underscore';
const FileUploadComponent = React.createClass({
mixins: [ReactMeteorData],
getInitialState(){
return {
uploading: [],
progress: 0,
inProgress: false
}
},
getMeteorData() {
var handle = Meteor.subscribe('files.all');
return {
docsReadyYet: handle.ready(),
docs: UserFiles.find().fetch()
};
},
uploadIt(e){
"use strict";
e.preventDefault();
let self = this;
if (e.currentTarget.files && e.currentTarget.files[0]) {
// We upload only one file, in case
// there was multiple files selected
var file = e.currentTarget.files[0];
if (file) {
let uploadInstance = UserFiles.insert({
file: file,
meta: {
locator: self.props.fileLocator,
userId: Meteor.userId()
},
streams: 'dynamic',
chunkSize: 'dynamic',
allowWebWorkers: false
}, false);
self.setState({
uploading: uploadInstance,
inProgress: true
});
uploadInstance.on('start', function () {
console.log('Starting');
});
uploadInstance.on('end', function (error, fileObj) {
console.log('On end File Object: ', fileObj);
});
uploadInstance.on('uploaded', function (error, fileObj) {
console.log('uploaded: ', fileObj);
//remove the filename from the upload box
self.refs['fileinput'].value = '';
self.setState({
uploading: [],
progress: 0,
inProgress: false
});
});
uploadInstance.on('error', function (error, fileObj) {
console.log('Error during upload: ' + error);
});
uploadInstance.on('progress', function (progress, fileObj) {
console.log('Upload Percentage: ' + progress);
self.setState({
progress: progress
})
});
uploadInstance.start();
}
}
},
showUploads() {
console.log('**********************************', this.state.uploading);
if (!_.isEmpty(this.state.uploading)) {
return <div>
{this.state.uploading.file.name}
<div className="progress progress-bar-default">
<div style={{width: this.state.progress + '%'}} aria-valuemax="100"
aria-valuemin="0"
aria-valuenow={this.state.progress || 0} role="progressbar"
className="progress-bar">
<span className="sr-only">{this.state.progress}% Complete (success)</span>
<span>{this.state.progress}%</span>
</div>
</div>
</div>
}
},
render() {
if (this.data.docsReadyYet) {
'use strict';
let fileCursors = this.data.docs;
let showit = fileCursors.map((aFile, key) => {
// console.log('A file: ', aFile.link(), aFile.get('name'));
let link = UserFiles.findOne({_id: aFile._id}).link();
return <div key={'file' + key}>
<IndividualFile
fileName={aFile.name}
fileUrl={link}
fileId={aFile._id}
fileSize={aFile.size}
/>
</div>
});
return <div>
<div className="row">
<div className="col-md-12">
<p>Upload New File:</p>
<input type="file" id="fileinput" disabled={this.state.inProgress} ref="fileinput"
onChange={this.uploadIt}/>
</div>
</div>
<div className="row m-t-sm m-b-sm">
<div className="col-md-6">
{this.showUploads()}
</div>
<div className="col-md-6">
</div>
</div>
{showit}
</div>
}
else return <div></div>
}
});
const IndividualFile = React.createClass({
propTypes: {
fileName: React.PropTypes.string.isRequired,
fileSize: React.PropTypes.number.isRequired,
fileUrl: React.PropTypes.string,
fileId: React.PropTypes.string.isRequired
},
removeFile(){
"use strict";
let conf = confirm('Are you sure you want to delete the file?') || false;
if (conf == true) {
Meteor.call('RemoveFile', this.props.fileId, function (err, res) {
if (err)
console.log(err);
});
}
},
renameFile(){
"use strict";
let validName = /[^a-zA-Z0-9 \.:\+()\-_%!&]/gi;
let prompt = window.prompt('New file name?', this.props.fileName);
//replace any non valid characters
if (prompt) {
prompt = prompt.replace(validName, '-');
prompt.trim();
}
if (!_.isEmpty(prompt)) {
Meteor.call('RenameFile', this.props.fileId, prompt, function (err, res) {
if (err)
console.log(err);
});
}
},
render() {
return <div className="m-t-sm">
<div className="row">
<div className="col-md-12">
<strong>{this.props.fileName}</strong>
<div className="m-b-sm">
</div>
</div>
</div>
<div className="row">
<div className="col-md-3">
<button onClick={this.renameFile} className="btn btn-outline btn-primary btn-sm">
Rename
</button>
</div>
<div className="col-md-3">
<a href={this.props.fileUrl} className="btn btn-outline btn-primary btn-sm"
target="_blank">View</a>
</div>
<div className="col-md-2">
<button onClick={this.removeFile} className="btn btn-outline btn-danger btn-sm">
Delete
</button>
</div>
<div className="col-md-4">
Size: {this.props.fileSize}
</div>
</div>
</div>
}
});
export default FileUploadComponent;
Hi React users,
Could please any of you take the beast from this thread and send PR to docs? Or at least point me to the right direction.
Sincerely.
@dr-dimitru Sure I can add it, give me a day to add some comments, etc..
@vtocco thank you
OK, added a wiki entry: https://github.com/VeliovGroup/Meteor-Files/wiki/React-Example
@vtocco great, could you send a PR to dev branch, just add this as docs/react-example.md file.
Feel free to add link to docs/toc.md and readme.md
Done, React Integration Example, thanks to @vtocco
@vtocco , I'm waiting for your PR and links in ToC and Readme
@vtocco thank you for great contribution! All docs is merged, updated and published.
Btw, anyone in this thread is tried/interested in WebRTC support for file uploads? Please, take a look on this discussion: https://forums.meteor.com/t/meteor-files-filescollection-webrtc-dc-for-upload/28262
Most helpful comment
Here are my react components (two of them, put the individualfile in a separate file to make it cleaner). One is for the upload portion and one displays each file. I have methods for renaming and deleting on the server where you should do lots of validation.. Also has a progress bar for uploading.
I wasn't able to get this to work with the web workers enabled, but I saw some recent work in that area so it might be fixed, so set that to true if you need it.
This is using the older mixin method for meteor data. I also added console logs so you can put different things in the node events and see whats going on.
Thanks for the awesome work btw!