changeset 2:df095eecba63

Auto-submit
author Adam Chlipala <adam@chlipala.net>
date Thu, 29 Dec 2011 15:42:15 -0500
parents f84d5e8aa992
children 6ad01456dc2e
files examples/server.ur include/ajaxUpload.h src/c/Makefile.am src/c/Makefile.in src/c/ajaxUpload.c src/ur/ajaxUpload.ur src/ur/ajaxUpload.urs src/ur/ajaxUploadFfi.urs
diffstat 8 files changed, 34 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/examples/server.ur	Thu Dec 29 15:26:46 2011 -0500
+++ b/examples/server.ur	Thu Dec 29 15:42:15 2011 -0500
@@ -3,9 +3,10 @@
 table images : { Id : int, MimeType : string, Content : blob }
   PRIMARY KEY Id
 
-fun main () =
+fun choice b =
     status <- source <xml/>;
-    au <- AjaxUpload.render {OnBegin = set status <xml>Uploading</xml>,
+    au <- AjaxUpload.render {AutoSubmit = b,
+                             OnBegin = set status <xml>Uploading</xml>,
                              OnSuccess = fn h =>
                                             let
                                                 fun addImage () =
@@ -37,3 +38,8 @@
       <hr/>
       <dyn signal={signal status}/>
     </body></xml>
+
+fun main () = return <xml><body>
+  <a link={choice False}>Normal</a><br/>
+  <a link={choice True}>Auto-submit</a>
+</body></xml>
--- a/include/ajaxUpload.h	Thu Dec 29 15:26:46 2011 -0500
+++ b/include/ajaxUpload.h	Thu Dec 29 15:42:15 2011 -0500
@@ -1,6 +1,6 @@
 #include <urweb.h>
 
-uw_Basis_string uw_AjaxUploadFfi_tweakForm(uw_context, uw_Basis_string iframeId, uw_Basis_string submitId);
+uw_Basis_string uw_AjaxUploadFfi_tweakForm(uw_context, uw_Basis_bool autoSubmit, uw_Basis_string iframeId, uw_Basis_string submitId);
 uw_Basis_string uw_AjaxUploadFfi_notifySuccess(uw_context, uw_Basis_string submitId, uw_Basis_int handle);
 
 uw_Basis_string uw_AjaxUploadFfi_idToString(uw_context, uw_Basis_string);
--- a/src/c/Makefile.am	Thu Dec 29 15:26:46 2011 -0500
+++ b/src/c/Makefile.am	Thu Dec 29 15:42:15 2011 -0500
@@ -2,5 +2,5 @@
 
 liburweb_ajaxUpload_la_SOURCES = ajaxUpload.c
 
-AM_CPPFLAGS = -I@INCLUDE@ -I../../include
+AM_CPPFLAGS = -I../../include -I@INCLUDE@
 AM_CFLAGS = -Wimplicit -Wall -Werror
--- a/src/c/Makefile.in	Thu Dec 29 15:26:46 2011 -0500
+++ b/src/c/Makefile.in	Thu Dec 29 15:42:15 2011 -0500
@@ -207,7 +207,7 @@
 top_srcdir = @top_srcdir@
 lib_LTLIBRARIES = liburweb_ajaxUpload.la
 liburweb_ajaxUpload_la_SOURCES = ajaxUpload.c
-AM_CPPFLAGS = -I@INCLUDE@ -I../../include
+AM_CPPFLAGS = -I../../include -I@INCLUDE@
 AM_CFLAGS = -Wimplicit -Wall -Werror
 all: all-am
 
--- a/src/c/ajaxUpload.c	Thu Dec 29 15:26:46 2011 -0500
+++ b/src/c/ajaxUpload.c	Thu Dec 29 15:42:15 2011 -0500
@@ -1,9 +1,8 @@
 #include <ctype.h>
-#include <stdio.h>
 
 #include <ajaxUpload.h>
 
-uw_Basis_string uw_AjaxUploadFfi_tweakForm(uw_context ctx, uw_Basis_string iframeId, uw_Basis_string submitId) {
+uw_Basis_string uw_AjaxUploadFfi_tweakForm(uw_context ctx, uw_Basis_bool autoSubmit, uw_Basis_string iframeId, uw_Basis_string submitId) {
   return uw_Basis_mstrcat(ctx,
                           "<iframe id=\"",
                           iframeId,
@@ -13,7 +12,11 @@
                           submitId,
                           "\"); subm.parentNode.target = \"",
                           iframeId,
-                          "\"; var onSub = subm.onmousedown; subm.onmousedown = undefined; subm.parentNode.onsubmit = function() { onSub(); return true; }; subm.withHandle = subm.onkeydown; subm.onkeydown = undefined; </script>",
+                          "\"; var onSub = subm.onmousedown; subm.onmousedown = undefined; subm.parentNode.onsubmit = function() { onSub(); return true; }; subm.withHandle = subm.onkeydown; subm.onkeydown = undefined; ",
+                          autoSubmit
+                          ? "subm.style.visibility = \"hidden\"; for (var node = subm.previousSibling; node.tagName != \"INPUT\"; node = node.previousSibling); node.onchange = function() { subm.parentNode.submit(); }; "
+                          : "",
+                          "</script>",
                           NULL);
 }
 
--- a/src/ur/ajaxUpload.ur	Thu Dec 29 15:26:46 2011 -0500
+++ b/src/ur/ajaxUpload.ur	Thu Dec 29 15:42:15 2011 -0500
@@ -32,7 +32,15 @@
              WHERE Handle = {[h]});
         return (Found r)
 
-fun render {OnBegin = ob, OnSuccess = os} =
+fun peek h =
+    ro <- oneOrNoRows1 (SELECT scratch.Filename, scratch.MimeType, scratch.Content
+                        FROM scratch
+                        WHERE scratch.Handle = {[h]});
+    return (case ro of
+                None => NotFound
+              | Some r => Found r)
+
+fun render {AutoSubmit = as, OnBegin = ob, OnSuccess = os} =
     iframeId <- fresh;
     submitId <- fresh;
     submitId' <- return (AjaxUploadFfi.idToString submitId);
@@ -50,6 +58,6 @@
             <upload{#File}/>
             <submit action={upload} id={submitId} onmousedown={ob} onkeydown={os}/>
           </form>
-          {AjaxUploadFfi.tweakForm iframeId submitId}
+          {AjaxUploadFfi.tweakForm as iframeId submitId}
         </xml>
     end
--- a/src/ur/ajaxUpload.urs	Thu Dec 29 15:26:46 2011 -0500
+++ b/src/ur/ajaxUpload.urs	Thu Dec 29 15:42:15 2011 -0500
@@ -12,7 +12,12 @@
 val claim : handle -> transaction claim_result
 (* In server-side code, claim ownership of a [handle]'s contents, deleting the persistent record of the file data. *)
 
-val render : {OnBegin : transaction {},
+val peek : handle -> transaction claim_result
+(* Like [claim], but keeps the file in temporary storage.  Beware that files older than 30 minutes may be removed automatically! *)
+
+val render : {AutoSubmit : bool,
+              (* If [True], no extra form submit button is included, and file is uploaded once file selection dialog is closed. *)
+              OnBegin : transaction {},
               (* Run this when an upload begins. *)
               OnSuccess : handle -> transaction {}
               (* Run this after a successful upload. *)}
--- a/src/ur/ajaxUploadFfi.urs	Thu Dec 29 15:26:46 2011 -0500
+++ b/src/ur/ajaxUploadFfi.urs	Thu Dec 29 15:42:15 2011 -0500
@@ -1,4 +1,4 @@
-val tweakForm : id -> id -> xbody
+val tweakForm : bool -> id -> id -> xbody
 val notifySuccess : id -> int -> xbody
 
 val idToString : id -> string