Я использую Fine Uploader (v5.0.1) с jQuery, jQuery.validate и jQuery.form плагинами для многополевой формы для новых событий, которые могут иметь от 0 до 2 вложений файлов.Точный загрузчик с вопросами о форме формы
У меня есть работа, но у меня есть несколько вопросов, прежде чем идти дальше.
- Мой клиентский код генерирует один POST-запрос для каждого файла (включая другие элементы формы) плюс один дополнительный запрос POST только для других элементов формы. Итак, если у моей формы есть два вложения файлов, я получаю три запроса POST. Это нормальное поведение? Могу ли я получить все в одном запросе POST?
- Если несколько запросов POST являются обычным явлением, мне нужно будет генерировать какой-то уникальный идентификатор на клиенте до первого запроса POST, поэтому я могу избежать дублирования записей событий в моей базе данных и связать каждую загрузку файла с помощью правильное событие. Если это направление, в котором я должен идти, есть ли примеры такого типа реализации, на которые я могу смотреть?
- Если файлы не прикреплены, я получаю диалоговое окно предупреждения: «Нет файлов для загрузки». Форма может быть отправлена без прикрепленных файлов, поэтому я не хочу указывать пользователю, что он должен прикреплять файлы. Как я могу избавиться от этого диалога?
- В настоящее время я получаю один ответ POST для данных формы плюс один ответ POST для каждого загруженного файла. Есть ли способ обработать только окончательный ответ POST (например, form.onAllComplete)? Что делать, если форма не имеет прикрепленных файлов?
- Я использую одну конечную точку сервера для формы, включая загрузку файлов. Должен ли я использовать две отдельные конечные точки, одну для полей другой формы и одну для загрузки файлов?
Вот моя форма: 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);
?>
Возможно, вы захотите урезать свой вопрос до минимально воспроизводимого примера. –
Не воспроизводится? Вот почему я предоставил ссылку на рабочую форму. – paulr
Ни один из ваших образцов кода не является хорошим кандидатом на инструмент стека для стека, особенно второй. Ни один из них не является исполняемым и не должен быть. Обычно я рекомендую людям забывать, что фрагменты стека существуют, поскольку они редко подходят, и в любом случае существуют альтернативы вне переполнения стека (например, jsbin). –