Really, I haven't gotten that far yet, I am only working to improve the integration with Jakarta FileUpload. JFU is quite capable and mature, but I figured the first step would be to expose more functionality since there were a few JIRAs related to people asking for more than what is currently offered.
I committed a partially complete plugin to the sandbox yesterday before I left my office, but I still need to glue it together with configuration, etc. (and work out a bug I realized I had in the middle of the night last night). Once I get the plugin to an installable state, you can check it out. I figure the first step is to make the plugin work, then the next step is building an example UI. I am not sure how I am going to build the example UI, but JQuery is probably the most likely candidate for me. As far as selecting multiple files with Ctrl-Click, I'm not sure if that is possible... Not from a struts/jquery perspective, but I don't know if the browser will let you do that. I think Flash may be the only option (or a java applet or something, but flash is more likely), so we can come back to that later. -Wes On Thu, Jun 4, 2009 at 4:07 AM, Qunhuan Mei <q...@qm18.wanadoo.co.uk> wrote: > Hi Wes, > > Struts’ ajax file upload would be very interesting to me since I have > implemented jQuery (http://www.phpletter.com/Our-Projects/AjaxFileUpload/) > and Struts for ajax file upload in my application and had one or two > problem(s). > > FYI: My use case is to upload a file, together with utf8 encoded caption. > The problem I had is utf8 encoded caption needs to be sent via HTTP POST, it > won’t work with HTTP get. But the jQuery arrangement is sending file in POST > while sending caption in Get. So what I did is to send caption and file in > two POSTs which cause other complications. Later the author (Øyvind Saltvik > oyvind.salt...@gmail.com) sent me the following code contributed by > (Prokofiev Nikolay nprokof...@gmail.com) which added the parameter POSTing > (e.g. caption) to jQuery’s file upload. > > $.ajaxFileUpload > ( > { > url:document.location+'&ajax=true', > secureuri:false, > fileElementId:'fileToUpload', > data: {foo: 'ghffgh', bar: 'fghfhgg'}, > dataType: 'json', > success: function (data, status) > { > if(typeof(data.error) != 'undefined') > { > if(data.error != '') > { > alert(data.error); > }else > { > alert(data.msg); > } > } > }, > error: function (data, status, e) > { > alert(e); > } > } > ) > > here is the script: > jQuery.extend({ > createUploadIframe: function(id, uri) > { > //create frame > var frameId = 'jUploadFrame' + id; > > if(window.ActiveXObject) { > var io = document.createElement('<iframe id="' + frameId + > '" name="' + frameId + '" />'); > if(typeof uri== 'boolean'){ > io.src = 'javascript:false'; > } > else if(typeof uri== 'string'){ > io.src = uri; > } > } > else { > var io = document.createElement('iframe'); > io.id = frameId; > io.name = frameId; > } > io.style.position = 'absolute'; > io.style.top = '-1000px'; > io.style.left = '-1000px'; > > document.body.appendChild(io); > > return io > }, > createUploadForm: function(id, fileElementId, postData) > { > //create form > var formId = 'jUploadForm' + id; > var fileId = 'jUploadFile' + id; > var form = $('<form action="" method="POST" name="' + formId + '" > id="' + formId + '" enctype="multipart/form-data"></form>'); > var oldElement = $('#' + fileElementId); > var newElement = $(oldElement).clone(); > $(oldElement).attr('id', fileId); > $(oldElement).before(newElement); > $(oldElement).appendTo(form); > try > { > for(param in postData) > { > var input = document.createElement('input'); > input.setAttribute('name', param); > input.setAttribute('value', postData[param]); > $(input).appendTo(form); > } > } > catch(e) {} > //set attributes > $(form).css('position', 'absolute'); > $(form).css('top', '-1200px'); > $(form).css('left', '-1200px'); > $(form).appendTo('body'); > return form; > }, > ajaxFileUpload: function(s) { > // TODO introduce global settings, allowing the client to modify > them for all requests, not only timeout > s = jQuery.extend({}, jQuery.ajaxSettings, s); > var id = new Date().getTime() > var form = jQuery.createUploadForm(id, s.fileElementId, s.data); > var io = jQuery.createUploadIframe(id, s.secureuri); > var frameId = 'jUploadFrame' + id; > var formId = 'jUploadForm' + id; > // Watch for a new set of requests > if ( s.global && ! jQuery.active++ ) > { > jQuery.event.trigger( "ajaxStart" ); > } > var requestDone = false; > // Create the request object > var xml = {} > if ( s.global ) > jQuery.event.trigger("ajaxSend", [xml, s]); > // Wait for a response to come back > var uploadCallback = function(isTimeout) > { > var io = document.getElementById(frameId); > try > { > if(io.contentWindow) > { > xml.responseText = > io.contentWindow.document.body?io.contentWindow.document.body.innerHTML:null > ; > xml.responseXML = > io.contentWindow.document.XMLDocument?io.contentWindow.document.XMLDocument: > io.contentWindow.document; > > }else if(io.contentDocument) > { > xml.responseText = > io.contentDocument.document.body?io.contentDocument.document.body.innerHTML: > null; > xml.responseXML = > io.contentDocument.document.XMLDocument?io.contentDocument.document.XMLDocum > ent:io.contentDocument.document; > } > }catch(e) > { > jQuery.handleError(s, xml, null, e); > } > if ( xml || isTimeout == "timeout") > { > requestDone = true; > var status; > try { > status = isTimeout != "timeout" ? "success" : "error"; > // Make sure that the request was successful or > notmodified > if ( status != "error" ) > { > // process the data (runs the xml through httpData > regardless of callback) > var data = jQuery.uploadHttpData( xml, s.dataType ); > > // If a local callback was specified, fire it and > pass it the data > if ( s.success ) > s.success( data, status ); > > // Fire the global callback > if( s.global ) > jQuery.event.trigger( "ajaxSuccess", [xml, s] ); > } else > jQuery.handleError(s, xml, status); > } catch(e) > { > status = "error"; > jQuery.handleError(s, xml, status, e); > } > > // The request was completed > if( s.global ) > jQuery.event.trigger( "ajaxComplete", [xml, s] ); > > // Handle the global AJAX counter > if ( s.global && ! --jQuery.active ) > jQuery.event.trigger( "ajaxStop" ); > > // Process result > if ( s.complete ) > s.complete(xml, status); > > jQuery(io).unbind() > > setTimeout(function() > { try > { > $(io).remove(); > $(form).remove(); > > } catch(e) > { > jQuery.handleError(s, xml, null, > e); > } > > > }, 100) > > xml = null > > } > } > // Timeout checker > if ( s.timeout > 0 ) > { > setTimeout(function(){ > // Check to see if the request is still happening > if( !requestDone ) uploadCallback( "timeout" ); > }, s.timeout); > } > try > { > // var io = $('#' + frameId); > var form = $('#' + formId); > $(form).attr('action', s.url); > $(form).attr('method', 'POST'); > $(form).attr('target', frameId); > if(form.encoding) > { > form.encoding = 'multipart/form-data'; > } > else > { > form.enctype = 'multipart/form-data'; > } > $(form).submit(); > > } catch(e) > { > jQuery.handleError(s, xml, null, e); > } > if(window.attachEvent){ > document.getElementById(frameId).attachEvent('onload', > uploadCallback); > } > else{ > document.getElementById(frameId).addEventListener('load', > uploadCallback, false); > } > return {abort: function () {}}; > > }, > > uploadHttpData: function( r, type ) { > var data = !type; > data = type == "xml" || data ? r.responseXML : r.responseText; > // If the type is "script", eval it in global context > if ( type == "script" ) > jQuery.globalEval( data ); > // Get the JavaScript object, if JSON is used. > if ( type == "json" ) > eval( "data = " + data ); > // evaluate scripts within html > if ( type == "html" ) > jQuery("<div>").html(data).evalScripts(); > //alert($('param', > data).each(function(){alert($(this).attr('value'));})); > return data; > } > }) > > But during my tesing, the code appears to run ok only in IE (IE 7). It > failed on Firefox (3.0.10), Safari (3.2.1) and Chrome (1.0.154.65), with > simply no request received from the server after “jQuery(form).submit();” > and no exception thrown or captured either. I reported the problem back but > so far no reply (I am not a Javascript expert). > > Hope your ajax file upload approach will also handle UTF8 encoded caption – > I certainly would do some testing when your code is ready > The other issue in my mind about file upload is if “multi-file upload in one > submit” could be achieved. I saw it in Flash version where user selects > multiple files using Window’s file selection while keeping control key down. > I suppose this ability would bring Struts’ file upload to the next level. > > Kind regards, > > Qunhuan > > -----Original Message----- > From: Wes Wannemacher [mailto:w...@wantii.com] > Sent: 03 June 2009 22:03 > To: Struts Users Mailing List > Subject: Re: About the "struts.multipart.saveDir" for file upload > > > I'll check it out, I just wanted to improve what we had because it's > currently impossible to do things like an AJAX upload with accurate > progress bar. After I get the plugin (1.0-SNAPSHOT, which is the maven > way of saying beta) committed to the sandbox, I'll whip up a quick > example of how to do an AJAX w/progress bar using struts. > > -Wes > > On Wed, Jun 3, 2009 at 5:00 PM, Andy <andrh...@hotmail.com> wrote: >> >> That's great Wes. I am using the file upload but only sparingly (and > hacked) due to some existing glitches. >> >> >> >> I read how the Stripes framework does file upload: > http://www.stripesframework.org/display/stripes/File+Uploads >> >> >> >> Thought you might find it interesting/useful.. >> >> >> >> Andy >> >> >> >>> Date: Wed, 3 Jun 2009 16:48:56 -0400 >>> Subject: Re: About the "struts.multipart.saveDir" for file upload >>> From: w...@wantii.com >>> To: user@struts.apache.org >>> >>> I don't know if I would suggest it, but you might be able to call - >>> >>> Dispatcher.getInstance().setMultipartSaveDir(String path) >>> >>> Now, I can't remember if there is one dispatcher per thread, so you >>> might have to call it in an interceptor. >>> >>> However, I would strongly suggest against doing that. >>> >>> I am working on an enhanced file upload plugin right now and will >>> probably commit it to the sandbox by tomorrow. The problem with the >>> stock file upload capability is that the FileItemFactory and >>> FileUpload objects are not available to be overridden, and hardly any >>> configuration is made visible. So, I've got a new >>> JakartaMultiPartRequest class I'll have out by tomorrow. >>> >>> -Wes >>> >>> On Wed, Jun 3, 2009 at 4:37 PM, Andy <andrh...@hotmail.com> wrote: >>> > >>> > It defaults but I think he's wondering how he can set the dir > programatically. >>> > >>> > >>> > >>> >> Date: Wed, 3 Jun 2009 15:35:33 -0500 >>> >> Subject: Re: About the "struts.multipart.saveDir" for file upload >>> >> From: burtonrho...@gmail.com >>> >> To: user@struts.apache.org >>> >> >>> >> I wasn't aware that it was required. If you don't specify doesn't it >>> >> default to the 'work' directory? >>> >> >>> >> On 6/3/09, Qunhuan Mei <q...@qm18.wanadoo.co.uk> wrote: >>> >> > >>> >> > Hi, >>> >> > >>> >> > When implementing file upload, it is required to specify an absolute >>> >> > directory in struts.xml such as following: >>> >> > >>> >> > <constant name="struts.multipart.saveDir" > value="C:/fileUploadTempDir" >>> >> > /> >>> >> > >>> >> > But this might be difficult to achieve, say when the project war is > deployed >>> >> > in a external shared server and we do not have much idea about the > directory >>> >> > structure of the target server machine. >>> >> > >>> >> > I was wondering if there is any recommended way to handle this > issue. >>> >> > >>> >> > Ideally I would like to specify the directory in java code where I > can >>> >> > detect the current working directory and specify the saveDir > accordingly. Is >>> >> > this possible? >>> >> > >>> >> > Many thanks in advance, >>> >> > >>> >> > Qunhuan >>> >> > >>> >> > >>> >> > >>> >> > >>> >> > > --------------------------------------------------------------------- >>> >> > To unsubscribe, e-mail: user-unsubscr...@struts.apache.org >>> >> > For additional commands, e-mail: user-h...@struts.apache.org >>> >> > >>> >> > >>> >> >>> >> -- >>> >> Sent from my mobile device >>> >> >>> >> --------------------------------------------------------------------- >>> >> To unsubscribe, e-mail: user-unsubscr...@struts.apache.org >>> >> For additional commands, e-mail: user-h...@struts.apache.org >>> >> >>> > >>> > _________________________________________________________________ >>> > Windows Live™: Keep your life in sync. >>> > > http://windowslive.com/explore?ocid=TXT_TAGLM_WL_BR_life_in_synch_062009 >>> >>> >>> >>> -- >>> Wes Wannemacher >>> Author - Struts 2 In Practice >>> Includes coverage of Struts 2.1, Spring, JPA, JQuery, Sitemesh and more >>> http://www.manning.com/wannemacher >>> >>> --------------------------------------------------------------------- >>> To unsubscribe, e-mail: user-unsubscr...@struts.apache.org >>> For additional commands, e-mail: user-h...@struts.apache.org >>> >> >> _________________________________________________________________ >> Insert movie times and more without leaving Hotmail®. >> > http://windowslive.com/Tutorial/Hotmail/QuickAdd?ocid=TXT_TAGLM_WL_HM_Tutori > al_QuickAdd_062009 > > > > -- > Wes Wannemacher > Author - Struts 2 In Practice > Includes coverage of Struts 2.1, Spring, JPA, JQuery, Sitemesh and more > http://www.manning.com/wannemacher > > --------------------------------------------------------------------- > To unsubscribe, e-mail: user-unsubscr...@struts.apache.org > For additional commands, e-mail: user-h...@struts.apache.org > > > > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: user-unsubscr...@struts.apache.org > For additional commands, e-mail: user-h...@struts.apache.org > > -- Wes Wannemacher Author - Struts 2 In Practice Includes coverage of Struts 2.1, Spring, JPA, JQuery, Sitemesh and more http://www.manning.com/wannemacher --------------------------------------------------------------------- To unsubscribe, e-mail: user-unsubscr...@struts.apache.org For additional commands, e-mail: user-h...@struts.apache.org