Wouldn't it be great to be able to upload files via the ctools content_type config modals? Yeah!
This is tricky because xhttp requests can't be multipart-form/data, so jQuery.form runs them through an iframe, which works great except that it complicates responses in JSON or pure js. See the "File Uploads" section within the code-samples on the jQuery.form homepage for more in-depth background:
http://malsup.com/jquery/form/#code-samples
As per the suggestion there, this patch forces the iframe method whenever a file-upload form element is present, and uses the textarea wrapper around the response.
This patch shows a working (if not especially awesome) implementation by making the following changes:
1) Changes Drupal.CTools.Modal.submitAjaxForm to detect for a multipart form. If so, enforce the iframe method, include a different callback handler to process the textarea-wrapped response, and append a little ?ctools_multipart to the ajax url so that...
2) ajax.inc now looks for $_GET['ctools_mulipart'] and returns textare-wrapped json, without setting any headers.
3) Quickly added a file-upload to the custom content_type. It doesn't meaningfully process the file, but you'll see that it is present in $_FILES. This code should be dumped, but I include it for demonstration purposes.
| Comment | File | Size | Author |
|---|---|---|---|
| #11 | ctools-file-upload-b4.patch | 775 bytes | populist |
| #8 | upload_file_js_merge.patch | 740 bytes | populist |
| #6 | 451928-file-uploads.patch | 3.24 KB | merlinofchaos |
| #5 | 451928-file-uploads.patch | 3.13 KB | merlinofchaos |
| #3 | ctools_modal_file_uploads.patch | 3.89 KB | joshk |
Comments
Comment #1
joshk commentedComment #3
joshk commentedUpdated patch as per some suggestions from Dmitrig01. Cleaner in modal.js.
Comment #4
dmitrig01 commentedRemoved one more line:
Comment #5
merlinofchaos commentedHere's an updated patch. The original patch made some changes that I didn't like, plus actually could introduce bugs (introducing a new variable without using 'var' explodes on some browsers, for example).
It directly added "?" to the URL which breaks when clean URLs are off, so I moved the component to the data, which means that it now checks $_REQUEST. I believe these items should be merged properly.
I didn't test a file upload; the test included modified the 'custom' type which I didn't want to accidentally commit, so I did not patch that part. So I'm putting the patch here in the hopes that someone else will test this and make sure it continues to work.
Comment #6
merlinofchaos commentedWhoops, last patch contained a leftover debug msg.
Comment #7
merlinofchaos commentedWell, I went ahead and committed htis.
Comment #8
populist commentedI think we were rolling a little loose with adding objects (was seeing ajaxOptions contain two objects) and was seeing the page hang when trying to upload files.
I renamed the additive object and added a call to Jquery.extend to the end which got it working for me.
Comment #9
joshk commentedWe should revisit this in light of the beta4 release. Since it currently doesn't work, and RC1 is coming real soon now, I'm giving it a bump.
Comment #10
merlinofchaos commentedI had totally missed that htis had a new patch. Josh, can you confirm for me that populist's patch works?
Comment #11
populist commentedthe new version of ctools broke the passing of data through the data attribute of the ajax submit options. the ctools_multipart variable previous defined (see below) is nowhere to be seen in ctools_ajax_render().
my solution is to pass back the ctools_multipart value using that same form (which ctools_ajax_render()) like so:
i rerolled my old patch (which is still necessary to merge the javascript objects) and posted it all together. works in my two test cases.
Comment #12
markus_petrux commentedI think the file upload issue was solved in CCK using this in the AHAH callback:
Note that this also disables devel_shutdown.
If populist's patch needs to get in, then I would suggest using $.extend() rather than jQuery.extend().
Comment #13
merlinofchaos commentedCommitted, with the $.extend change.
Comment #14
merlinofchaos commented#13 suggests I committed this, so 'needs work' is wrong status.
Comment #16
eugenmayer commentedCan anybody confirm this is working for him in IE Browsers? I cant. Simple "only one file" upload method, wont work.
Not work is probably the wrong description. The file gets uploaded, but the request result is somehow a unknown filetype for the IE ( unkown Mime ) instead of being json.
Bit of researching told be that it is quiet a bad idea calling form.submit() in a IE, because this will include other security checks, making those json call fail.
I expect this http://drupal.org/node/947532 to be a similar issue or rather the same
Comment #17
eugenmayer commentedwell finally gound out that it all comes down to a missing
See the other issue for detailed explaination. Should we include that in the ctools docs somehow? Debugging this is a reayl painfull work...
Comment #18
merlinofchaos commentedThat's actually a general form api issue. You can't upload files to forms, CTools or not, without that. Perhaps this could be stressed in the CTools documentation, but I'm not certain where.
Comment #19
amitaibu@EugenMayer,
There's an example module I did that uses CTools' ajax for file upload in #940286: Code example for "File" form element in ajax form, that might help you.
Comment #20
eugenmayer commentedyou can upload files without setting this @merlin, it actually really affects the ajax part right now, due the jquery selector.
@19 well its fixed for me already, i was just thinking about saving other peoples time searching for this.
Comment #21
amitaibufyi, I have stumbled upon a case where $_POST was empty in IE when submitting a modal when $form_state['has_file_element'] was set to true -- #1158928: Set $form_state['has_file_element'] only when file element is accessible
Comment #22
yesct commentedcomment #17 helped with #1208094: Filefield AJAX editables break when more than one is included on the page
Comment #23
populist commentedI am going to close this issue since the primary purpose was already solved. If this is still an issue, feel free to open a new one in the queue!