带有表单选项问题的Fine Uploader

时间:2014-12-05 22:05:44

标签: php jquery jquery-validate fine-uploader jquery-forms-plugin

我正在使用Fine Uploader(v5.0.1)和jQuery,jQuery.validate和jQuery.form插件,用于新事件的多字段表单,可以有零到两个文件附件。

我有它的工作,但在我走得更远之前我有几个问题。

  1. 我的客户端代码为每个文件(包括其他表单元素)生成一个POST请求,另外只为其他表单元素生成一个POST请求。所以,如果我的表单有两个文件附件,我收到三个POST请求。这是正常的行为吗?我可以在一个POST请求中获取所有内容吗?
  2. 如果多个POST请求是正常行为,我将不得不在第一个POST请求之前在客户端生成某种唯一标识符,这样我就可以避免在我的数据库中重复事件记录并将每个文件上传与正确的事件。如果这是我需要的方向,那么我可以看一下这种实现的例子吗?
  3. 如果没有附加文件,我会收到一个警告对话框:“没有要上传的文件。”表单可以在没有文件附件的情况下提交,因此我不想向用户暗示他/她必须附加文件。我怎样才能摆脱这个对话?
  4. 我目前正在为表单数据获取一个POST响应,并为每个上传的文件获得一个POST响应。有没有办法只处理最终的POST响应(例如,form.onAllComplete)?如果表单没有文件附件怎么办?
  5. 我正在为表单使用一个服务器端点,包括文件上传。我应该使用两个单独的端点,一个用于其他表单字段,一个用于文件上载?
  6. 以下是我的表单:http://www.paulrachal.com/test/fineuploader-test.htm

    这是我的代码: 客户端:

    <!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>
    

    服务器:

    <?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's 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's 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);
    
    ?>
    

1 个答案:

答案 0 :(得分:2)

按顺序回答您的问题:

  1. Fine Uploader在单独的请求中发送每个文件,并且无法更改此内容。
  2. Fine Uploader已为每个文件生成唯一ID(UUID)。此ID随上载请求一起发送。如果要为文件发送其他数据,可以通过setParams API method执行此操作。这将发送您选择的其他自定义参数以及文件。您可以为所有文件或特定文件指定新的参数。
  3. 在表单模式下,Fine Uploader拦截提交请求,并通过ajax / XHR发送文件和所有表单字段。目前,它期望至少选择一个文件,因为表单字段作为每个所选文件的参数发送。缺少选定的文件意味着,在当前状态下,无法发送表单字段。更改此项将需要调整Fine Uploader的内部代码。您可以通过不使用表单模式来解决此问题。相反,您需要在一个请求中提交表单数据,然后让Fine Uploader通过API发送任何选定的文件。
  4. Fine Uploader应截取表单提交,因此每个文件只应有一个响应。表单字段随每个文件一起发送。
  5. 如果您希望为用户选择文件字段,则可能是必需的方法。