I have a form to add user and outside it an upload field (dropzone.js) to manage the user's avatar image.
If the form is in edit mode, I know the user's id so I can manage the avatar; but If I want to add an user I Have no id to bind an image to new user.
Actually, I'm using this approach in insert mode:
Others solutions could be:
Are there better solutions?
EDIT 1: This is my code
var ModalAvatar = React.createClass({
propTypes: {
isActive : React.PropTypes.bool.isRequired,
onChange : React.PropTypes.func.isRequired
},
componentDidMount: function() {
var self = this;
Dropzone.autoDiscover = false;
this.dropzone = new Dropzone('#demo-upload', {
parallelUploads: 1,
thumbnailHeight: 120,
thumbnailWidth: 120,
maxFilesize: 3,
filesizeBase: 1000,
});
this.dropzone.on("addedfile", function(file){
// How I could read the added file by $_FILES?
var url = URL.createObjectURL(file);
var formData = new FormData();
formData.append("avatarFile", file);
self.props.onChange("avatarFile", formData);
});
// Now fake the file upload (I took this from dropzone.js)
var minSteps = 6,
maxSteps = 60,
timeBetweenSteps = 100,
bytesPerStep = 100000;
this.dropzone.uploadFiles = function(files) {
var self = this;
for (var i = 0; i < files.length; i++) {
var file = files[i];
var totalSteps = Math.round(Math.min(maxSteps, Math.max(minSteps, file.size / bytesPerStep)));
for (var step = 0; step < totalSteps; step++) {
var duration = timeBetweenSteps * (step + 1);
setTimeout(function(file, totalSteps, step) {
return function() {
file.upload = {
progress: 100 * (step + 1) / totalSteps,
total: file.size,
bytesSent: (step + 1) * file.size / totalSteps
};
self.emit('uploadprogress', file, file.upload.progress, file.upload.bytesSent);
if (file.upload.progress == 100) {
file.status = Dropzone.SUCCESS;
self.emit("success", file, 'success', null);
self.emit("complete", file);
self.processQueue();
}
};
}(file, totalSteps, step), duration);
}
}
}
this.toggle(this.props.isActive);
},
render: function(){
return (
<form action="/upload" className="dropzone needsclick dz-clickable" id="demo-upload">
<div className="dz-message needsclick">
Drop files here or click to upload.
</div>
</form>
)
}
});
var User = React.createClass({
getInitialState: function(){
return {
isActive : false
}
},
onChange: function(formData){
this.setState({
avatarImg: formData
});
},
openModal: function(){
this.setState({
isActive: true
});
},
render: function(){
var model = {
id : this.state.id,
avatarImg : this.state.avatarImg
};
return (
<div className="user">
<div className="user-avatar" onClick={this.openModal}><img src="path"></div>
<Form model={model} onSuccess={this.onSuccess}>
<FieldName value={name} />
<FieldEmail value={email} />
</Form>
<ModalAvatar
isActive={this.state.isActive}
onChange={this.onChange} />
</div>
)
}
});
In User
component, I have a form to add name, email, etc and another div .user-avatar
to show user's avatar and open modal to change it.
My idea is simulate to upload in dropzone, and with "addedfile" event transform file
parameter in something that I can read in php with $_FILES, but with that code $_FILES is empty. What I wrong?
I don't think you should allow the user upload image if he still haven't registered .. You should assign/upload images only when you have the user to do for.
So this mean you don't approach to the server without the user itself or enough data to create the user. You can allow preview on the creation and you don't have to use base64. Read about it, "Javascript upload image". You can simply use URL.createObjectURL()
or simply pass the file reference to a form data
Unless you have a reason to backup the image as soon as the user select it. Don't use the server, what if I canceled the creatino of the user ? You have a picture none will use ? you will start using TTL and stuff like it ? Just. Be lazy when it comes to the server. For your good and the client. Use it when you really need it.