Your version that breaks mainly breaks because you are mutating the record and recomputing the formlet, rather than saving the formlet in the continuation for both the display and the processing.<div><br></div><div>As far as what you&#39;d like to write, I think that&#39;s a good start, but there&#39;s a few problems.</div>
<div><br></div><div>1) A line like</div><div><br></div><div>{(to-string (required (text-input))) . =&gt; . name}</div><div><br></div><div>fails to explain how the name can go back into the formlet on the LHS, because in general formlets may not be able to have a default value like that.</div>
<div><br></div><div>2) A line like</div><div><br></div><div>(formlet-fill record-formlet record)</div><div><br></div><div>seems to indicate that you will fill the formlet from the contents of record, which is a hash table, but the results of the formlet are six values, so there is no connection between the thing that comes in and the thing that comes out. And in general that&#39;s pretty hard because the output can be any computation of the values bound by the formlet.</div>
<div><br></div><div>I can imagine implementing something like...</div><div><br></div><div><div>(define record-formlet</div><div>            (formlet</div><div>             ;; Define the input format</div><div>             ([name (hash-ref this &#39;name)]</div>
<div>              [company (hash-ref this &#39;company)]</div><div>              [address (hash-ref this &#39;company)]</div><div>              [city (hash-ref this &#39;city)]</div><div>              [state (hash-ref this &#39;state)]</div>
<div>              [zip (hash-ref this &#39;zip)])</div><div>             ;; Define the display format / input mapping</div><div>             (#%# ,{(to-string (required (text-input))) . &lt;=&gt; . name}</div><div>                  ,{(to-string (required (text-input))) . &lt;=&gt; . company}</div>
<div>                  ,{(to-string (required (text-input))) . &lt;=&gt; . address}</div><div>                  ,{(to-string (required (text-input))) . &lt;=&gt; . city}</div><div>                  ,{(to-string (required (text-input))) . &lt;=&gt; . state}</div>
<div>                  ,{(to-string (required (text-input))) . &lt;=&gt; . zip})</div><div>             ;; Define the output format</div><div>             (values name company address city state zip)))</div><div><br></div>
<div>where the rest of your code works, except you&#39;d also need to use the same servlet when you process (because it may use the old contents as defaults.) I can imagine a set of macros for restricted kinds of matching input and output (like hash tables or lists)</div>
<div><br></div><div>Right now, a formlet&#39;s type is basically (Nat -&gt; (values Display (Bindings -&gt; Answer)), but this would make it so its type was something like (Nat LastAnswer -&gt; (values Display (Bindings -&gt; Answer)), including the formlets that are returned from to-string, required, and text-input.</div>
<div><br></div><div>Does that seem more palatable?</div><div><br></div><div>Jay</div><br><div class="gmail_quote">On Sat, Nov 19, 2011 at 7:32 AM, Jordan Schatz <span dir="ltr">&lt;<a href="mailto:jordan@noionlabs.com">jordan@noionlabs.com</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">Let me see if I can explain what I&#39;m after better. The app that I am<br>
porting is mostly CRUD (Create Read Update Delete), one twist though is<br>
that we never explicitly use create, if a user wants to create a new<br>
record they actually edit a copy of the most recent record, so a form<br>
always has values (though not necessarily the same &quot;default&quot; values).<br>
<br>
If I understand the docs, then this:<br>
<a href="http://noionlabs.com/formlets/save-formlet.rkt" target="_blank">http://noionlabs.com/formlets/save-formlet.rkt</a><br>
Is the right way to do it. The general pattern is that to have a formlets<br>
with values I need to have a formlet-maker function, that creates the<br>
formlet, and I need to save that formlet for the formlet-process<br>
function.<br>
<br>
The docs seemed to suggest that I needed to save that formlet (and not<br>
use formlet-maker to make a new one) for use with formlet-process, but<br>
this <a href="http://noionlabs.com/formlets/generate-new-formlet.rkt" target="_blank">http://noionlabs.com/formlets/generate-new-formlet.rkt</a> does work. I<br>
assume its not common/best practice though since its easy to break:<br>
<a href="http://noionlabs.com/formlets/breaks.rkt" target="_blank">http://noionlabs.com/formlets/breaks.rkt</a><br>
<br>
What I&#39;d like to be able to write is:<br>
<a href="http://noionlabs.com/formlets/formlet-fill.rkt" target="_blank">http://noionlabs.com/formlets/formlet-fill.rkt</a><br>
<br>
I don&#39;t really want to make a new formlet, or save it for use in the<br>
processing step, I just want to be able to modify the values in the<br>
formlet before sending it to the client.<br>
<br>
Shalom,<br>
<font color="#888888">Jordan<br>
</font><div><div></div><div class="h5"><br>
On Fri, Nov 18, 2011 at 04:10:29PM -0700, Jay McCarthy wrote:<br>
&gt; You need to make a new formlet that knows about the default values.<br>
&gt;<br>
&gt; We could imagine a macro that makes this nicer, but in general it will need<br>
&gt; to be something that creates a new one.<br>
&gt;<br>
&gt; Is there some reason you don&#39;t want to do that?<br>
&gt;<br>
&gt; I can imagine something like (formlet-display) that took the old values,<br>
&gt; but then it would be more monad-like than arrow-like, and wouldn&#39;t really<br>
&gt; be a formlet. If you can clarify your use case, it may be worth<br>
&gt; investigating.<br>
&gt;<br>
&gt; Jay<br>
&gt;<br>
&gt; On Fri, Nov 18, 2011 at 1:13 PM, Jordan Schatz &lt;<a href="mailto:jordan@noionlabs.com">jordan@noionlabs.com</a>&gt; wrote:<br>
&gt;<br>
&gt; &gt;<br>
&gt; &gt; I have a pattern of user interaction that is common in my web app:<br>
&gt; &gt;<br>
&gt; &gt; I have a db record, I present it to the user in a form, the user edits<br>
&gt; &gt; the form, submits it, server side logic validates it, and then returns<br>
&gt; &gt; the same form with the updated record.<br>
&gt; &gt;<br>
&gt; &gt; I want to port the app to Racket, and I thought formlets would be just<br>
&gt; &gt; the thing, but I don&#39;t see how to fill the values into the formlet<br>
&gt; &gt; without making a new formlet... seems I need a (formlet-fill<br>
&gt; &gt; (some-values)) to go along with the formlet-display and formlet-process.<br>
&gt; &gt;<br>
&gt; &gt; Here is what I have: (Which doesn&#39;t work)<br>
&gt; &gt;<br>
&gt; &gt; ----------------------------------------------------------------------<br>
&gt; &gt; #lang web-server/insta<br>
&gt; &gt;<br>
&gt; &gt; (require web-server/formlets)<br>
&gt; &gt;<br>
&gt; &gt; (define record (hasheq &#39;title &quot;this is a title&quot;<br>
&gt; &gt;                       &#39;body &quot;post body&quot;))<br>
&gt; &gt;<br>
&gt; &gt; (define (start request)<br>
&gt; &gt;  (edit-record request))<br>
&gt; &gt;<br>
&gt; &gt; (define (edit-record request)<br>
&gt; &gt;  (local [(define (record-formlet our-values)<br>
&gt; &gt;            (formlet<br>
&gt; &gt;             (#%# ,{(text-input #:value (string-&gt;bytes/utf-8 (hash-ref<br>
&gt; &gt; our-values &#39;title))) . =&gt; . title}<br>
&gt; &gt;                  ,{(text-input #:value (string-&gt;bytes/utf-8 (hash-ref<br>
&gt; &gt; our-values &#39;body))) . =&gt; . body})<br>
&gt; &gt;             (values title body)))<br>
&gt; &gt;<br>
&gt; &gt;          (define (handle-response request)<br>
&gt; &gt;            (define-values (title body)<br>
&gt; &gt;              (formlet-process our-formlet request))<br>
&gt; &gt;            (set! record (hasheq &#39;title title<br>
&gt; &gt;                                 &#39;body body))<br>
&gt; &gt;            (start (redirect/get)))<br>
&gt; &gt;<br>
&gt; &gt;          (define (response-generator embed/url)<br>
&gt; &gt;            (response/xexpr<br>
&gt; &gt;             `(html<br>
&gt; &gt;               (form ([action ,(embed/url handle-response)])<br>
&gt; &gt;                     ,@(formlet-display our-formlet)<br>
&gt; &gt;                     (input ([type &quot;submit&quot;]))))))]<br>
&gt; &gt;<br>
&gt; &gt;          (send/suspend/dispatch response-generator)))<br>
&gt; &gt;<br>
&gt; &gt; ----------------------------------------------------------------------<br>
&gt; &gt;<br>
&gt; &gt; It seems like this would be a very common pattern... what is the &quot;normal&quot;<br>
&gt; &gt; way to do it?<br>
&gt; &gt;<br>
&gt; &gt; Thanks,<br>
&gt; &gt; Jordan<br>
&gt; &gt; _________________________________________________<br>
&gt; &gt;  For list-related administrative tasks:<br>
&gt; &gt;  <a href="http://lists.racket-lang.org/listinfo/users" target="_blank">http://lists.racket-lang.org/listinfo/users</a><br>
&gt; &gt;<br>
&gt;<br>
&gt;<br>
&gt;<br>
&gt; --<br>
&gt; Jay McCarthy &lt;<a href="mailto:jay@cs.byu.edu">jay@cs.byu.edu</a>&gt;<br>
&gt; Assistant Professor / Brigham Young University<br>
&gt; <a href="http://faculty.cs.byu.edu/~jay" target="_blank">http://faculty.cs.byu.edu/~jay</a><br>
&gt;<br>
&gt; &quot;The glory of God is Intelligence&quot; - D&amp;C 93<br>
</div></div></blockquote></div><br><br clear="all"><div><br></div>-- <br>Jay McCarthy &lt;<a href="mailto:jay@cs.byu.edu" target="_blank">jay@cs.byu.edu</a>&gt;<br>Assistant Professor / Brigham Young University<br><a href="http://faculty.cs.byu.edu/~jay" target="_blank">http://faculty.cs.byu.edu/~jay</a><br>
<br>&quot;The glory of God is Intelligence&quot; - D&amp;C 93<br>
</div>