*** VVMSelectWidget - OPTIONS chain widget for web2py ***
*** Created by Vadim V. Mostovoy, vadim *at* routix.net ***
db.define_table('Kind',
Field('Name', length=50, unique=True, required=True, notnull=True, label="Product kind"),
format='%(Name)s')
db.define_table('Category',
Field('Kind_id', db.Kind, required=True, notnull=True, label="Kind"),
Field('Name', length=50, required=True, notnull=True, label="Category name"),
format='%(Name)s')
db.define_table('Subcategory',
Field('Category_id', db.Category, required=True, notnull=True, label="Category"),
Field('Name', length=50, required=True, notnull=True, label="Subcategory name"),
format='%(Name)s')
db.define_table('Product',
Field('Subcategory_id', db.Subcategory, required=True, notnull=True, label="Product group"),
Field('Name', length=100, required=True, notnull=True),
format='%(Name)s')
EXAMPLES:
1. Simple way
# define tables hierarchy
sel_widget = VVMSelectWidget(db.Kind, db.Category, db.Subcategory)
# set widget, note: you must set widget to field with "set_widget_to()" method!
sel_widget.set_widget_to(db.Product.Subcategory_id)
return dict(crud=crud.create(db.Product))
# or:
#return dict(crud=crud.update(db.Product, 13))
2. More configurable way
# fields formats/representations; if all or some omited - default formats
# will be used; Formats can be either strings or functions
formats = dict(Kind="%(Name)s", Category="%(Name)s", Subcategory=lambda row: "%(Name)s (%(id)s)" % row)
# placeholder used when selected nothing; if omited - default will be used
# can be either string or function
placeholder = lambda table: "Select %s..." % str(table).lower()
# define fields for which we will show "Add..." links
# Note: db.Kind is omited; This means that user cannot add new records to db.Kind
add_links_to = [db.Category, db.Subcategory]
# width for dialog; if omited - sizes will be ajusted automatically
dialog_width=500
dialog_height=300
# create widget instance
sel_widget = VVMSelectWidget(db.Kind, db.Category, db.Subcategory,
placeholder=placeholder,
formats=formats,
dialog_width=dialog_width,
dialog_height=dialog_height,
add_links_to=add_links_to)
sel_widget.set_widget_to(db.Product.Subcategory_id)
return dict(crud=crud.create(db.Product))
3. If you need just "Add..." link next to your single dropdown, but not cascading your dropdowns - just omit tables hierarchy list in the constructor!
# create class without tables hierarchy
# in this case widget will add link for
# a new record creation and nothing more
sel_widget = VVMSelectWidget()
sel_widget.set_widget_to(db.Product.Subcategory_id)
return dict(crud=crud.create(db.Product))
4. Sometimes you need to show/hide other page elements as a result of dropdown select/deselect event; in this case you can supply your own event handler to widget; here is an example of dropdown color changing; color value depends on dropdown value; NOTE: be careful, poorly written javascript event handler can halt execution of other javascript code on your page! use exception catching in your event handler; in any case your javascript code must not raise any exceptions and must have correct javascript syntax
# define javascript event handler
change_handler_js = """
function(dropdown) {
if ($(dropdown).val() > 0)
$(dropdown).css('background-color', '#EBF5CC');
else
$(dropdown).css('background-color', '#FFE6E6');
}
"""
# define tables hierarchy and set your js event handler
sel_widget = VVMSelectWidget(db.Kind, db.Category, db.Subcategory,
change_handler_js=change_handler_js)
# set widget
sel_widget.set_widget_to(db.Product.Subcategory_id)
return dict(crud=crud.create(db.Product))


Comments (4)
0
craxsnet 6 months ago
Hello,
with the new version of web2py 2.2.1, the widget no work, i get the following error:
replies (4)
0
hervé-mayou-10727 7 months ago
Hello,
Are there options to take care of a case like this one, where child_atom would change according to parent_atom?
db.define_table('atom', Field('value', 'string', unique=True, required=True), Field('description', 'text'), auth.signature, format='%(value)s' ) db.define_table('user_atom', Field('user', db.auth_user, required=True), Field('top_atom', db.atom, default=1, required=True), Field('parent_atom', db.atom, required=True), Field('child_atom', db.atom, required=True), auth.signature )If not, I can (eventually) provide help to (eventually) add them...
replies (1)
0
craxsnet 11 months ago
ERROR
replies (4)
0
rochacbruno 1 year ago
Does it works with SQLFORM or only with crud.create?
replies (1)