Accurate loader with form variant questions

I am using Fine Uploader (v5.0.1) with jQuery, jQuery.validate and jQuery.form multifield form plugins for new events that can have zero to two file attachments.

I have work to do, but I have a few questions before I move on.

  • My client code generates one POST request for each file (including other form elements) plus one additional POST request for other form elements only. So, if my form has two file attachments, I get three POST requests. Is this normal behavior? Can I get everything in one POST request?
  • If multiple POST requests are common, I will need to generate some sort of unique ID on the client prior to the first POST request, so I can avoid duplicate event records in my database and link each file upload with the correct event. If this is the direction I should be going, are there examples of this type of implementation that I can look at?
  • If the files are not connected, I get a warning dialog: "No files to download". The form can be submitted without attachments, so I don't want to tell the user to attach files. How can I get rid of this dialogue?
  • I am currently getting one POST response for form data plus one POST response for each file uploaded. Is there a way to only handle the final POST response (like form.onAllComplete)? What if the form has no attached files?
  • I am using one server endpoint for a form including file uploads. Should I use two separate endpoints, one for the fields of another form and one for uploading files?

Here is my form: http://www.paulrachal.com/test/fineuploader-test.htm

Here is my code: Client:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0">
    <title>New Event</title>
    <link rel="stylesheet" href="http://code.jquery.com/mobile/1.4.0/jquery.mobile-1.4.0.min.css" />
    <script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
    <script src="http://code.jquery.com/mobile/1.4.0/jquery.mobile-1.4.0.min.js"></script>
    <script src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.13.0/jquery.validate.min.js"></script>
    <script src="http://malsup.github.com/jquery.form.js"></script>
    <!-- Fine Uploader -->
    <link rel="stylesheet" href="../css/custom.fineuploader-5.0.1.min.css" />
    <script src="../js/custom.fineuploader-5.0.1.min.js"></script>
    <!-- document.ready -->
    <script type="text/javascript" charset="utf-8">
    $(document).ready(function(){
    <!-- event handlers -->
    // hide the file upload button when the page loads
    $( '#manual-fine-uploader' ).hide();
    // show the file upload button on change in attachments checkbox
    $("#hasattachments").change(function() {
        if ($('#hasattachments:checked').length) {
            $('#manual-fine-uploader').show();
        }
        else {
            $('#manual-fine-uploader').hide();
        }
    })
    <!-- Fine Uploader setup -->
    var manualuploader = $('#manual-fine-uploader').fineUploader({
      request: {
        endpoint: 'fineuploader-test.php'
      },
      form: {
          element: 'new-event'
      },
      template: "qq-template-manual-noedit",
      validation: {
        allowedExtensions: ['txt', 'pdf'],
        itemLimit: 2,
        sizeLimit: 256000 // 250 kB = 250 * 1024 bytes
      },
      autoUpload: false
    });
    <!-- form validation -->
    // setup form validation on the form element
    $("#new-event").validate({
    // validation rules
    rules: {
        description: {
            required: {
                depends: function(element) {
                  if ( $("input[name='eventtype']:checked").val() == "3" || $("input[name='eventtype']:checked").val() == "4" || $("input[name='eventtype']:checked").val() == "5" )
                  return true;
                }
            }
        },
    },
    // validation error messages
    messages: {
        description: "Please enter a description"
    },
    // submit handler
    submitHandler: function(form) {
      $("#send").attr("value", "Sending...");
      $(form).ajaxSubmit({
        target: "#response",
        dataType: "json",
        success: function processJson(response) {
            if (response.success)
            {
                $(form).slideUp("fast");
                $("#response").html("<span class='success'>" + response.success + "</span>").hide().slideDown("fast");
            } // end if
            else if (response.failure)
            {
                $("#response").empty();
                $(".error").removeClass("error");
                $errors = response.failure;
                for ($i = 0; $i < $errors.length; $i++) {
                    $error = $errors[$i];
                    $.each($error, function(key, value) {
                        // append error text to div#response
                        $("#response").append("<li class='failure'>" + value + "</li>").hide();
                        // set form elements based on the error
                        switch(key) {
                            case "description-isempty":
                                $("#description").addClass("error");
                                break;
                            case "eventname-isempty":
                                $("#eventname").addClass("error");
                                break;
                            case "eventtype-isinvalid":
                                $("#eventtype-input").addClass("error");
                                break;
                            default:
                                // default statements if no cases are true
                        } // end switch
                    }); // end $.each
                } // end for
                $("#response").addClass("failure");
                $("#response").slideDown("fast");
                $("html, body").animate({ scrollTop: 0 }, "fast");
            } // end else if
        } // end processJson
      });
      return false;
    }
    }); // end #new-event.validate
    <!-- validate individual fields on change -->
    // #description
    $('#description').on('change', function() {
        $('#new-event').validate().element('#description');
    });
    }); // end document.ready
    </script>
    <!-- Fine Uploader Template -->
    <script type="text/template" id="qq-template-manual-noedit">
    <div class="qq-uploader-selector qq-uploader">
        <div class="qq-upload-drop-area-selector qq-upload-drop-area" qq-hide-dropzone>
            <span>Drop files here to upload</span>
        </div>
        <div class="qq-upload-button-selector qq-upload-button">
            <div>Browse...</div>
        </div>
        <span class="qq-drop-processing-selector qq-drop-processing">
            <span>Processing dropped files...</span>
            <span class="qq-drop-processing-spinner-selector qq-drop-processing-spinner"></span>
        </span>
        <ul class="qq-upload-list-selector qq-upload-list">
            <li>
                <div class="qq-progress-bar-container-selector">
                    <div class="qq-progress-bar-selector qq-progress-bar"></div>
                </div>
                <span class="qq-upload-spinner-selector qq-upload-spinner"></span>
                <span class="qq-upload-file-selector qq-upload-file"></span>
                <span class="qq-upload-size-selector qq-upload-size"></span>
                <a class="qq-upload-cancel-selector qq-upload-cancel" href="#">Cancel</a>
                <span class="qq-upload-status-text-selector qq-upload-status-text"></span>
            </li>
        </ul>
    </div>
    </script>
    <!-- styles -->
    <style type="text/css">
    .qq-upload-button-selector {
        background: #0080FF;
    }
    #response {
      margin-bottom: 20px;
      text-align: center;
    }
    #response .success {
      color: #08a300;
    }
    #response .failure {
      color: #dc0000;
    }
    div.failure {
      background-color: #FF0;
    }
    .error {
        border: 2px solid red;
    }
    input.error {
        border: 2px solid red;
    }
    select.error {
        border: 2px solid red;
    }
    </style>
  </head>
  <body>
    <!-- new-event-form -->
    <div id="new-event-form" data-role="page">
    <!-- header -->
    <div data-role="header"><h1>NEW EVENT</h1></div>
    <div class="content" data-role="content">
    <div id="response"></div>
    <form id="new-event" action="fineuploader-test.php" method="post">
    <div data-role="fieldcontain">
        <fieldset data-role="controlgroup">
            <legend>Event Type:</legend>
            <div id="eventtype-input">
                <input type="radio" name="eventtype" id="eventtype_1" value="1" checked="checked" />
                <label for="eventtype_1">Ride</label>

                <input type="radio" name="eventtype" id="eventtype_2" value="2" />
                <label for="eventtype_2">Clinic</label>

                <input type="radio" name="eventtype" id="eventtype_3" value="3" />
                <label for="eventtype_3">Social Event</label>

                <input type="radio" name="eventtype" id="eventtype_4" value="4" />
                <label for="eventtype_4">Meeting</label>

                <input type="radio" name="eventtype" id="eventtype_5" value="5" />
                <label for="eventtype_5">Non-Club Event</label>
            </div>
       </fieldset>
    </div>
    <div data-role="fieldcontain">
        <label for="eventname">Event Name:</label>
        <input type="text" name="eventname" id="eventname" value="" maxlength="40" required />
    </div>
    <div id="descriptioninput" data-role="fieldcontain">
        <label for="description">Description:</label>
        <input type="text" name="description" id="description" value="" maxlength="40"  />
    </div>
    <div id="attachments" data-role="fieldcontain">
        <fieldset data-role="controlgroup">
            <legend>Attachments:</legend>
                <input type="checkbox" name="hasattachments" id="hasattachments" value="1" />
                <label for="hasattachments">Attachments</label>
        </fieldset>
    </div>
    <div id="manual-fine-uploader">Browse...</div>
        <div class="ui-body ui-body-b">
        <fieldset class="ui-grid-a">
            <div class="ui-block-a"><input type="reset" data-theme="d" value="Cancel"></div>
            <div class="ui-block-b"><input type="submit" data-theme="a" value="Submit"></div>
        </fieldset>
        </div>
    </form>
    </div> <!-- /content -->
    </div> <!-- /page -->
  </body>
