PDA

View Full Version : [CLOSED] FileUploadField gets cleared even if POST did not happen



ingbabic
Apr 08, 2016, 1:01 PM
Hi
I have strange situation with FileUploadField. It gets cleared even if POST did not happen. I prevent post with before handler like in following example:
View:


<script>

var returnValue = true;

function doValidation() {

returnValue = !returnValue
return returnValue;
}
</script>

@Html.X().ResourceManager()

@(
Html.X().Window()
.Items
(
Html.X().FormPanel().ID("mainForm")
.Items
(
Html.X().FileUploadField().ID("fileUpload").ClearOnSubmit(false)
)
)
.Buttons
(
Html.X().Button().Text("OK").ID("btnOk").Disabled(false)
.DirectEvents
(
de =>
{
de.Click.Before = "return doValidation();";
de.Click.IsUpload = true;
de.Click.FormID = "mainForm";
de.Click.Url = Url.Action("DoAction");
de.Click.ExtraParams.Add(new Parameter("formValues", "this.up('window').down('form').getForm().getFieldV alues(false)", ParameterMode.Raw));
de.Click.EventMask.ShowMask = true;
}
)
)
)


Controller:


public class DefaultController : Controller
{
// GET: Default
public ActionResult Index()
{
return View();
}

public ActionResult DoAction()
{
FileUploadField fileUploadField = this.GetCmp<FileUploadField>("fileUpload");

if (fileUploadField.HasFile)
{
string fileName = fileUploadField.PostedFile.FileName;
X.Msg.Notify(new NotificationConfig
{
Icon = Icon.Accept,
Title = "Information",
Html = string.Format("Poste file {0}", fileName),
HideDelay = 4000
}).Show();
}
else
{
X.Msg.Notify(new NotificationConfig
{
Icon = Icon.Error,
Title = "Error",
Html = "No file posted!",
HideDelay = 4000
}).Show();
}
DirectResult result = new DirectResult();
result.IsUpload = true;
return result;
}
}

You will notice that ClearOnSubmit works (text box part in FileUploadField doesn't get emptied), but file is actually gone. We have tried to have similar situation like in real project, only here first time it will simply not let you post (in real project there are several complex checks, so we wanted to avoid it and to make sample as simple as possible).

fabricio.murta
Apr 08, 2016, 2:41 PM
Hello @ingbabic!

Thanks for the simple example!

It seems that it gets the inner file handle to the browser cleaned on that point.

This seems sufficient to overcome the issue:


<script type="text/javascript">
Ext.form.field.File.override({
extractFileInput: function () {
var fileInput = this.fileInputEl.dom;
if (this.clearOnSubmit) this.reset();
return fileInput;
}
});
</script>


But might block from selecting another file once one is selected and submit, thus a manual "clear" button might be necessary. Something like this:


Html.X().Button().Text("Clear").ID("btnClear").Disabled(false).OnClientClick("App.fileUpload.reset(); App.fileUpload.inputEl.setValue('');")


May probably want to bind an event to the browse button to clean the current selection if any. What would turn another potential problem: one clicks 'Browse', the current selection is cleared, then cancel selecting and the field will no longer have the previous handle.

I can give it a further review if the solution does not look good for you.

fabricio.murta
Apr 08, 2016, 6:00 PM
It may be more appropriate and functional for you (just in case), if this is sufficient:
- Do not clear if the submit did not really happen
- The field can be cleared once the submit effectively happens

Then you could actually validate the form before submitting simply by moving the doValidation to the client-side click listener. No override would be necessary and the form will only be cleared if and only if the validation passes:




@{
Layout = null;
}

<!DOCTYPE html>

<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>c60816_Index</title>
</head>
<body>
<div>
<script>
var returnValue = true;

function doValidation(e) {
returnValue = !returnValue
return returnValue;
}
</script>

@Html.X().ResourceManager()

@(
Html.X().Window()
.Items
(
Html.X().FormPanel().ID("mainForm")
.Items
(
// Yes, we want clear on submit now!
Html.X().FileUploadField().ID("fileUpload").ClearOnSubmit(true)
)
)
.Buttons
(
Html.X().Button().Text("OK").ID("btnOk").Disabled(false)
.DirectEvents
(
de =>
{
de.Click.IsUpload = true;
de.Click.FormID = "mainForm";
de.Click.Url = Url.Action("c60816_DoAction");
de.Click.ExtraParams.Add(new Parameter("formValues", "this.up('window').down('form').getForm().getFieldV alues(false)", ParameterMode.Raw));
de.Click.EventMask.ShowMask = true;
}
)
.Listeners(lt =>
{
lt.Click.Fn = "doValidation";
}),
)
)
</div>
</body>
</html>


But, again, this only applies if you can afford to reset the field once the submission effectively happens.

ingbabic
Apr 11, 2016, 7:47 AM
Thank you, both solutions seem to work.