Forum OpenACS Development: Simple page using ad_form and -on_refresh

I am trying to do something quite complicated using ad_form and -on-refresh. However, I cannot even get "the basic stuff" working. Can someone give a _simple_ example of how to update the values of fields displayed to the user in the -on_refresh block?

Here's my ad-form call. gp_refresh is a simple widget which set's __refreshing_p and submits the form.

ad_form -name homepage_edit -form {
    {hp_title:text {label {Homepage Title}}}
    {test:gp_refresh}
  } -on_refresh {
    set hp_title "Refreshing"
  }

Collapse
Posted by Nis Jørgensen on
Hmmm - in that thread, the most elaborate example contains this:

-on_refresh {
    # didn't use -on_refresh
    # set subcategory_options before ad_form
    # because I couldn't find a way to set them here
}

So at least I am not alone with my problem 😊

Another post lead me to this solution for doing what I want to do:
-on_refresh {
  template::element::set_value homepage_edit hp_title REFRESHING
}

I would have assumed that ad_form_set_value would work also, but it doesn't. It doesn't give an error either. Strange.

Collapse
Posted by Nis Jørgensen on
OK, I am changing this from a "How do I make this work" to a "Wouldn't it be smarter if it worked like this"

My suggestion is this: Variables set in the on_refresh block should be automatically assigned to elements of the same name - similar to how on_request works.

I am trying to get this working by frankenstein programming - but I don't really understand ad_form (or the form builder) well enough to know if I am breaking things.

Collapse
Posted by Jade Rubick on
Nis, I'm running into the exact same problem. I completely agree that -on_fresh's behavior is not intuitive.

What did you end up doing to get around this issue?

Collapse
Posted by Nis Jørgensen on
I believe I worked around it by referencing the form fields directly in the on_refresh (ie  template::element::set_value $formname $element $value).
Collapse
Posted by Mark Aufflick on
In  certain circumstances (to do with bcms i think) I had to add the following to the page code:

if {[ns_queryget "form:id"] eq "simpleform" && [ns_queryget "__refreshing_p"]} {
    # FIX bogus - assumes that if simpleform is being refreshed, it
    # should be in edit mode. A safe asumption, but not really how it
    # should be done.

    set form_mode edit
}

I don't think I've altered the values at the form level - I've only used __refreshing_p within custom widgets (where you have to access the form fields directly anyway)

Collapse
Posted by Jade Rubick on
Thanks, Nis. I've put this on the documentation on HEAD, so it should be in OpenACS 5.2's documentation.
Collapse
Posted by Nis Jørgensen on
For the record, I have created the below patch that allows for setting form values in on_refresh. I haven't tested all the posibilities - just a test form to see that it "works" for my simple test case.

Please note that part of this code is just magical incantations to me. I have a feeling ad_form could use a little refactoring ... I might get around to that the next time it bites me.
Index: form-processing-procs.tcl
===================================================================
RCS file: /usr2/cvsroot/mlm/packages/acs-tcl/tcl/form-processing-procs.tcl,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 form-processing-procs.tcl
--- form-processing-procs.tcl  21 Apr 2004 09:15:40 -0000      1.1.1.1
+++ form-processing-procs.tcl  11 Nov 2004 18:31:37 -0000
@@ -989,6 +989,25 @@

        if { [info exists on_refresh] } {
            ad_page_contract_eval uplevel #$level $on_refresh
+
+            # NAJ: If values are set in the on_refresh block, stuff them into the form fields.
+            # This code is just a copy-paste (and a little gluing) of code from the other branches
+            # I don't understand the datas structures well enough to know if there is an easier way to
+            # do this - or if I am doing it in a foolproof way.
+
+            foreach element_name $af_element_names($form_name) {
+                if { [llength $element_name] == 1 } {
+                    if { [uplevel \#$level [list info exists $element_name]] } {
+                        set myvalues [uplevel \#$level [list set $element_name]]
+                        if { [info exists af_flag_list(${form_name}__$element_name)] && \
+                            [lsearch $af_flag_list(${form_name}__$element_name) multiple] >= 0 } {
+                            template::element set_values $form_name $element_name $myvalues
+                        } else {
+                            template::element set_value $form_name $element_name $myvalues
+                        }
+                    }
+                }
+            }
        }
    }

===================================================================

Collapse
Posted by Jade Rubick on
Nis: you might want to submit this in bug-tracker, to make sure it gets applied.
Collapse
Posted by Nis Jørgensen on
Hmm - the patch has problems with some existing form widgets. I don't have time to track this down now.

So don't use this at home.