Massimo,
Many, many thanks for adding formstyle functions in 179.1.  You've
provided a solution for the one aspect of SQLFORM that has given me
the most headaches in trying to customize the presentation of form
items, namely that the composition of the items in the field rows are
determined in SQLFORM.__init__() instead of later when the view is
rendered.

For example,  I have some forms generated with SQLFORM.factory that
really needed to have the labels to the right of slider widgets in
order to make the app more useful from smartphones with small
screens.  Now I can define a formstyle function like this:

------------
_slider_row_id_ptn = re.compile(r'^.*_c[0-9]+_.*$') ## _c[0-9]+
matches field id

def responseformstyle(id,a,td_b,c):
    if _slider_row_id_ptn.match(id):
        ##  Put the label to the right of the slider
        row = TR(td_b, TD(a,_class='w2p_fl'),
                     TD(c,_class='w2p_fc'),_id=id)
    else:
        ## mimic formstyle 'table3cols'
        row = TR(TD(a,_class='w2p_fl'), td_b,
                     TD(c,_class='w2p_fc'),_id=id)
    return row
------------

Works great! Having to know about how SQLFORM builds a row_id seems a
bit funky and fragile, but at least I can do what's needed now.

May I propose a change for a future release?  IMO, it would be awesome
if Field.__init__() had an optional argument, say,
'formstyleitem=None' that could be used to pass an arbitrary object
that SQLFORM could pass to a formstyle function. Then I could dispense
with the regex and do something like

------------
def responseformstyle2(id,a,td_b,c,styleitem=None):
    #import pdb; pdb.set_trace()
    if styleitem == 'labelright':
        ##  Put the label to the right of the slider
        row = TR(td_b, TD(a,_class='w2p_fl'),
                     TD(c,_class='w2p_fc'),_id=id)
    else:
        ## mimic formstyle 'table3cols'
        row = TR(TD(a,_class='w2p_fl'), td_b,
                     TD(c,_class='w2p_fc'),_id=id)
    return row
------------


or pass an object containing information or methods to modify the
representation of the Field items, e.g,

------------
class LabelRight(object):
    """ Silly test of passing object for formstyleitem """
    def __init__(self,id):
        self.id = id

def responseformstyle3(id,a,td_b,c,styleitem=None):
    import pdb; pdb.set_trace()
    if isinstance(styleitem,LabelRight):
        ## append the field id after the label text.
        a.components.append(styleitem.id)

        ##  Put the label to the right of the slider
        row = TR(td_b, TD(a,_class='w2p_fl'),
                     TD(c,_class='w2p_fc'),_id=id)
    else:
        ## mimic formstyle 'table3cols'
        row = TR(TD(a,_class='w2p_fl'), td_b,
                     TD(c,_class='w2p_fc'),_id=id)
    return row
------------

If that seems like something worth adding in a future release, here
are patches against sql.py and sqlhtml.py (179.2) that are working
correctly in my application and seem to be backward compatible with
older apps, albeit they could certainly do with more thorough testing.

$ diff -Nanr sql.py.save sql.py
d2603 1
a2603 3
            autodelete=False, represent=None, uploadfolder=None,
            formstyleitem=None, #object passed to user-defined
formstyle function
            )
a2639 1
        formstyleitem=None,
a2676 2
        self.formstyleitem = formstyleitem


$ diff -Nanr sqlhtml.py.save sqlhtml.py
a603 1
        xfieldstyleitems = {}
a714 3
            if hasattr(field,'formstyleitem') and field.formstyleitem !
= None:
                xfieldstyleitems[row_id] = field.formstyleitem

d810 1
a810 5
                if id in xfieldstyleitems.keys():
                    item = xfieldstyleitems[id]
                    newrows = formstyle(id,a,td_b,c,styleitem=item)
                else:
                    newrows = formstyle(id,a,td_b,c)


Cheers,
Mike

Reply via email to