[html-formfu] [patch] fix _Group's empty_first option when used in arg hash

Ronald J Kimball rkimball+formfu at pangeamedia.com
Wed Mar 4 16:59:19 GMT 2009


The _Group element type has an empty_first option, which can be used to =

specify that an empty option should be added at the start of the option =

list.  Unfortunately, the empty_first option is unreliable when =

specified in the element's argument hash.  It depends on the order of =

keys in the hash as to whether it will work or not.

Here's an example:

---
elements:
   - type: Select
     name: test
     values:
       - first
       - second
     empty_first: 1
     empty_first_label_xml: ' '

produces:

<form action=3D"" method=3D"post">
<div class=3D"select">
<select name=3D"test">
<option value=3D"first">First</option>
<option value=3D"second">Second</option>
</select>
</div>
</form>

As you can see, the empty first option was not added.


_Group expects that $self->empty_first() will return true while =

executing $self->options or $self->values.  However, this is not =

guaranteed, because ObjectUtil's populate() method may call =

$self->options(...) or $self->values(...) /before/ it calls =

$self->empty_first(...):

     eval {
         map { $self->$_( $args{$_} ) } keys %args;

         map { $self->$_( $defer{$_} ) }
             grep { exists $defer{$_} }
                 @keys
             ;
     };

The methods are called in whatever order they're returned by keys %args. =

  Neither 'options' nor 'values' are in the list of keys that should be =

deferred.  Here's the order that happened to occur for my test above:

   empty_first_label_xml,name,values,empty_first


If I add the following statement at the beginning of the eval, before =

the first map:

       $self->empty_first($args{'empty_first'})
         if exists $args{'empty_first';

Then the empty first option is added as expected:

<form action=3D"" method=3D"post">
<div class=3D"select">
<select name=3D"test">
<option value=3D"">&nbsp;</option>
<option value=3D"first">First</option>
<option value=3D"second">Second</option>
</select>
</div>
</form>


The obvious fix is to add 'options' and 'values' at the beginning of the =

list of deferred keys, to make sure they're called after empty_first et =

al., but still called before the other deferred keys.

Patch attached.

Ronald
-------------- next part --------------
diff -r -uw HTML-FormFu-0.03007/lib/HTML/FormFu/ObjectUtil.pm HTML-FormFu-0=
.03007.empty_first/lib/HTML/FormFu/ObjectUtil.pm
--- HTML-FormFu-0.03007/lib/HTML/FormFu/ObjectUtil.pm	2008-10-30 10:13:32.0=
00000000 -0400
+++ HTML-FormFu-0.03007.empty_first/lib/HTML/FormFu/ObjectUtil.pm	2009-03-0=
4 11:51:35.000000000 -0500
@@ -337,6 +337,8 @@
     }
 =

     my @keys =3D qw(
+        options
+        values
         default_args
         auto_fieldset
         load_config_file


More information about the HTML-FormFu mailing list