3

I searched the internet and found this JavaScript and jQuery template for a file upload progress bar that works 100% fine(given the fact that you only use one form input).

My situation is that I need to pass one file and 4 other inputs like text and select to a Controller Action. The action works fine. My problem is to pass all these values through ajax to the Action whilst maintaining the progress bar functionality.

Action Parameters

[HttpPost]
public ActionResult Add_Attachment_to_Process(int id, int Department_id, HttpPostedFileBase Attachment, string sel_checkTask, string cbx_checkTask = null)

HTML

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>

<form method="post" enctype="multipart/form-data" action="/Processes/Add_Attachment_to_Process" id="myform">
    <input type="file" id="media" name="file" />


    <div class="input-group mb-3">
        <div class="input-group-prepend">
            <div class="input-group-text">
                <input type="checkbox" aria-label="Checkbox for following text input" id="cbx_checkTask" name="cbx_checkTask">
                <span id="span_checkTask">Link Task</span>
            </div>
        </div>
        <select class="form-control" id="sel_checkTask" name="sel_checkTask" style="width : 700px;" disabled>
            @foreach (var t in Model.User_Tasks)
            {
                <option value="@t.Task_Discription">@t.Task_Discription - @t.Key_Terms</option>
            }
        </select>
    </div>

    <input id="id" name="id" value="@ViewBag.process_id " />
    <input id="Department_id" name="Department_id" value="@ViewBag.Department_id" />

    <input type="submit" />
</form>

<div class="progress" style="width:40%">
    <div id="uploadprogressbar" class="progress-bar" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" style="width:0%">
        0%
    </div>
</div>

JavaScript

$(document).ready(function () {
        $("#myform").on('submit', function (event) {
            event.preventDefault();

            var formData = new FormData($("#myform")[0]);

            $.ajax({
                xhr: function () {
                    var xhr = new window.XMLHttpRequest();
                    xhr.upload.addEventListener('progress', function (e) {

                        if (e.lengthComputable) {

                            console.log('Bytes Loaded: ' + e.loaded);
                            console.log('Total Size: ' + e.total);
                            console.log('Percentage Uploaded: ' + ((e.loaded / e.total) * 100) + '%');

                            var percent = Math.round((e.loaded / e.total) * 100);

                            $("#uploadprogressbar").html(percent + '%');
                            $("#uploadprogressbar").width(percent + '%');
                        }

                    });
                    return xhr;
                },
                type: 'POST',
                url: '/Processes/Add_Attachment_to_Process',
                data: formData,
                processData: false,
                contentType: false,
                success: function () {
                    alert('File Uploaded');
                },
                error: function (xhr, status, error) {
                    var errorMessage = xhr.status + ': ' + xhr.statusText;
                    alert('Error - ' + errorMessage);
                }
            });
        });
    });
9
  • What is the problem? Commented Jan 14, 2020 at 6:32
  • When I use multiple inputs, the progress bar works, but the action is not called. Commented Jan 14, 2020 at 6:35
  • what is the result of 'formData'? Are you using .net core? Commented Jan 14, 2020 at 6:41
  • No I am not using core.Please advise how to get the result of 'formData'. Commented Jan 14, 2020 at 6:48
  • add 'console.log(formData )' below 'var formData = new FormData($("#myform")[0]);' Commented Jan 14, 2020 at 6:49

1 Answer 1

3

AS per the discussion above, try this sort of pattern to better see what values are not being sent

let f = new FormData();
    f.append('id', getYouFormValue("id"));
    f.append('sel_checkTask', getYouFormValue("sel_checkTask"));
    f.append('cbx_checkTask ', getYouFormValue("cbx_checkTask "));
    if (form.File) {
        f.append('File', getYouFormValue("file"));
    }
    const requestOptions = {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: f
    }

    return fetch(`/Processes/Add_Attachment_to_Process`, requestOptions)
        .then(handleResponse)
        .then(result => {
           //do stuff
        });

function handleResponse(response) {
    return response.text().then(text => {
        const data = text && JSON.parse(text);
        if (!response.ok) {
            if (response.status === 401) {
                console.log('not logged in')
            }
            const error = (data && data.message) || data.title || response.statusText;
            return Promise.reject(error);

        }
        return data;
    });
}

function getYouFormValue(element){
    let val  = document.getElementById(element);
    if(!val){
        console.log('empty value');
        return null;
    }

    return val;

}

Sign up to request clarification or add additional context in comments.

5 Comments

Wow that's amazing, thank you. One question: Is the getYouFormValue() an existing function or was it user created?
In my application a pass an object into the submit function which I call in the place of that, but you are handling the submit event and thus you would have to create a function to get the form values out of your form.
Thank you for the help. I will definitely consider the above JavaScript code in the next situation. Seems like renaming the file input to the correct name solved the problem.
@JohannesKarsten No problem, consider upvoting the answer if it was helpful please
I will accept this answer as the answer that solved the problem as I am not at a high enough level to upvote yet.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.