2

I have a user form with a kendo upload control. I need to make sure the upload control has been completed before the user is aloud to submit the form. Uploading a file is just an optional. I will like to have a message to the user if they hit the submit button that lets them know the upload control is still processing. I am thinking of using e.preventDefault on the submit button along with a variable to check if they are still uploading a file. I can set it to false in the upload event and switch it to true in the complete event.

Wanted to see if anyone else had any other ideas?

https://dojo.telerik.com/uXOVuHuC
Jefferson
  • 173
  • 2
  • 12
  • 32

3 Answers3

4

When user start upload file or an upload process was finish, there will be an uid (unique ID) for each file upload. So you can store these uid in an array when the upload is start, and remove the uid when the upload was finished. Then control whether user can submit the form based on whether the uid array is empty. Following is the example:

Create an array variable which use to store uploading file's uid

/* use to store file's uids which are uploading */
let uploadingList = [];

Assuming you want to disable the submit button when submit form was not allowed

/* to update button status */
const syncButtonStatus = () => {
    /* set allow to submit form if the list is empty */
    const canSubmit = !uploadingList.length;

    /* disable the button if not allowed to submit */
    $('#submit-button').prop('disabled', !canSubmit);
};

Create a function to add uid to the list

/* add the uid to the list by uid value */
const addUid = (uid) => {
    const index = uploadingList.indexOf(uid);
    if (index == -1) {
        uploadingList.push(uid);
    }
};

When start upload a file, add the uid to the list and update the button status

/* when start upload of each file */
const startUpload = (upload) => {
    /* add the file uid to the list */
    addUid(upload.files[0].uid);

    /* update the button status */
    syncButtonStatus();
};

Create a function to remove uid from the list

/* remove the uid from the list by uid value */
const removeUid = (uid) => {
    const index = uploadingList.indexOf(uid);
    if (index > -1) {
        uploadingList.splice(index, 1);
    }
};

When an upload process was finished, remove uid from the list and update the button status

/* when an upload process was finished regardless of success or failed */
const finishUpload = (upload) => {
    /* loop through each upload file */
    upload.sender.getFiles().forEach((file) => {
        /* remove their uids from the list */
        removeUid(file.uid)
    });

    /* update the button status */
    syncButtonStatus();
};

Demo:

/* use to store file's uids which are uploading */
let uploadingList = [];

/* to update button status */
const syncButtonStatus = () => {
  /* set allow to submit form if the list is empty */
  const canSubmit = !uploadingList.length;

  /* disable the button if not allowed to submit */
  $('#submit-button').prop('disabled', !canSubmit);


  /* THIS IS NOT PART OF THE FUNCTION! it just for demo to show how the list store the uid */
  $('#list').html(uploadingList.reduce((html, uid) => `${html}<li>${uid}</li>`, ''));
};

/* add the uid to the list by uid value */
const addUid = (uid) => {
  const index = uploadingList.indexOf(uid);
  if (index == -1) {
    uploadingList.push(uid);
  }
};

/* when start upload of each file */
const startUpload = (upload) => {
  /* add the file uid to the list */
  addUid(upload.files[0].uid);

  /* update the button status */
  syncButtonStatus();
};

/* remove the uid from the list by uid value */
const removeUid = (uid) => {
  const index = uploadingList.indexOf(uid);
  if (index > -1) {
    uploadingList.splice(index, 1);
  }
};

/* when an upload process was finished regardless of success or failed */
const finishUpload = (upload) => {
  /* loop through each upload file */
  upload.sender.getFiles().forEach((file) => {
    /* remove their uids from the list */
    removeUid(file.uid)
  });

  /* update the button status */
  syncButtonStatus();
};

$(document).ready(function() {
  $("#photos").kendoUpload({
    async: {
      saveUrl: "https://jsonplaceholder.typicode.com/posts/1",
      removeUrl: "https://jsonplaceholder.typicode.com/posts/1",
      autoUpload: true
    },
    upload: startUpload,
    complete: finishUpload,
  });
});
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2022.2.621/styles/kendo.default-ocean-blue.min.css">
<form>
  <button type="button" id="submit-button">Submit</button>
  <hr />
  <b>Uploading file uid list:</b>
  <ul id="list">
  </ul>
  <input type="file" name="files" id="photos" />
</form>
<script src="https://code.jquery.com/jquery-1.12.3.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2022.2.621/js/angular.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2022.2.621/js/jszip.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2022.2.621/js/kendo.all.min.js"></script>
Stern Chen
  • 303
  • 1
  • 8
  • What if there was any errors should we also add logic to a error event ? – Jefferson Aug 06 '22 at 22:42
  • 1
    If you want to do something specific when an upload error occurs, yes. `complete: finishUpload` will always trigger when an upload process was finished regardless success or failed. – Stern Chen Aug 07 '22 at 11:37
1

I can't post a comment - not enough rep

And this isn't really a question per se

So this isn't really an answer either

An alternative option might be to disable the submit button altogether until something has been uploaded - assuming something must be uploaded

If something doesn't have to be uploaded but can be (ie :optional) then disable the submit button while the uploading is taking place and then re-enable afterwards

Boomer
  • 358
  • 3
  • 11
1

@Boomer is correct, You could disable the submit on the page load

 $("input[type=submit]").prop('disabled', true);

then use kendoUpload event to enable it accordingly, examples:

complete: onComplete,
          upload: onUpload,
            error: onError,
            success: onSuccess
      });
      function onComplete(e) {
         $("input[type=submit]").prop('disabled', false);
      }
      function onSuccess(e) {
        $("input[type=submit]").prop('disabled', false);
      }
      function onUpload(e) {
         $("input[type=submit]").prop('disabled', true);
      }
      function onError(e) {
          $("input[type=submit]").prop('disabled', true);
      }

I think the complete only fires when all active uploads complete so you could use that, as for error or success it just says they fire if one succeeds or fail so assume its one file at a time; but I guess you would want the submit button to still be enabled in that case so the user can submit the files that did manage upload. So if you disable the submit on page load and enable it on any upload event except maybe error and then regardless of what files managed to upload or not in a selection of files, the user can still submit what was uploaded and if they all only failed then as you don't do anything in the error method the button would still be disabled, make sense?

Patrick Hume
  • 2,064
  • 1
  • 3
  • 11
  • 1
    what if you upload multiple files and and one file calls `onSuccess` but the other files are still uploading? I think this will only work for one file at a time. – Jefferson Aug 03 '22 at 20:05
  • yes you make a goo point, added a comment above to the original answer i hope it helps – Patrick Hume Aug 03 '22 at 20:28