</html>

      

Server:

<?php

// get values from POST request
$eventtype = $_POST['eventtype'];           // eventtype field
$eventname = $_POST['eventname'];           // eventname field
$description = $_POST['description'];       // description field
$hasattachments = $_POST['hasattachments']; // hasattachments field
$qqfile = $_POST['qqfile'];                 // file upload field
$qquuid = $_POST['qquuid'];                 // file upload uuid
$qqfilename = $_POST['qqfilename'];         // file upload filename

// include the upload handler class
require_once "handler.php";
// initialize errors array
$errors = array();
// validate elements
// eventtype
$eventtypes = array_flip(array('1', '2', '3', '4', '5'));
if (!isset($eventtypes[$eventtype])) $errors = addError("eventtype-isinvalid");
// eventname
$eventname = filter_var($eventname, FILTER_SANITIZE_STRING);
if(empty($eventname)) $errors = addError("eventname-isempty");
// description
$description = filter_var($description, FILTER_SANITIZE_STRING);
if (empty($description)) $errors = addError("description-isempty");
// file uploads
if ($hasattachments == 1) uploadFiles();
// functions
// add error
function addError($error) {
    switch ($error)
    {
        case "description-isempty":
            $errors[] = array("description-isempty" => "Please enter a description.");
            break;
        case "eventname-isempty":
            $errors[] = array("eventname-isempty" => "Please enter an event name.");
            break;
        case "eventtype-isinvalid":
            $errors[] = array("eventtype-isinvalid" => "Please select an event type.");
            break;
    } // end switch($error)
    return $errors;
} // end function addError()
// file uploads
function uploadFiles() {
    $uploader = new UploadHandler();
    // specify the list of valid extensions
    $uploader->allowedExtensions = array("txt", "pdf");
    // specify max file size in bytes
    $uploader->sizeLimit = 250 * 1024; // 250 kB
    // specify the input name set in the javascript.
    $uploader->inputName = "qqfile"; // matches Fine Uploader default inputName value by default
    // specify the folder to temporarily save parts to use the chunking/resume feature
    $uploader->chunksFolder = "chunks";
    $method = $_SERVER["REQUEST_METHOD"];
    if ($method == "POST") {
        header("Content-Type: text/plain");
        // call handleUpload() with the name of the folder, relative to PHP getcwd()
        $result = $uploader->handleUpload("uploads/");
        // get the name used for uploaded file
        $result["uploadName"] = $uploader->getUploadName();
    } // end if
} // end function uploadFiles()

// return response
if (!empty($errors)) $response = array("failure" => $errors);
else $response = array("success" => "Success! Your event has been posted.");
echo json_encode($response);

?>

      

+3


source to share


1 answer


Answering your questions in order:



  • Precise uploader sends each file in a separate request and there is no way to change this.
  • Fine Uploader already generates a unique identifier (UUID) for each file. This ID is sent with the download request. If you would like to send additional data for a file, you can do so using the setParams

    API
    method . This will send additional custom options of your choice along with the file. You can specify new parameters for all files or for a specific file.
  • In form mode, Fine Uploader intercepts the submit request and sends files (files) and all form fields via ajax / XHR. It currently expects at least one file to be selected, since form fields are submitted as parameters for each file selected. The absence of the selected files means that in the current state the form fields cannot be submitted. To do this, you need to make adjustments to the internal code of Fine Uploader. You can get around this by not using form mode. Instead, you will need to submit the form data in one request, and then pass Fine Uploader to any selected files via the API.
  • The exact loader should intercept the form submit, so there should only be one response per file. Form fields are sent with every file.
  • This might be the required approach if you want to make the file field optional for your users.
+2


source







All Articles