Cart Buy Licenses Contact Support Login/Register
v 1.8.6
v 1.8.6
Overview Examples Docs Source Download

File question - delayed upload

Postpone file upload until survey is completed. Chosen files are stored in the temporary local storage and sent on server after survey completed.


                        
        
            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://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script>
<script src="https://surveyjs.azureedge.net/1.8.6/survey.ko.js"></script>
<link href="https://surveyjs.azureedge.net/1.8.6/survey.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>