post 正常形式与 dropzone
post normal form with dropzone
我遵循 this tutorial 以便将 DropZone 包含在传统表单元素中:
HTML
<form id="my-awesome-dropzone" class="dropzone">
<div class="dropzone-previews"></div> <!-- this is were the previews should be shown. -->
<!-- Now setup your input fields -->
<input type="email" name="username" />
<input type="password" name="password" />
<button type="submit">Submit data and files!</button>
</form>
还有JS
Dropzone.options.myAwesomeDropzone = { // The camelized version of the ID of the form element
// The configuration we've talked about above
autoProcessQueue: false,
uploadMultiple: true,
parallelUploads: 100,
maxFiles: 100,
// The setting up of the dropzone
init: function() {
var myDropzone = this;
// First change the button to actually tell Dropzone to process the queue.
this.element.querySelector("button[type=submit]").addEventListener("click", function(e) {
// Make sure that the form isn't actually being sent.
e.preventDefault();
e.stopPropagation();
myDropzone.processQueue();
});
// Listen to the sendingmultiple event. In this case, it's the sendingmultiple event instead
// of the sending event because uploadMultiple is set to true.
this.on("sendingmultiple", function() {
// Gets triggered when the form is actually being sent.
// Hide the success button or the complete form.
});
this.on("successmultiple", function(files, response) {
// Gets triggered when the files have successfully been sent.
// Redirect user or notify of success.
});
this.on("errormultiple", function(files, response) {
// Gets triggered when there was an error sending the files.
// Maybe show form again, and notify user of error
});
}
}
它工作得很好,除非用户没有提交文件。根据this post,我必须进行一些编辑:
替换简单的
myDropzone.processQueue();
来自
var form = $(this).closest('#dropzone-form');
if (form.valid() == true) {
if (myDropzone.getQueuedFiles().length > 0) {
myDropzone.processQueue();
} else {
myDropzone.uploadFiles([]); //send empty
}
}
现在,正如 Whosebug post "DropZonejs: Submit form without files" 评论中所写,我得到
Uncaught TypeError: Cannot read property 'status' of undefined
所以我检查了 dropzone issue 687,通过替换 dropzone.js 的一些内容来解决这个问题。这一行
ata.append(this._getParamName(i), files[i], files[i].name);
到那些行
if ( typeof files[i] != "undefined" ) {
formData.append(this._getParamName(i), files[i], files[i].name);
} else {
formData.append(this._getParamName(i), "");
}
现在可以正常工作了(使用模型中的正确数据调用控制器)但是发出的调用是 AJAX 调用,我想在我的应用程序的控制器中进行重定向,所以它没有工作。我可以用一个 URL 做一个 Json 作为 return 但我必须在后端保持重定向。
控制器示例:
[HttpPost]
public ActionResult Create(CustomViewModel model)
{
// Here I get Request.IsAjaxRequest() = true when form is submitted
if (ModelState.IsValid)
{
var container = DoSomething();
if (container.HasErrors)
{
SetError(container.ErrorMessage);
return RedirectToAction("Index");
}
}
else
{
SetAlert("ErrorMessage");
}
return RedirectToAction("Index");
}
我该如何解决这个问题?
预先感谢您的帮助
Dropzone 使用 AJAX 上传文件,这意味着页面本身永远不会更改,您不能使用服务器端重定向来更改页面。您唯一的选择是:
- Return 带有 URL 的 JSON 对象并在客户端重定向。
或
- 执行正常的表单回发,而不是 AJAX 上传。为此,您将不得不停止使用 Dropzone。
我遇到了同样的问题,但没有太多时间来解决它。只需要让它尽快工作...
这是我的 2 美分;
您可以从您的控制器return这样的东西;
return Json(new { ErrorMessage = "", RedirectURL = Url.Action("Get", null, new { id = result.Value.id }, Request.Url.Scheme ) });
并从您发布的 JS 中填写此方法:
this.on("successmultiple", function (files, response) {
// Gets triggered when the files have successfully been sent.
// Redirect the user or notify of success.
var errorMessage = response.ErrorMessage;
if (errorMessage.length > 0) {
alert(errorMessage);
}
else {
window.location.replace(response.RedirectURL);
}
};
我遵循 this tutorial 以便将 DropZone 包含在传统表单元素中:
HTML
<form id="my-awesome-dropzone" class="dropzone">
<div class="dropzone-previews"></div> <!-- this is were the previews should be shown. -->
<!-- Now setup your input fields -->
<input type="email" name="username" />
<input type="password" name="password" />
<button type="submit">Submit data and files!</button>
</form>
还有JS
Dropzone.options.myAwesomeDropzone = { // The camelized version of the ID of the form element
// The configuration we've talked about above
autoProcessQueue: false,
uploadMultiple: true,
parallelUploads: 100,
maxFiles: 100,
// The setting up of the dropzone
init: function() {
var myDropzone = this;
// First change the button to actually tell Dropzone to process the queue.
this.element.querySelector("button[type=submit]").addEventListener("click", function(e) {
// Make sure that the form isn't actually being sent.
e.preventDefault();
e.stopPropagation();
myDropzone.processQueue();
});
// Listen to the sendingmultiple event. In this case, it's the sendingmultiple event instead
// of the sending event because uploadMultiple is set to true.
this.on("sendingmultiple", function() {
// Gets triggered when the form is actually being sent.
// Hide the success button or the complete form.
});
this.on("successmultiple", function(files, response) {
// Gets triggered when the files have successfully been sent.
// Redirect user or notify of success.
});
this.on("errormultiple", function(files, response) {
// Gets triggered when there was an error sending the files.
// Maybe show form again, and notify user of error
});
}
}
它工作得很好,除非用户没有提交文件。根据this post,我必须进行一些编辑:
替换简单的
myDropzone.processQueue();
来自
var form = $(this).closest('#dropzone-form');
if (form.valid() == true) {
if (myDropzone.getQueuedFiles().length > 0) {
myDropzone.processQueue();
} else {
myDropzone.uploadFiles([]); //send empty
}
}
现在,正如 Whosebug post "DropZonejs: Submit form without files" 评论中所写,我得到
Uncaught TypeError: Cannot read property 'status' of undefined
所以我检查了 dropzone issue 687,通过替换 dropzone.js 的一些内容来解决这个问题。这一行
ata.append(this._getParamName(i), files[i], files[i].name);
到那些行
if ( typeof files[i] != "undefined" ) {
formData.append(this._getParamName(i), files[i], files[i].name);
} else {
formData.append(this._getParamName(i), "");
}
现在可以正常工作了(使用模型中的正确数据调用控制器)但是发出的调用是 AJAX 调用,我想在我的应用程序的控制器中进行重定向,所以它没有工作。我可以用一个 URL 做一个 Json 作为 return 但我必须在后端保持重定向。
控制器示例:
[HttpPost]
public ActionResult Create(CustomViewModel model)
{
// Here I get Request.IsAjaxRequest() = true when form is submitted
if (ModelState.IsValid)
{
var container = DoSomething();
if (container.HasErrors)
{
SetError(container.ErrorMessage);
return RedirectToAction("Index");
}
}
else
{
SetAlert("ErrorMessage");
}
return RedirectToAction("Index");
}
我该如何解决这个问题? 预先感谢您的帮助
Dropzone 使用 AJAX 上传文件,这意味着页面本身永远不会更改,您不能使用服务器端重定向来更改页面。您唯一的选择是:
- Return 带有 URL 的 JSON 对象并在客户端重定向。
或
- 执行正常的表单回发,而不是 AJAX 上传。为此,您将不得不停止使用 Dropzone。
我遇到了同样的问题,但没有太多时间来解决它。只需要让它尽快工作...
这是我的 2 美分;
您可以从您的控制器return这样的东西;
return Json(new { ErrorMessage = "", RedirectURL = Url.Action("Get", null, new { id = result.Value.id }, Request.Url.Scheme ) });
并从您发布的 JS 中填写此方法:
this.on("successmultiple", function (files, response) {
// Gets triggered when the files have successfully been sent.
// Redirect the user or notify of success.
var errorMessage = response.ErrorMessage;
if (errorMessage.length > 0) {
alert(errorMessage);
}
else {
window.location.replace(response.RedirectURL);
}
};