Survey.StylesManager.applyTheme("orange");
var json = { questions: [
{ type: "file", title: "Please upload your files", name: "files", storeDataAsText: false, allowMultiple: true, maxSize: 102400 }
]};
window.survey = new Survey.Model(json);
survey.onComplete.add(function(result) {
document.querySelector('#surveyResult').textContent =
"Result JSON:\n" + JSON.stringify(result.data, null, 3);
});
// This global variable is used for storing choosen files while survey is not completed
var temporaryFilesStorage = {};
survey
.onComplete
.add(function (result) {
// In this handler we upload the files to the server from the temporary storage
// alert("Uploading files");
console.log("Uploading files");
// You need here to wait all files to be uploaded
// And only then show the results
function onFilesUploaded() {
document
.querySelector('#surveyResult')
.textContent = "Result JSON:\n" + JSON.stringify(result.data, null, 3);
}
// temporaryFilesStorage keys are the question names
var questionsToUpload = Object.keys(temporaryFilesStorage);
var uploadedQuestionsCount = 0;
questionsToUpload.forEach(function(questionName) {
var question = survey.getQuestionByName(questionName);
var filesToUpload = temporaryFilesStorage[questionName];
var formData = new FormData();
filesToUpload
.forEach(function (file) {
formData.append(file.name, file);
});
var xhr = new XMLHttpRequest();
xhr.open("POST", "/api/MySurveys/uploadFiles?accessKey=<your_access_key>"); // https://surveyjs.io/api/MySurveys/uploadFiles
xhr.onload = function () {
var data = JSON.parse(xhr.responseText);
question.value = filesToUpload.map(function(file) {
return {
name: file.name,
type: file.type,
content: data[file.name]
};
});
uploadedQuestionsCount++;
// If all files has been uploaded then show the results
if(uploadedQuestionsCount === questionsToUpload.length) {
onFilesUploaded();
}
};
xhr.onerror = function () {
question.value = [{name: "file1", type: "image/jpeg", content: "https://surveyjs.io/Content/Images/examples/image-picker/lion.jpg"}];
uploadedQuestionsCount++;
// If all files has been uploaded then show the results
if(uploadedQuestionsCount === questionsToUpload.length) {
onFilesUploaded();
}
};
xhr.send(formData);
});
// If nothing to upload then show the results
if(0 === questionsToUpload.length) {
onFilesUploaded();
}
});
survey
.onClearFiles
.add(function(survey, options) {
//alert("Clear files: " + options.fileName + " From question: " + options.name);
console.log("Clear files: " + options.fileName + " From question: " + options.name);
// Get temp files for this question
var tempFiles = temporaryFilesStorage[options.name];
var fileInfoToRemove = tempFiles.filter(function(file) { return file.name === options.fileName; })[0];
if(fileInfoToRemove !== undefined) {
var index = tempFiles.indexOf(fileInfoToRemove);
tempFiles.splice(index, 1);
}
// Code to remove temporary stored files
// Write your own code to remove files fron server if they were loaded already
// and then invoke success and allow to proceed further
options.callback("success");
});
survey
.onUploadFiles
.add(function(survey, options) {
// Add files to the temporary storage
if(temporaryFilesStorage[options.name] !== undefined) {
temporaryFilesStorage[options.name].concat(options.files);
} else {
temporaryFilesStorage[options.name] = options.files;
}
// Load previews in base64. Until survey not completed files are loaded temporary as base64 in order to get previews
var question = survey.getQuestionByName(options.name);
var content = [];
options.files.forEach(function(file) {
let fileReader = new FileReader();
fileReader.onload = function(e) {
content = content.concat([
{ name: file.name, type: file.type, content: fileReader.result, file: file }
]);
if (content.length === options.files.length) {
//question.value = (question.value || []).concat(content);
options.callback("success", content.map(function(fileContent) {
return {
file: fileContent.file,
content: fileContent.content
};
}));
}
};
fileReader.readAsDataURL(file);
});
});
function detectIEOrEdge() {
var ua = window.navigator.userAgent;
var msie = ua.indexOf("MSIE ");
var trident = ua.indexOf("Trident/");
var edge = ua.indexOf("Edge/");
return edge > 0 || trident > 0 || msie > 0;
}
survey
.onDownloadFile
.add(function(survey, options) {
//alert("onDownloadFile called. Content is " + options.content);
console.log("onDownloadFile called. Content is " + options.content);
// We simply use content in this sample
if(options.content.indexOf("base64") !== -1 || options.content.indexOf("http") !== -1) {
options.callback("success", options.content);
return;
}
// In real appliaction you need to handle whether content is ready to be used (it's base 64 encoded or an URL)
// And decide whether to leave it as is or do a roundtrip to server for the real preview content url/data
var xhr = new XMLHttpRequest();
xhr.open("GET", "/api/MySurveys/files?name=" + options.content); // "https://surveyjs.io/api/MySurveys/files?name=" + options.content
xhr.onloadstart = function(ev) {
xhr.responseType = "blob";
}
xhr.onload = function () {
var file;
if (detectIEOrEdge()){
file = new Blob([xhr.response], options.fileValue.name, { type: options.fileValue.type });
}
else {
file = new File([xhr.response], options.fileValue.name, { type: options.fileValue.type });
}
var reader = new FileReader();
reader.onload = function(e) {
options.callback("success", e.target.result);
};
reader.readAsDataURL(file);
};
});
survey.data = {
files: [{name: "giraffe.jpg", type: "image/jpeg", content: "https://surveyjs.io/Content/Images/examples/image-picker/giraffe.jpg"}]
};
survey.render("surveyElement");
<!DOCTYPE html>
<html lang="en">
<head>
<title>Postpone file upload until survey is completed. Chosen files are stored in the temporary local storage and sent on server after survey completed., Knockoutjs Survey Library Example</title>
<meta name="viewport" content="width=device-width" />
<script src="https://unpkg.com/knockout@3.5.1/build/output/knockout-latest.js"></script>
<script src="/DevBuilds/survey-knockout/survey.ko.min.js"></script>
<link href="/DevBuilds/survey-knockout/survey.min.css" type="text/css" rel="stylesheet" />
<link rel="stylesheet" href="./index.css">
</head>
<body>
<div id="surveyElement" style="display:inline-block;width:100%;">
</div>
<div id="surveyResult"></div>
<script type="text/javascript" src="./index.js"></script>
</body>
</html>