PDA

View Full Version : Fileupload and JsonData at the same time?



muselmanach
18 Aug 2011, 11:25 AM
I got the following structure: formpanel->fieldset->(TextField, TextArea, FileUpload, Button)

I want to perform a formpanel submit after clicking the button.

Is it possible to send the content of the textfield and textarea with json and do a normal fileupload at the same time?

Thank u, for your help.

stevil
18 Aug 2011, 12:26 PM
I don't believe so. If a formpanel sees a field that is is a file upload field, it uses an IFRAME submit hack to get the file uploaded instead of the normal AJAX update. That's because there is no cross-browser way of getting to the contents of the file (HTML5 declares it, but not all browsers support it yet).

It would seem to me that you would need to get the FileUpload onto a separate form/formpanel, and in your button click, submit the first form and the second form independently (each according to its needs based on the presence/absence of a FileUpload field).

stevil

muselmanach
18 Aug 2011, 1:20 PM
the problem is i need all of my components in the same formpanel.
maybe anyone knows some hacks to override the sumit actions or anything like that, so i can upload my file and send jsonData at the same time.

thanks

stevil
18 Aug 2011, 2:05 PM
the problem is i need all of my components in the same formpanel.
maybe anyone knows some hacks to override the sumit actions or anything like that, so i can upload my file and send jsonData at the same time.

thanks

I think, then that what you need to do is something like this:

1) Extend Ext.form.action.Submit
2) override doSubmit to both call buildForm AND getParams into params on two separate Ajax requests
3) override buildForm to only build out the <form> element for your upload field
4) issue both Ajax calls, with separate callbacks so you know which response is which
5) Extend Ext.form.Panel
6) override submit to use the alias you created in 1)

A very rough example (not tested or debugged - you need to fill in functionality as well), would look like:



Ext.define('My.form.action.Submit', {
extend:'Ext.form.action.Action',
alias: 'formaction.mysubmit',
type: 'mysubmit',
doSubmit: function() {
var formEl,
ajaxOptions = Ext.apply(this.createCallback(), {
url: this.getUrl(),
method: this.getMethod(),
headers: this.headers
}),
ajaxUploadOptions = {
success: this.onUploadSuccess,
failure: this.onUploadFailure,
url: this.getUrl(),
method: this.getMethod(),
headers: this.headers
};

// For uploads we need to create an actual form that contains the file upload fields,
// and pass that to the ajax call so it can do its iframe-based submit method.
if (this.form.hasUpload()) {
formEl = ajaxUploadOptions.form = this.buildForm();
ajaxUploadOptions.isUpload = true;
}

// ALSO do the Ajax request
ajaxOptions.params = this.getParams();

// Issue both requests
Ext.Ajax.request(ajaxOptions);
Ext.Ajax.request(ajaxUploadOptions);

// Clean up
if (formEl) {
Ext.removeNode(formEl);
}
},

buildForm: function() {
var fieldsSpec = [],
formSpec,
formEl,
basicForm = this.form,
params = this.getParams(),
uploadFields = [];

basicForm.getFields().each(function(field) {
if (field.isFileUpload()) {
uploadFields.push(field);
}
});

// skip building other form fields

formSpec = {
tag: 'form',
action: this.getUrl(),
method: this.getMethod(),
target: this.target || '_self',
style: 'display:none',
cn: fieldsSpec
};

// Set the proper encoding for file uploads
if (uploadFields.length) {
formSpec.encoding = formSpec.enctype = 'multipart/form-data';
}

// Create the form
formEl = Ext.DomHelper.append(Ext.getBody(), formSpec);

// Special handling for file upload fields: since browser security measures prevent setting
// their values programatically, and prevent carrying their selected values over when cloning,
// we have to move the actual field instances out of their components and into the form.
Ext.Array.each(uploadFields, function(field) {
if (field.rendered) { // can only have a selected file value after being rendered
formEl.appendChild(field.extractFileInput());
}
});
return formEl;
},

// You may need to build a latch mechanism to
// detect when both requests have succeeded
onSuccess: function(response) {
var form = this.form,
success = true,
result = this.processResponse(response);
if (result !== true && !result.success) {
if (result.errors) {
form.markInvalid(result.errors);
}
this.failureType = Ext.form.action.Action.SERVER_INVALID;
success = false;
}

// Do something here in conjunction with onUploadSuccess
// according to your requirements

form.afterAction(this, success);
},
onUploadSuccess: function(response) {
// Do something here in conjunction with onSuccess
// according to your requirements
}
onUploadFailure: function(response) {
// Do something here in conjunction with onSuccess
// according to your requirements
}
});

Ext.define('My.form.Panel', {
extend: 'Ext.form.Panel',
alias: 'myform',
submit: function(options) {
// use the custom submit action above
return this.doAction('mysubmit', options);
}
});


Like I say, it's not absolutely complete, but it may get you started. Hope this helps,

stevil

P.S. Really sorry about the formatting - it pasted out of UltraEdit weirdly before I could catch it!

muselmanach
18 Aug 2011, 3:06 PM
thank you, i think this will do the job.
i'll post my code, when its working.