In essence, file uploading is done via Ajax. Each time the send() function is executed, an Ajax POST request is sent behind the scene. Its url is a script you specify as a value of the upload property.
{view:"uploader", name:"uploader", upload:"server/upload"}
You can write a custom script in your favorite language whether it is PHP, NodeJS, etc. Regardless of the language, the script must contain:
Below NodeJS solution is explained:
In the example below Busboy module is used to parse incoming form data. When Busboy receives a file, the module calls its file event, so you can make use of this event to put the file into the desired catalogue.
First, provide a name for the file and encode it with MD5:
const Busboy = require("busboy");
//...
app.post(root + "/upload",(req,res)=>{
var busboy = new Busboy({ headers: req.headers });
var saveTo = "";
var fileName = "";
busboy.on("file", (field, file, name) => {
fileName = path.basename(name);
fileName = crypto.createHash("md5").update(fileName).digest("hex");
});
// ...
})
Then define a script path to send the file to:
busboy.on("file", (field, file, name) => {
//...
saveTo = path.join(__dirname, "uploads", "photos", fileName);
file.pipe(fs.createWriteStream(saveTo));
});
You must also tune the server response to notify about the result of file uploading.
The script ought to return JSON string that is later processed by Uploader to change the properties of the corresponding file object. Uploader expects an object with two fields:
In the example below the Busboy's finish event is used to return the server response.
app.post(root + "/upload",(req,res)=>{
// ...
busboy.on("finish", function() {
if (saveTo){
let fileName = path.basename(saveTo);
res.send({
status: "server", value: fileName });
}
});
return req.pipe(busboy);
})
Why is it done in the described way? Each file object features status that changes during uploading:
The response is available directly in the send() callback that takes it as a parameter:
$$("uploader1").send(function(response){
if(response)
webix.message(response.status);
webix.message(response.sname);
});
Related sample: Sending on Custom Action
In case of multiple files uploaded at a time, a direct response isn't suitable, as it contains info about one file.
Instead, start a cycle that will get to each file's value:
$$("uploader1").send(function(){
$$("uploader1").files.data.each(function(obj){
var status = obj.status;
var name = obj.name;
if(status === "server"){
var sname = obj.sname; //came from upload script
webix.message("Upload: "+status+" for "+ name+" stored as "+sname );
}
else{
webix.message("Upload: "+status+" for "+ name);
}
})
})
Related sample: Uploader and Form Integration
The same can be done by addressing directly to the uploader datastore, through the data array:
$$("uploader1").send(function(){
var text = f.data.pull[file_id].sname;
webix.message("Test sname: "+ text);
});
Or, in a cycle in case of multiple files uploaded at a time:
for(var i in f.data.pull){
var text = f.data.pull[i].sname;
webix.message("Test sname: "+ text);
}
By default, the value of a button for uploading files is "upload". If you want to set your own name for this button, you need to make use of the inputName property:
{ view:"uploader", inputName:"myFile" }
Back to top