Forum OpenACS Q&A: Form builder troubles

Collapse
Posted by Sean Redmond on

I'm trying to use ad_form for the first time, and I can't get my -edit_data block to execute. At first I couldn't get the -select_query_name to work, which turned out to be a typo, so maybe this is too, but I can't find it.

In the .tcl file:

ad_form -name new_label -form {

	label_id:key(v_bma_ip_labels_label_id_seq)

	{label:text
		{label "Label"}
		{html {size 25}}
	}
	{descrip:text(textarea)
		{label "Description"}
		{html {rows 3 cols 50}}
	}
} -select_query_name get_label -edit_data {
	db_dml update_label { *SQL* } 
} -after_submit {
	ad_returnredirect "index"
}

In the .xql file:

<?xml version="1.0"?>
<queryset>
	<fullquery name="get_label">
		<querytext>
			select
				label_id,
				label,
				descrip
			from
				bma_ip_labels
			where
				label_id=:label_id
		</querytext>
	</fullquery>
	
	<fullquery name="update_label">
		<querytext>
			update bma_ip_labels
				set
					label = :label,
					descrip = :descrip
				where
					label_id = :label_id
		</querytext>
	</fullquery>
</queryset>

The form displays fine, with all the proper values, but when I click "Submit" it doesn't do the update, and doesn't go where -after_submit tells it to. Rather it comes right back to the edit page, with all the changes reset to their unchanged values. The logs only ever show the select_query_name query being run, even for a supposed update. That is the update_label query never gets run at all, so it's not as if it's failing and I'm seeing the results of an update that didn't work.

I've made sure all the files have been reloaded, and even restarted the server. This is OACS 4.6.3

Collapse
2: Re: Form builder troubles (response to 1)
Posted by Dave Bauer on
What does your ad_page_contract definition look like?

It should say:

label_id:integer,optional

or just label_id:integer,notnull, if you don't plan on using that script to process new entries.

Collapse
3: Re: Form builder troubles (response to 2)
Posted by Sean Redmond on
It is:

label_id:integer,optional

Collapse
4: Re: Form builder troubles (response to 1)
Posted by Sean Redmond on

I've narrowed it down somewhat. The ad_form proc is defined in acs-tcl/tcl/form-processing-procs.tcl and adding or updating a record occurs about line 964 (of the version I have installed). Call this B:

if { [info exists new_data] && $__new_p } {
    ad_page_contract_eval uplevel #$level $new_data
    template::element::set_value $form_name __new_p 0
} elseif { [info exists edit_data] && !$__new_p } {
    ad_page_contract_eval uplevel #$level $edit_data
}

This is nested within another condition, starting at line 904. Call this A:

if { [template::form is_valid $form_name] && ![uplevel #$level {set __refreshing_p}] } {
    ....

My page is never getting to B because it is failing the test of A. Specifically, it's failing template::form is_valid, and more specifically, this test (acs-templating/tcl/form-procs.tcl, line 580):

  set level [template::adp_level]

  upvar #$level $id:submission submission

  if { ! $submission } { 
    return 0 
  }

From what I can tell, this variable should get set during an earlier call to template::form create, but I'm not sure how to debug it any further. I'm lost in upvar's

Collapse
5: Re: Form builder troubles (response to 1)
Posted by Dave Bauer on
Sean

ad_form and form builder work fine in OpenACS 4.6.3. If possible plese post the entire tcl file that is handling the processing. To work correctly for editing records you must have passed in the key, label_id in your case, to the tcl page.

Collapse
6: Re: Form builder troubles (response to 5)
Posted by Sean Redmond on
Dave, Here is the whole TCL file (there's not much more to it)
ad_page_contract {
                                                                                
    Add an a label for an ip range
                                                                                
    @author Sean Redmond (sean@jiffycomp.com)
    @creation-date 2004-04-23
    @cvs-id $Id: index.tcl,v 1.6 2002/12/17 16:43:06 nsadmin Exp $
} {
        label_id:integer,optional
}
 
set package_id [ad_conn package_id]
set context_bar [list]
 
if {[exists_and_not_null label_id]} {
        set page_title "Edit Label"
} else {
        ad_require_permission $package_id create
        set page_title "Add a Label"
}
 
 
ad_form -name new_label -form {
 
        label_id:key(v_bma_ip_labels_label_id_seq)
 
        {label:text
                {label "Label"}
                {html {size 25}}
        }
        {descrip:text(textarea)
                {label "Description"}
                {html {rows 3 cols 50}}
        }
} -select_query_name get_label -edit_data {
        db_dml update_label { *SQL* }
} -after_submit {
        ad_returnredirect "index"
}

So it's named one-label.tcl and if invoke it with something like one-label?label_id=8, I get a form with the expected values filled in (I put a few in manually). If I change anything and hit submit, I get the same page with the old values. That would seem to indicate that it's at least getting the right label_id after the submit since it returns to the same record, even though it doesn't do the update.

Thanks.
Collapse
7: Re: Form builder troubles (response to 1)
Posted by Tak-Hung Yu on
I think you have to call ad_form_new_p instead of exists_and_not_null.

if {![ad_form_new_p -key label_id]} {
    set page_title "Edit Label"
} else {
    ....
}

Jon has a rather extensive document on how to use ad_form at http://jongriffin.com/static/openacs/ad_form/using-ad-form.

Collapse
8: Re: Form builder troubles (response to 7)
Posted by Sean Redmond on

I made this change, but it didn't have any effect.

I've looked at Jon's documentation and I still can't see where I'm going wrong.

Collapse
9: Re: Form builder troubles (response to 1)
Posted by Ben Chan on
maybe try this?  I just tend to make sure each switch has it's own braces.

-select_query_name {
  get_label
} -edit_data {
        db_dml update_label SQL
}

Collapse
10: Re: Form builder troubles (response to 1)
Posted by Jeff Lu on
Sean, You need to add descrip to ad_page_contract, set it as optional.
ad_page_contract {
                                                                                
    Add an a label for an ip range
                                                                                
    @author Sean Redmond (sean@jiffycomp.com)
    @creation-date 2004-04-23
    @cvs-id $Id: index.tcl,v 1.6 2002/12/17 16:43:06 nsadmin Exp $
} {
        label_id:integer,optional
        descrip:optional
}
Collapse
Posted by Sean Redmond on

Sean, You need to add descrip to ad_page_contract, set it as optional.

Jeff, This is true, but it doesn't fix the problem. If the edit_data block were ever executed, the missing variable would cause an error, but it never gets that far. When it should be updating the data, it always goes to the select_query_name instead.

Collapse
12: Re: Form builder troubles (response to 1)
Posted by Sean Redmond on

Thanks for everyone's help so far, but something is definitely busted in my ACS installation.

I grepped for any other scripts with an edit_data block and found a bunch in bug tracker. So I mounted an instance of bug tracker and ran into exactly the same problem: no updates are ever done via forms that use form builder -- unless bug tracker is coincidentally broken in the same subtle way as my script (not likely)

Anyone have a clue where to start looking for the problem?

Collapse
13: Re: Form builder troubles (response to 1)
Posted by Jade Rubick on
Sean, it's hard to say.

Ad_form is problematic, in my view. I'm actually considering going back to using the underlying form builder -- I'm trying to convert one of my scripts right now.

Does anybody else know what's going on here?