changeset 1785:ffd7ed3bc0b7

Basis.giveFocus
author Adam Chlipala <adam@chlipala.net>
date Sat, 21 Jul 2012 11:59:41 -0400
parents e6bc6bbd7a32
children d794149b3713
files doc/manual.tex lib/js/urweb.js lib/ur/basis.urs src/settings.sml tests/focus.ur
diffstat 5 files changed, 37 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/doc/manual.tex	Sat Jul 21 10:12:35 2012 -0400
+++ b/doc/manual.tex	Sat Jul 21 11:59:41 2012 -0400
@@ -2093,7 +2093,13 @@
   \mt{val} \; \mt{fresh} : \mt{transaction} \; \mt{id}
 \end{array}$$
 
-The \cd{fresh} function is allowed on both server and client, but there is no other way to create IDs, which includes lack of a way to force an ID to match a particular string.  The only semantic importance of IDs within Ur/Web is in uses of the HTML \cd{<label>} tag.  IDs play a much more central role in mainstream JavaScript programming, but Ur/Web uses a very different model to enable changes to particular nodes of a page tree, as the next manual subsection explains.  IDs may still be useful in interfacing with JavaScript code (for instance, through Ur/Web's FFI).
+The \cd{fresh} function is allowed on both server and client, but there is no other way to create IDs, which includes lack of a way to force an ID to match a particular string.  The main semantic importance of IDs within Ur/Web is in uses of the HTML \cd{<label>} tag.  IDs play a much more central role in mainstream JavaScript programming, but Ur/Web uses a very different model to enable changes to particular nodes of a page tree, as the next manual subsection explains.  IDs may still be useful in interfacing with JavaScript code (for instance, through Ur/Web's FFI).
+
+One further use of IDs is as handles for requesting that \emph{focus} be given to specific tags.
+
+$$\begin{array}{l}
+  \mt{val} \; \mt{giveFocus} : \mt{id} \to \mt{transaction} \; \mt{unit}
+\end{array}$$
 
 \subsubsection{\label{signals}Functional-Reactive Page Generation}
 
--- a/lib/js/urweb.js	Sat Jul 21 10:12:35 2012 -0400
+++ b/lib/js/urweb.js	Sat Jul 21 11:59:41 2012 -0400
@@ -1824,5 +1824,14 @@
     return "uw" + (--nextId);
 }
 
+function giveFocus(id) {
+    var node = document.getElementById(id);
+
+    if (node)
+        node.focus();
+    else
+        er("Tried to give focus to ID not used in document: " + id);
+}
+
 
 // App-specific code
--- a/lib/ur/basis.urs	Sat Jul 21 10:12:35 2012 -0400
+++ b/lib/ur/basis.urs	Sat Jul 21 11:59:41 2012 -0400
@@ -762,6 +762,7 @@
 
 type id
 val fresh : transaction id
+val giveFocus : id -> transaction unit
 
 val dyn : ctx ::: {Unit} -> use ::: {Type} -> bind ::: {Type} -> [ctx ~ [Dyn]] => unit
           -> tag [Signal = signal (xml ([Dyn] ++ ctx) use bind)] ([Dyn] ++ ctx) [] use bind
--- a/src/settings.sml	Sat Jul 21 10:12:35 2012 -0400
+++ b/src/settings.sml	Sat Jul 21 11:59:41 2012 -0400
@@ -177,7 +177,8 @@
                         "onMouseup",
                         "preventDefault",
                         "stopPropagation",
-                        "fresh"]
+                        "fresh",
+                        "giveFocus"]
 
 val benign = ref benignBase
 fun setBenignEffectful ls = benign := S.addList (benignBase, ls)
@@ -205,7 +206,8 @@
                         "onMousedown",
                         "onMouseup",
                         "preventDefault",
-                        "stopPropagation"]
+                        "stopPropagation",
+                        "giveFocus"]
 val client = ref clientBase
 fun setClientOnly ls = client := S.addList (clientBase, ls)
 fun isClientOnly x = S.member (!client, x)
@@ -322,7 +324,8 @@
 
                           ("atom", "atom"),
                           ("css_url", "css_url"),
-                          ("property", "property")]
+                          ("property", "property"),
+                          ("giveFocus", "giveFocus")]
 val jsFuncs = ref jsFuncsBase
 fun setJsFuncs ls = jsFuncs := foldl (fn ((k, v), m) => M.insert (m, k, v)) jsFuncsBase ls
 fun jsFunc x = M.find (!jsFuncs, x)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/focus.ur	Sat Jul 21 11:59:41 2012 -0400
@@ -0,0 +1,14 @@
+fun main () : transaction page =
+    id1 <- fresh;
+    id2 <- fresh;
+    s1 <- source "";
+    s2 <- source "";
+    which <- source False;
+
+    return <xml><body>
+      <ctextbox id={id1} source={s1}/>
+      <ctextbox id={id2} source={s2}/>
+      <button onclick={fn _ => w <- get which;
+                          set which (not w);
+                          giveFocus (if w then id1 else id2)}/>
+    </body></xml>