Warning: Can't synchronize with repository "(default)" (Unsupported version control system "svn": No module named svn). Look in the Trac log for more information.

Ticket #849 (closed enhancement: invalid)

Opened 11 years ago

Last modified 10 years ago

[PATCH] error info messages within a form

Reported by: jiri.popek@… Owned by: anonymous
Priority: normal Milestone:
Component: FastData Version: 0.9a5
Severity: normal Keywords:
Cc:

Description

  • Some little changes in formmaker.py and datacontroller made to get a nice info messages when form does not pass validation. It is very nice to inform a user, that some of the fields were not filled in properly.
  • Form fields now created according SQLObject class parameter order

Attachments

datacontroller.py.diff Download (2.4 KB) - added by jiri.popek@… 11 years ago.
formmaker.py.diff Download (2.1 KB) - added by jiri.popek@… 11 years ago.

Change History

Changed 11 years ago by jiri.popek@…

Changed 11 years ago by jiri.popek@…

comment:1 Changed 11 years ago by anonymous

  • Summary changed from error info messages within a form to [PATCH] error info messages within a form

comment:2 Changed 11 years ago by alberto

After a quick skim at the patch...

  • are you sure you're using g_error_fields in a thread safe way?
  • why place the errors where the help_text belongs.
  • Why not use TG's mechanix to handle validation errors (validate() decorator)

Alberto

comment:3 Changed 11 years ago by anonymous

  • are you sure you're using g_error_fields in a thread safe way?

No, I am not sure - but if anyone will found it bugy, I will find a better way to do it

  • why place the errors where the help_text belongs.

Because there is no better built-in support to print the error messages within the form. Changing TG widgets classes would take much more time. (Anyway - help_text param in formmaker was not used at all)

  • Why not use TG's mechanix to handle validation errors (validate() decorator)

TG's validate() is used to get tg_errors dictionary in controller class. Then is passed to function for creating the form. Form creating function looks for his name (as key in tg_errors) and shows value (validation error message) as help_text

comment:4 Changed 11 years ago by alberto

When validate() validates a form (implicitly with the tg_errors kw argument as you're suggesting or explicitly by decorating the method with validate) it places a dict with the unpacked FE.Invalid expception at cherrypy.request.validation_errors.

If you then branch execution (or let @error_handler() do it) from the method receiving the data to the one that submitted the form, then errors *and* previous input will get displayed magically at the form. No need to hack on the help_text attribute which, who knows, might get used in the future ;) Just make sure you branch to the other method, do *not* use HTTP redirects as that request data will then vanish.

This will also ensure that validation_errors get passed in a thread-safe way (through cp.request) without extra hassle.

The functionallity you're trying to implement is very useful indeed, but it would be better to use TG's existing mechanisms for doing things as it could also serve as documentation IMO. I'm afraid, however, that FastData? got a little bit outdated in this respect... :(

HTH, Alberto

comment:5 Changed 11 years ago by alberto

I'm in the process of writing a TG tutorial explainig this and other things which might help you:  http://svn.toscat.net/tg_tutorial/trunk/tgsimpleblog/controllers.py

HTH, Alberto

comment:6 Changed 11 years ago by Jiri Popek <jiri.popek@…>

Great! This works exactly I wanted to... ;) So, FastData? needs to be updated a little bit. However when I created a form class with

MultipleSelectField(name='genres', validator=MultipleSelection(), options=get_all_genres, label=_('Genres'))

MultipleSelectField? doesn't reuse selected options according previously submitted selections (which doesn't passed through validation). TextField? does. Where is the right place where widgets "refills" itself according to previously submitted values?

Jiri

comment:7 Changed 11 years ago by michele

Jiri, try to avoid the MultipleSelection? validator, the MultipleSelectionField? will try to automatically guess the right validator to use.

comment:8 Changed 11 years ago by Jiri Popek <jiri.popek@…>

Unfortunately not-raises an exception:

File "turbogears/widgets/forms.py", line 715, in __init__
    raise ValueError, ("No validator specified and couldn't "
ValueError: No validator specified and couldn't guess one. I cannot work properly without it

This exception is raised when fetching from DB using:

def get_all_genres():
        return [(a.id, a.name) for a in Genre.select()]

which returns [(0, u'Comedy'), (1, u'Sci-Fi'), (2, u'History')], but if get_all_genres() returns a fixed list:

def get_all_genres():
        return [(0, u'Comedy'), (1, u'Sci-Fi'), (2, u'History')]

the code works fine. Is there bug in MultipleSelectField? ? Thanx for all posts anyway.

Jiri

comment:9 Changed 11 years ago by michele

No, it should work, I need to test this case but ATM I can't make it.

In the meanwhile pass a validator=Int() and all should be fine.

comment:10 Changed 11 years ago by Jiri Popek <jiri.popek@…>

Thanks, it works using validator=Int()... Finally-what is necessary for MultipleSelectField? to automatically selelect items according to RelatedJoin? values?

class Genre(SQLObject):
    titles = RelatedJoin('Title')

class Title(SQLObject):
    genres         = RelatedJoin('Genre')

def get_all_genres():
        return [(int(a.id), "%s" % a.name) for a in Genre.select()]

FORM:
genres = MultipleSelectField(name='genres', options=get_all_genres, label=_('Genres'), validator=Int())

Thank you Jiri

comment:11 Changed 11 years ago by alberto

Pass it as a value when prepopulation the form:

value = {
    'genres' : [1,4,7],
}
form.display(value)

HTH, Alberto

comment:12 Changed 11 years ago by alberto

More explicitly:

genres = [genre.id for genre in Genre.select()]
value = {
    'genres' : genres,
}
form.display(value)

comment:13 Changed 11 years ago by jiri.popek@…

Great!

Now I know how this automatic filling forms in works. I created patch to solve problem with automatic selecting items within MultipleSelectField? by data from join column and submitted it as Ticket 858.

Thanx to all for handy information.

Jiri

comment:14 Changed 11 years ago by kevin

  • Status changed from new to closed
  • Resolution set to invalid

the problems that Alberto pointed out in the beginning are correct... it's not threadsafe, we shouldn't use help_text for this, and it's better to use @validate. I'm closing this ticket.

Note: See TracTickets for help on using tickets.