[web2py] Acces to row object with widget (widget=lambda field, value, row: ...)

167 views
Skip to first unread message

Richard

unread,
Feb 6, 2014, 4:14:26 PM2/6/14
to web...@googlegroups.com
Hello,

I may ask something not realistic, I didn't think that much to this...

But I found my self, I would really need to know the value of another fields the than the field on which the widget is apply in other to init my widget correctly. I found a workaround that would be as easy as passing the value of those fields as a vars in the URL, but I feel that it is hacky compare to having acces to row from widget, like reprensent...

Just to be more specific... I use this widget, from s-cubism sqlab : 


That I modify to fix issue with initialisation on update form... The thing is, that my fix is far from perfect, since the conditionnal field (the one on which the widget have been declared) is not filtered out, only the proper value for the conditionnal field is selected as it should on form update...

So, I thougt, that I can fix this like that :

Defining another _get_select_el function (maybe not required, but for now let use it) :

    def _get_select_el_for_init(self, trigger, value=None):
        if trigger:
            self._require.orderby = self.orderby or self._require.orderby
            self._require.dbset = self._require.dbset(self.where(trigger))
            options = self._require.options()
            opts = [OPTION(v, _value=k) for (k, v) in options]
            return DIV(SELECT(_id='%s__aux' % self._el_id, value=value,
                              _onchange='jQuery("#%s").val(jQuery(this).val());' % self._hidden_el_id,
                              *opts))
        else:
            return self.default

Then 

I can do that :

    if value:
            el = DIV(script_el,
                     SPAN(self._get_select_el_for_init(trigger=self.conditional_field_value, value=value),
                          # SELECT(value=value,
                          #        _id='%s__aux' % self._el_id,
                          #        _onchange='jQuery("#%s").val(jQuery(this).val());' % self._hidden_el_id,
                          #        *[OPTION(v, _value=k) for (k, v) in field.requires.options()],
                          #        ),
                          _id=self._disp_el_id),
                     INPUT(_value=value, _type='hidden',
                           _name=field.name, _id=self._hidden_el_id,
                           requires=field.requires),
                     _id=self._el_id)
        else:
            el = DIV(script_el,
                     SPAN(select_el or self.default, _id=self._disp_el_id),
                     INPUT(_value=value, _type='hidden',
                           _name=field.name, _id=self._hidden_el_id,
                           requires=field.requires),
                     _id=self._el_id)

Instead of what is commented out...

self.conditional_field_value contain the id selected in the "master" field.

It would requires that I could do something like that :

widget=lambda field, value, row: lazy_options_widget(field=field,
                                                             on_key='no_table_master_field__selected',
                                                             off_key='master_field__unselected',
                                                             where=lambda master_field: (db.lookuptable.master_field == row.master_field),
                                                             trigger=request.vars.master_field,
                                                             orderby=db.lookuptable.id,
                                                             ...
                                                             )

Does it make any sens or what?

I can just do that instead :

 if value:
            el = DIV(script_el,
                     SPAN(self._get_select_el_for_init(trigger=current.request.vars.conditional_field_value, value=value),
                          # SELECT(value=value,
                          #        _id='%s__aux' % self._el_id,
                          #        _onchange='jQuery("#%s").val(jQuery(this).val());' % self._hidden_el_id,
                          #        *[OPTION(v, _value=k) for (k, v) in field.requires.options()],
                          #        ),
                          _id=self._disp_el_id),
                     INPUT(_value=value, _type='hidden',
                           _name=field.name, _id=self._hidden_el_id,
                           requires=field.requires),
                     _id=self._el_id)

And passing the vars into the URL...

Thanks

Richard

Anthony

unread,
Feb 6, 2014, 6:14:20 PM2/6/14
to web...@googlegroups.com
Don't have time to process all this, but are you saying you have a row object and just need to know how to pass it to a custom widget?

Richard Vézina

unread,
Feb 7, 2014, 9:29:29 AM2/7/14
to web2py-users
Kind of...

Richard


--
Resources:
- http://web2py.com
- http://web2py.com/book (Documentation)
- http://github.com/web2py/web2py (Source code)
- https://code.google.com/p/web2py/issues/list (Report Issues)
---
You received this message because you are subscribed to the Google Groups "web2py-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to web2py+un...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Anthony

unread,
Feb 7, 2014, 11:32:19 AM2/7/14
to web...@googlegroups.com
Then what's wrong with just doing:

widget=lambda field, value, row=row: lazy_options_widget(field=field,
                                                             on_key='no_table_master_field__selected',
                                                             off_key='master_field__unselected',
                                                             where=lambda master_field: (db.lookuptable.master_field =row.master_field),
                                                             trigger=request.vars.master_field,
                                                             orderby=db.lookuptable.id,
                                                             ...
                                                             )

Anthony

Richard Vézina

unread,
Feb 7, 2014, 11:40:50 AM2/7/14
to web2py-users
Notting, it just don't work... Notice, I am using web2py 2.4.7... So passing row not seems an option...

Also, the lazy_option plugin is bizz, I don't fully understand how it get to know the value, and field already is used for something else and not seems to be used as it normal in the custom widget like describe in the book... I mean, 

widget=lambda field, value: lazy_optoin_widget(field, value, ...)

Is not working as expected... But I can refactor this...

So, is :

widget=lambda field, value, row: ...

Working out of the box in last web2py stable?

Thanks

Richard

Anthony

unread,
Feb 7, 2014, 1:51:36 PM2/7/14
to web...@googlegroups.com
So, is :

widget=lambda field, value, row: ...

Working out of the box in last web2py stable?

No, web2py will not pass a row to a widget -- it only passes a field and value. That's why I said to do:

lambda field, value, row=row: ...

In that case, you are specifying the "row" argument of the lambda with a default value (notice the "=row"), which of course you must define yourself in the preceding code (that's why I asked if you already had a row object). When web2py calls the widget, it will pass in the field and value, and the lambda function itself will then have access to the field, value, and row.

Anthony

Richard Vézina

unread,
Feb 7, 2014, 3:58:12 PM2/7/14
to web2py-users
Nice trick!!

Many thanks for that, I read read too fast your preceding post... I will see what I can do with that, it should solve my issue...

Richard


--
Reply all
Reply to author
Forward
0 new messages