[Html-widget] latest formfu developments

Carl Franks fireartist at gmail.com
Mon Feb 26 11:49:12 GMT 2007


On 24/02/07, Mario Minati <mario at minati.de> wrote:
> Carl Franks schrieb:
> > I18N support has been added, with all error messages being moved out
> > to the FormFu/I18N/en.pm package.
> I discovered that and found a bug (probably).
> When defining a constraint like this:
> $form->constraint( Required => qw/shortname name/ )->message('mm -
> Required. ');
> It tries to get a translation for 'mm - Required. ', which of course is
> not available.
> So I think we need a way to bypass the I18N.

Previously, the field 'label', 'comment' and 'value' accessors had
*_xml() varients, for ensuring that the output isn't html-escaped.
Last week as an experimental feature, I also added a *_loc() varient,
as the means for passing a string which should be localised.

I've now extended this to the constraints and errors, so they have
message(), message_xml() and message_loc()

I've described it as experimental, because I'm not sure yet if this is
the best solution, so of course it may change.

> An other question about the FormFu Controller:
> First I was really amazed by the idea of creating forms from yml, but
> than I realized, that I need Callback-constraints and to incoporate data
> from different tables into select fields, which won't work via yml files.
> Then I tried to use the FormFu Controller in FormMethod style to create
> the form. But I don't understand yet how to create the data for the
> populate function. If it is also 'only' a hashref like in the .t-files
> than I also cannot create callbacks.

A hashref can hold code-refs, so something like this would work:
sub my_sub_which_returns_a_form_hashref {
  return {
    constraints => [
      [ Callback => 'foo', { callback => sub { #do something# } } ],
    ],
  };
}

You could use the FormMethod action, which could even load the bulk of
the form from a config file, and then just add the things which need
to be done programatically.

Because load_config_file() uses Config::Any - which supports loading
perl files - you could still define your programatic constraints in a
config file (as long as it doesn't require access to runtime data)

As far as getting db data into select fields is concerned, there's not
really any way around doing that somewhere in your code.
If you're using DBIx::Class, you could create a db-specific formfu
element which gets the data itself, by accessing the dbic classes
directly.

> If I am right (don't hope so) how can I create a form, as with the Form
> Action the result gets calculated before I could add any elements
> programatically.

I find that sometimes I have to overwrite the result that the Action created:
    $db->fill_formfu_values( $form );
    $c->stash->{result} = $form->result;

Because as well as modifying the form object, you can modify the
result object using add_valid() and add_error() - it's not really
practical to always use an auto-generated result. I can't really see
any way round this.

> I uploaded my first adjustments, but there will be more to come.
> One idea I am having in my mind is to provide an icon for every label so
> the user has an improved GUI experience. What do you think is the best
> way to realize that, with the xml attributes or enhanceing the code?

I'm thinking of adding some sort of stash for each element, so you can
pass non-standard data around the code and to the templates.
That way you could set something like
    $element->stash->{icon} = 'help';
Then maybe in the 'field' template file, add an appropriate block to handle it.

> I found the following problems in the code you send me two weeks ago, so
> I am not sure if they are still relevant:
> - a fieldset cannot receive class attribute with add_container_attr,
> only add_attributes worked
>     my $fs_last = $form->element('Fieldset')->add_attributes( { class =>
> 'fs_submit_area' } );

Yes, only elements which inherit from 'field' have
container_attributes() - in that case attributes() refers to the
actual input/select/etc tag.
With Fieldset (which inherits from Block) attributes() refers to the
actual block itself, so there is no other container.
Do you think that for Blocks, container_attributes() should be
provided as an alias for attributes() ?

Which reminds me - I need to check how Multi handles this - as it's a
bit of a half-Multi and half-field.

>   Where do you think should be the place for the errors, where the
> labels are, under the labels, where the comments are or under the comments?
>   Can we provide a way to switch that programatically (ease of use) or
> you think changing the templates is always the way to go?

Yeah, I don't really think anything like this belongs in the code - if
it can't be handled with css, then that's why each project has it's
own copy of the TT template files - so they can be easily customised.

> I have an other idea of extending the formfu. Actually It's more a need
> than an idea.
> I need forms to submit n-times the same field, e. g. I want to be able
> to submit telephone numbers, but don't know if it will be only one or ten.
> My database is that flexible that it can hold as many numbers as given.
> Now I would like to create an javascript-supported form which gives me
> in the beginning one field for a telephone number and a '+'-button which
> creates an additional field.
> This concept should not only work for one single field that can be
> repeated but also for a complete fieldset, so that I could submit
> multiple address to give an other example.
>
> What do you think. I'll do the codeing, but I'll need definetly your
> help on how to integrate it in the structures of formfu.

okay - I'll have to think some more about this one :)

Thanks for your feedback though, it's been very helpful.

Carl



More information about the Html-widget mailing list