Do you think a reasonable interpretation of xforms:upload/@incremental = 'true' would be that the file gets uploaded, and the instance updated, as soon as the user selects a file? This might affect the approach taken to implement http://forge.objectweb.org/tracker/index.php?func=detail&aid=304933&group_id=168&atid=350207. Adrian -- You receive this message as a subscriber of the [hidden email] mailing list. To unsubscribe: mailto:[hidden email] For general help: mailto:[hidden email]?subject=help ObjectWeb mailing lists service home page: http://www.objectweb.org/wws |
Administrator
|
Adrian,
Yes, @incremental="true" could work like GMail's file attachments: i.e. as soon as you select a file, upload proceeds in the background. If the file is large, it won't really be "as soon as", since the file must be uploaded to the server first (JavaScript doesn't have access to the content of the file on the client). Is that what you had in mind? -Erik Adrian Baker wrote: > Experimenting with the xforms:upload control I notice that the xml > instance data doesn't get updated with the uploaded file until there is > a submission of the relevant instance. > > Do you think a reasonable interpretation of xforms:upload/@incremental = > 'true' would be that the file gets uploaded, and the instance updated, > as soon as the user selects a file? This might affect the approach taken > to implement > http://forge.objectweb.org/tracker/index.php?func=detail&aid=304933&group_id=168&atid=350207. -- Orbeon - XForms Everywhere: http://www.orbeon.com/blog/ -- You receive this message as a subscriber of the [hidden email] mailing list. To unsubscribe: mailto:[hidden email] For general help: mailto:[hidden email]?subject=help ObjectWeb mailing lists service home page: http://www.objectweb.org/wws |
Regarding http://forge.objectweb.org/tracker/index.php?func=detail&aid=304933&group_id=168&atid=350207: I know this is always a difficult question, but do you see this fitting into any particular point on the development roadmap? Adrian Erik Bruchez wrote: Adrian, -- You receive this message as a subscriber of the [hidden email] mailing list. To unsubscribe: mailto:[hidden email] For general help: mailto:[hidden email]?subject=help ObjectWeb mailing lists service home page: http://www.objectweb.org/wws |
Administrator
|
Adrian Baker wrote:
> Yes exactly, thanks. > > Regarding > http://forge.objectweb.org/tracker/index.php?func=detail&aid=304933&group_id=168&atid=350207: > I know this is always a difficult question, but do you see this fitting > into any particular point on the development roadmap? 1. Supporting upload with replace="instance|none" would certainly be very valuable for most applications that use upload, but so far we have seen relatively little demand for it. So for now this remains fairly low priority. 2. Supporting the incremental mode is even lower priority, as this falls in the "fun to have" category ;-) But once #1 is implemented, this should not bee *too* hard to do. I don't think that #1 should be very hard to implement by using the appropriate YUI facilities: http://developer.yahoo.com/yui/connection/ It would be great if somebody did some preliminary investigations on this. A good part of the work is pure JavaScript / YUI and should be doable in xforms.js, and then we also have to make the XForms server be able to handle upload data (see xforms-server-submit.xpl vs. xforms-server.xpl). -Erik -- Orbeon - XForms Everywhere: http://www.orbeon.com/blog/ -- You receive this message as a subscriber of the [hidden email] mailing list. To unsubscribe: mailto:[hidden email] For general help: mailto:[hidden email]?subject=help ObjectWeb mailing lists service home page: http://www.objectweb.org/wws |
Erik Bruchez wrote:
Adrian Baker wrote:I'd hoped to do some work on implementing (1), however this is now looking unlikely. Here are some notes I made regarding a possible implementation approach - these might be useful for someone, although I expect most of this would be self-evident to Erik & Alex :) I got as far as modifying the client to asynchronously trigger a file upload & invoke the xforms-server-upload.xpl pipeline mentioned below (easy enough), but did not start on the server side changes. (start) Orbeon's support for upload isn't complete: upload is only supported on replace="all", not replace="instance" - see http://forge.objectweb.org/tracker/index.php?func=detail&aid=304933&group_id=168&atid=350207. The standard HTML 4 file upload & current OPS upload support
works by declarding an input with type file: This gets rendered as an input field with a Browse button immediately to the right. The user chooses a file using Browse... and the input field is populated with the filename which will be uploaded. When the parent html form is submitted the file is uploaded, page is blown away and replaced with response (effectively a replace="all"). In XForms we need to support the concept of uploading a file without doing a replace="all", eg when
This gives rise to a some UI considerations which we don't face with replace="all". 1. how do we communicate that upload is occuring/upload has completed?
2. what do we do when upload is complete/when xf:upload is bound to
an uploaded file? Let's aim to start with the simplest solution of (b), blanking the input field, which is also closest to the current behaviour of OPS. ImplementationWe can use YAHOO.util.Connect to upload a <form> containing an <input type="file"> asynchronously: // argument formId can be the id or name attribute value of the // HTML form, or an HTML form object. var formObject = document.getElementById('aForm'); // the second argument is true to indicate file upload. YAHOO.util.Connect.setForm(formObject, true); var cObj = YAHOO.util.Connect.asyncRequest('POST', 'http://www.yahoo.com', callback); However this is different to the current way OPS does asynchronous requests, which involves manual construction of an event-request xml document which contains information about the interaction: requestDocumentString += '<!DOCTYPE xxforms:event-request [<!ENTITY nbsp " ">]>\n'; ... YAHOO.util.Connect.initHeader("Content-Type", "application/xml"); YAHOO.util.Connect.asyncRequest("POST", XFORMS_SERVER_URL, { success: xformsHandleResponse }, requestDocumentString); Orbeon also does regular synchronous form submissions when replace="all": // Submit form case "submission": { if (xformsGetLocalName(actionElement.childNodes[actionIndex]) == "submission") { newDynamicStateTriggersPost = true; ORBEON.xforms.Globals.formDynamicState[formIndex].value = newDynamicState; ORBEON.xforms.Globals.requestForm.submit(); The submitted form here contains the entire state of the instance data in hidden inputs, along with the visible inputs - including any <input type="file">. This how OPS supports synchronous file uploads with replace="all". OPS uses xforms-server-submit.xpl to extract the hidden inputs and constructs the event request xml document server side, which is then processed normally by XFormsServer.java: xforms-server-submit.xpl
<p:config xmlns:p="http://www.orbeon.com/oxf/pipeline" xmlns:oxf="http://www.orbeon.com/oxf/processors" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- Extract parameters --> <p:processor name="oxf:request"> <p:input name="config"> <config stream-type="xs:anyURI"> <include>/request/parameters</include> </config> </p:input> <p:output name="data" id="request-params" debug="xxxrequest-params"/> </p:processor> <!-- Create XForms Server request --> <p:processor name="oxf:xslt"> <p:input name="data" href="#request-params"/> <p:input name="config"> <xxforms:event-request xsl:version="2.0" xmlns:xxforms="http://orbeon.org/oxf/xml/xforms"> <xxforms:static-state> <xsl:value-of select="/*/parameters/parameter[name = '$static-state']/value"/> </xxforms:static-state> <xxforms:dynamic-state> <xsl:value-of select="/*/parameters/parameter[name = '$dynamic-state']/value"/> </xxforms:dynamic-state> <xsl:variable name="files" select="/*/parameters/parameter[filename]"/> <xsl:if test="$files"> <xxforms:files> <xsl:copy-of select="$files"/> </xxforms:files> </xsl:if> <xxforms:action/> </xxforms:event-request> </p:input> <p:output name="data" id="xml-request"/> </p:processor> <!-- Run XForms Server --> <p:processor name="oxf:xforms-server"> <p:input name="request" href="#xml-request" schema-href="xforms-server-request.rng"/> </p:processor> </p:config> We could extend this submit behaviour to run asynchronously to perform uploads. Instead of calling requestForm.submit(), we would use the YAHOO.util.Connect library to asynchronously POST the form. To handle the POST server side, we'd need an extended version of xforms-server-submit.xpl which responded with the standard xml event response (which xforms-server-submit.xpl does not do). This logic is already present in xforms-server.xpl: xforms-server.xpl
<p:config xmlns:p="http://www.orbeon.com/oxf/pipeline" xmlns:oxf="http://www.orbeon.com/oxf/processors" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- Extract request body --> <p:processor name="oxf:request"> <p:input name="config"> <config stream-type="xs:anyURI"> <include>/request/body</include> </config> </p:input> <p:output name="data" id="request-body"/> </p:processor> <!-- Dereference URI and return XML --> <p:processor name="oxf:url-generator"> <p:input name="config" href="aggregate('config', aggregate('url', #request-body#xpointer(string(/request/body))))"/> <p:output name="data" id="xml-request"/> </p:processor> <!-- Run XForms Server --> <p:processor name="oxf:xforms-server"> <p:input name="request" href="#xml-request" schema-href="xforms-server-request.rng"/> <p:output name="response" id="xml-response" schema-href="xforms-server-response.rng"/> </p:processor> <!-- Generate response --> <p:processor name="oxf:xml-serializer"> <p:input name="data" href="#xml-response"/> <p:input name="config"> <config> <content-type>application/xml</content-type> </config> </p:input> </p:processor> </p:config> So a first attempt at the resulting xpl might look like: xforms-server-upload.xpl
<p:config xmlns:p="http://www.orbeon.com/oxf/pipeline" xmlns:oxf="http://www.orbeon.com/oxf/processors" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- Extract parameters --> <p:processor name="oxf:request"> <p:input name="config"> <config stream-type="xs:anyURI"> <include>/request/parameters</include> </config> </p:input> <p:output name="data" id="request-params"/> </p:processor> <!-- Create XForms Server request --> <p:processor name="oxf:xslt"> <p:input name="data" href="#request-params"/> <p:input name="config"> <xxforms:event-request xsl:version= class="code-quote">"2.0" xmlns:xxforms="http://orbeon.org/oxf/xml/xforms"> <xxforms:static-state> <xsl:value-of select="/*/parameters/parameter[name = '$static-state']/value"/> </xxforms:static-state> <xxforms:dynamic-state> <xsl:value-of select="/*/parameters/parameter[name = '$dynamic-state']/value"/> </xxforms:dynamic-state> <xsl:variable name="files" select="/*/parameters/parameter[filename]"/> <xsl:if test="$files"> <xxforms:files> <xsl:copy-of select="$files"/> </xxforms:files> </xsl:if> <xxforms:action/> </xxforms:event-request> </p:input> <p:output name="data" id="xml-request"/> </p:processor> <!-- Run XForms Server --> <p:processor name="oxf:xforms-server"> <p:input name="request" href="#xml-request" schema-href="xforms-server-request.rng"/> <p:output name="response" id="xml-response" schema-href="xforms-server-response.rng"/> </p:processor> <!-- Generate response --> <p:processor name="oxf:xml-serializer"> <p:input name="data" href="#xml-response"/> <p:input name="config"> <config> <content-type>application/xml</content-type> </config> </p:input> </p:processor> </p:config> Invoking the new pipeline from the xforms.js client is straightforward enough (note that at least version 0.11.3 of the YUI library is needed for the upload to return a responseXML document - OPS currently runs against 0.11.1 so would need to be upgraded): YAHOO.util.Connect.setForm(ORBEON.xforms.Globals.requestForm, true);
YAHOO.util.Connect.asyncRequest('POST', BASE_URL + "/xforms-server-upload", {upload: xformsHandleResponse});
The remaining work is in modifying the server side code to accept file uploads outside of a submit with replace="all". The pipeline above results in the following event request: <xxforms:event-request xmlns:xxforms="http://orbeon.org/oxf/xml/xforms" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:oxf="http://www.orbeon.com/oxf/processors" xmlns:p="http://www.orbeon.com/oxf/pipeline"> <xxforms:static-state>session:7C457098-A8A9-FE08-E17E-83D8ED165739</xxforms:static-state> <xxforms:dynamic-state>session:544FF17D-A43A-4A3B-5715-0CE457CF1DD4</xxforms:dynamic-state> <xxforms:files> <parameter> <name>fu</name> <filename>C:\Documents and Settings\adrianb\Desktop\backup.jpg</filename> <content-type>image/pjpeg</content-type> <content-length>3237</content-length> <value>file:/C:/dev/Venice/Common/CommonService/build/main/catalina-base/temp/upload_00000149.tmp</value> </parameter> </xxforms:files> <xxforms:action/> </xxforms:event-request> Currently OPS' server side logic will ignore the uploaded files, because interprets the <xxforms:files> element in org.orbeon.oxf.xforms.XFormsModelSubmission upon receiving a final replace="all" submission (indicated here by the isDeferredSubmissionSecondPass flag): if (isDeferredSubmissionSecondPass) { // Handle uploaded files if any final Element filesElement = (event instanceof XXFormsSubmitEvent) ? ((XXFormsSubmitEvent) event).getFilesElement() : null; if (filesElement != null) { for (Iterator i = filesElement.elements().iterator(); i.hasNext();) { // (update instance document with uploaded files) This logic would need to be factored out so it can be invoked from the standard event handling in org.orbeon.oxf.xforms.XFormsContainingDocument. To trigger the inspection of the file uploads & subsequent update of the instance data, an xforms-value-changed event could be raised by the new xforms-server-upload.xpl pipeline. This would also cover off something the above pipeline is missing: something identifying the upload control triggering the upload, because the <xxforms:files> section contains entries for *all* upload controls on the page (although they should be empty for already uploaded files) so this isn't enough. To make the filesElement available the XFormsValueChanged event could need to be modified or subclassed to store a reference to this. This contains a reference to the collection of <xxforms:files> elements provided by the client - the target of the value changed event (the upload control) would then be used to extract the appropriate file. Alternatively the pipeline could filter out files which do not originate from the target control, and only attach the correct uploaded file to the value changed event. (end)Adrian -- You receive this message as a subscriber of the [hidden email] mailing list. To unsubscribe: mailto:[hidden email] For general help: mailto:[hidden email]?subject=help ObjectWeb mailing lists service home page: http://www.objectweb.org/wws |
Administrator
|
Adrian,
Wow, that's a good analysis of how things work and should work! Thanks! Now we just need to implement it ;-) -Erik Adrian Baker wrote: > Erik Bruchez wrote: >> Adrian Baker wrote: >>> Yes exactly, thanks. >>> >>> Regarding >>> http://forge.objectweb.org/tracker/index.php?func=detail&aid=304933&group_id=168&atid=350207: >>> I know this is always a difficult question, but do you see this >>> fitting into any particular point on the development roadmap? >> >> 1. Supporting upload with replace="instance|none" would certainly be >> very valuable for most applications that use upload, but so far we >> have seen relatively little demand for it. So for now this remains >> fairly low priority. >> >> 2. Supporting the incremental mode is even lower priority, as this >> falls in the "fun to have" category ;-) But once #1 is implemented, >> this should not bee *too* hard to do. >> >> I don't think that #1 should be very hard to implement by using the >> appropriate YUI facilities: >> >> http://developer.yahoo.com/yui/connection/ >> >> It would be great if somebody did some preliminary investigations on >> this. A good part of the work is pure JavaScript / YUI and should be >> doable in xforms.js, and then we also have to make the XForms server >> be able to handle upload data (see xforms-server-submit.xpl vs. >> xforms-server.xpl). >> >> -Erik >> > I'd hoped to do some work on implementing (1), however this is now > looking unlikely. Here are some notes I made regarding a possible > implementation approach - these might be useful for someone, although I > expect most of this would be self-evident to Erik & Alex :) I got as far > as modifying the client to asynchronously trigger a file upload & invoke > the xforms-server-upload.xpl pipeline mentioned below (easy enough), but > did not start on the server side changes. > > (start) > > Orbeon's support for upload isn't complete: upload is only supported on > replace="all", not replace="instance" - see > http://forge.objectweb.org/tracker/index.php?func=detail&aid=304933&group_id=168&atid=350207^ > <http://forge.objectweb.org/tracker/index.php?func=detail&aid=304933&group_id=168&atid=350207>. > > The standard HTML 4 file upload & current OPS upload support works by > declarding an input with type file: > <input type="file"/> > > This gets rendered as an input field with a Browse button immediately to > the right. The user chooses a file using Browse... and the input field > is populated with the filename which will be uploaded. When the parent > html form is submitted the file is uploaded, page is blown away and > replaced with response (effectively a replace="all"). > > In XForms we need to support the concept of uploading a file *without* > doing a replace="all", eg when > > * instance with file is submitted with replace="instance" > * xf:upload/@incremental is true and the user chooses a file > > This gives rise to a some UI considerations which we don't face with > replace="all". > > 1. how do we communicate that upload is occuring/upload has completed? > > * initially just make do with standard throbber > * eventually during upload could the <input> box could be used > as/replaced with a progress bar? > > 2. what do we do when upload is complete/when xf:upload is bound to an > uploaded file? > (a). leave <input> filled in with filename? will cause reupload on > form.submit() though - can we prevent this? Won't leaving the filename > there indicate that there is a pending upload? > (b). blank the input field. puts onus on form author to > indicate/display uploaded file, which is more flexible. However controls > are meant to reflect current instance data ("Form controls when rendered > display the underlying data values to which they are bound" - > http://www.w3.org/TR/xforms/slice8.html#ui-processing^ ). On the other > hand, blanking gives an indication that there is no pending upload. Also > when a blank <input> is submitted with a form.submit() OPS ignores this > rather than clearing the uploaded file in the instance data. > (c) use some extra html elements alongside the <input file=""> to > indicate that a binary is present (icon+filename etc). Convenient, but > this behaviour can be more flexibly added by form author. > > Let's aim to start with the simplest solution of (b), blanking the input > field, which is also closest to the current behaviour of OPS. > > > Implementation > > We can use YAHOO.util.Connect to upload a <form> containing an <input > type="file"> asynchronously: > > // argument formId can be the id or name attribute value of the > // HTML form, or an HTML form object. > var formObject = document.getElementById('aForm'); > > // the second argument is true to indicate file upload. > YAHOO.util.Connect.setForm(formObject, true); > > var cObj = YAHOO.util.Connect.asyncRequest('POST', 'http://www.yahoo.com', callback); > > However this is different to the current way OPS does asynchronous > requests, which involves manual construction of an event-request xml > document which contains information about the interaction: > > requestDocumentString += '<!DOCTYPE xxforms:event-request [<!ENTITY nbsp " ">]>\n'; > ... > YAHOO.util.Connect.initHeader("Content-Type", "application/xml"); > YAHOO.util.Connect.asyncRequest("POST", XFORMS_SERVER_URL, { success: xformsHandleResponse }, requestDocumentString); > > Orbeon also does regular synchronous form submissions when replace="all": > > // Submit form > case "submission": { > if (xformsGetLocalName(actionElement.childNodes[actionIndex]) == "submission") { > newDynamicStateTriggersPost = true; > ORBEON.xforms.Globals.formDynamicState[formIndex].value = newDynamicState; > ORBEON.xforms.Globals.requestForm.submit(); > > The submitted form here contains the entire state of the instance data > in hidden inputs, along with the visible inputs - including any <input > type="file">. This how OPS supports synchronous file uploads with > replace="all". OPS uses xforms-server-submit.xpl to extract the hidden > inputs and constructs the event request xml document server side, which > is then processed normally by XFormsServer.java: > > *xforms-server-submit.xpl* > > <p:config xmlns:p="http://www.orbeon.com/oxf/pipeline" > xmlns:oxf="http://www.orbeon.com/oxf/processors" > xmlns:xs="http://www.w3.org/2001/XMLSchema" > xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> > > <!-- Extract parameters --> > <p:processor name="oxf:request"> > <p:input name="config"> > <config stream-type="xs:anyURI"> > <include>/request/parameters</include> > </config> > </p:input> > <p:output name="data" id="request-params" debug="xxxrequest-params"/> > </p:processor> > > <!-- Create XForms Server request --> > <p:processor name="oxf:xslt"> > <p:input name="data" href="#request-params"/> > <p:input name="config"> > <xxforms:event-request xsl:version="2.0" xmlns:xxforms="http://orbeon.org/oxf/xml/xforms"> > <xxforms:static-state> > <xsl:value-of select="/*/parameters/parameter[name = '$static-state']/value"/> > </xxforms:static-state> > <xxforms:dynamic-state> > <xsl:value-of select="/*/parameters/parameter[name = '$dynamic-state']/value"/> > </xxforms:dynamic-state> > <xsl:variable name="files" select="/*/parameters/parameter[filename]"/> > <xsl:if test="$files"> > <xxforms:files> > <xsl:copy-of select="$files"/> > </xxforms:files> > </xsl:if> > <xxforms:action/> > </xxforms:event-request> > </p:input> > <p:output name="data" id="xml-request"/> > </p:processor> > > <!-- Run XForms Server --> > <p:processor name="oxf:xforms-server"> > <p:input name="request" href="#xml-request" schema-href="xforms-server-request.rng"/> > </p:processor> > > </p:config> > > We could extend this submit behaviour to run asynchronously to perform > uploads. Instead of calling requestForm.submit(), we would use the > YAHOO.util.Connect library to asynchronously POST the form. To handle > the POST server side, we'd need an extended version of > xforms-server-submit.xpl which responded with the standard xml event > response (which xforms-server-submit.xpl does not do). This logic is > already present in xforms-server.xpl: > > *xforms-server.xpl* > > <p:config xmlns:p="http://www.orbeon.com/oxf/pipeline" > xmlns:oxf="http://www.orbeon.com/oxf/processors" > xmlns:xs="http://www.w3.org/2001/XMLSchema" > xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> > > <!-- Extract request body --> > <p:processor name="oxf:request"> > <p:input name="config"> > <config stream-type="xs:anyURI"> > <include>/request/body</include> > </config> > </p:input> > <p:output name="data" id="request-body"/> > </p:processor> > > <!-- Dereference URI and return XML --> > <p:processor name="oxf:url-generator"> > <p:input name="config" href="aggregate('config', aggregate('url', #request-body#xpointer(string(/request/body))))"/> > <p:output name="data" id="xml-request"/> > </p:processor> > > <!-- Run XForms Server --> > <p:processor name="oxf:xforms-server"> > <p:input name="request" href="#xml-request" schema-href="xforms-server-request.rng"/> > <p:output name="response" id="xml-response" schema-href="xforms-server-response.rng"/> > </p:processor> > > <!-- Generate response --> > <p:processor name="oxf:xml-serializer"> > <p:input name="data" href="#xml-response"/> > <p:input name="config"> > <config> > <content-type>application/xml</content-type> > </config> > </p:input> > </p:processor> > > </p:config> > > So a first attempt at the resulting xpl might look like: > > *xforms-server-upload.xpl* > > <p:config xmlns:p="http://www.orbeon.com/oxf/pipeline" > xmlns:oxf="http://www.orbeon.com/oxf/processors" > xmlns:xs="http://www.w3.org/2001/XMLSchema" > xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> > > <!-- Extract parameters --> > <p:processor name="oxf:request"> > <p:input name="config"> > <config stream-type="xs:anyURI"> > <include>/request/parameters</include> > </config> > </p:input> > <p:output name="data" id="request-params"/> > </p:processor> > > <!-- Create XForms Server request --> > <p:processor name="oxf:xslt"> > <p:input name="data" href="#request-params"/> > <p:input name="config"> > <xxforms:event-request xsl:version= class="code-quote">"2.0" xmlns:xxforms="http://orbeon.org/oxf/xml/xforms"> > <xxforms:static-state> > <xsl:value-of select="/*/parameters/parameter[name = '$static-state']/value"/> > </xxforms:static-state> > <xxforms:dynamic-state> > <xsl:value-of select="/*/parameters/parameter[name = '$dynamic-state']/value"/> > </xxforms:dynamic-state> > <xsl:variable name="files" select="/*/parameters/parameter[filename]"/> > <xsl:if test="$files"> > <xxforms:files> > <xsl:copy-of select="$files"/> > </xxforms:files> > </xsl:if> > <xxforms:action/> > </xxforms:event-request> > </p:input> > <p:output name="data" id="xml-request"/> > </p:processor> > > <!-- Run XForms Server --> > <p:processor name="oxf:xforms-server"> > <p:input name="request" href="#xml-request" schema-href="xforms-server-request.rng"/> > <p:output name="response" id="xml-response" schema-href="xforms-server-response.rng"/> > </p:processor> > > <!-- Generate response --> > <p:processor name="oxf:xml-serializer"> > <p:input name="data" href="#xml-response"/> > <p:input name="config"> > <config> > <content-type>application/xml</content-type> > </config> > </p:input> > </p:processor> > > </p:config> > > Invoking the new pipeline from the xforms.js client is straightforward > enough (note that at least version 0.11.3 of the YUI library is needed > for the upload to return a responseXML document - OPS currently runs > against 0.11.1 so would need to be upgraded): > > YAHOO.util.Connect.setForm(ORBEON.xforms.Globals.requestForm, true); > YAHOO.util.Connect.asyncRequest('POST', BASE_URL + "/xforms-server-upload", {upload: xformsHandleResponse}); > > The remaining work is in modifying the server side code to accept file > uploads outside of a submit with replace="all". The pipeline above > results in the following event request: > > <xxforms:event-request xmlns:xxforms="http://orbeon.org/oxf/xml/xforms" > xmlns:xs="http://www.w3.org/2001/XMLSchema" > xmlns:oxf="http://www.orbeon.com/oxf/processors" > xmlns:p="http://www.orbeon.com/oxf/pipeline"> > <xxforms:static-state>session:7C457098-A8A9-FE08-E17E-83D8ED165739</xxforms:static-state> > <xxforms:dynamic-state>session:544FF17D-A43A-4A3B-5715-0CE457CF1DD4</xxforms:dynamic-state> > <xxforms:files> > <parameter> > <name>fu</name> > <filename>C:\Documents and Settings\adrianb\Desktop\backup.jpg</filename> > <content-type>image/pjpeg</content-type> > <content-length>3237</content-length> > <value>file:/C:/dev/Venice/Common/CommonService/build/main/catalina-base/temp/upload_00000149.tmp</value> > </parameter> > </xxforms:files> > <xxforms:action/> > </xxforms:event-request> > > Currently OPS' server side logic will ignore the uploaded files, because > interprets the <xxforms:files> element in > org.orbeon.oxf.xforms.XFormsModelSubmission upon receiving a final > replace="all" submission (indicated here by the > isDeferredSubmissionSecondPass flag): > > if (isDeferredSubmissionSecondPass) { > // Handle uploaded files if any > final Element filesElement = (event instanceof XXFormsSubmitEvent) ? ((XXFormsSubmitEvent) event).getFilesElement() : null; > if (filesElement != null) { > for (Iterator i = filesElement.elements().iterator(); i.hasNext();) { > > // (update instance document with uploaded files) > > This logic would need to be factored out so it can be invoked from the > standard event handling in > org.orbeon.oxf.xforms.XFormsContainingDocument. To trigger the > inspection of the file uploads & subsequent update of the instance data, > an xforms-value-changed event could be raised by the new > xforms-server-upload.xpl pipeline. This would also cover off something > the above pipeline is missing: something identifying the upload control > triggering the upload, because the <xxforms:files> section contains > entries for *all* upload controls on the page (although they should be > empty for already uploaded files) so this isn't enough. > > To make the filesElement available the XFormsValueChanged event could > need to be modified or subclassed to store a reference to this. This > contains a reference to the collection of <xxforms:files> elements > provided by the client - the target of the value changed event (the > upload control) would then be used to extract the appropriate file. > Alternatively the pipeline could filter out files which do not originate > from the target control, and only attach the correct uploaded file to > the value changed event. > > (end) > > Adrian -- Orbeon - XForms Everywhere: http://www.orbeon.com/blog/ -- You receive this message as a subscriber of the [hidden email] mailing list. To unsubscribe: mailto:[hidden email] For general help: mailto:[hidden email]?subject=help ObjectWeb mailing lists service home page: http://www.objectweb.org/wws |
Free forum by Nabble | Edit this page |