How about you just do this somewhere:
 
db.table.field1.widget=SQLFORM.widgets.options.widget
 
or
 
db.define_table('table', Field('field', requires=..., 
widget=SQLFORM.widgets.options.widget))
 
Does that bring the drop-down back to your field?
 
Anthony

On Wednesday, June 22, 2011 4:07:22 PM UTC-4, Richard wrote:

> I try to hack a bit with IS_IN_DB to include a "ornull=" option that give 
> this : 
>
>  class IS_IN_DB_DEV_ORNULL():
>     """
>     example::
>
>         INPUT(_type='text', _name='name',
>               requires=IS_IN_DB(db, db.mytable.myfield, zero=''))
>
>     used for reference fields, rendered as a dropbox
>     """
>
>     def __init__(
>         self,
>         dbset,
>         field,
>         label=None,
>         error_message='value not in database',
>         orderby=None,
>         groupby=None,
>         cache=None,
>         multiple=False,
>         zero='',
>         sort=False,
>         _and=None,
>         ornull=None,
>         null=None,
>         ):
>         from dal import Table
>         if isinstance(field,Table): field = field._id
>
>         if hasattr(dbset, 'define_table'):
>             self.dbset = dbset()
>         else:
>             self.dbset = dbset
>         self.field = field
>         (ktable, kfield) = str(self.field).split('.')
>         if not label:
>             label = '%%(%s)s' % kfield
>         if isinstance(label,str):
>             if regex1.match(str(label)):
>                 label = '%%(%s)s' % str(label).split('.')[-1]
>             ks = regex2.findall(label)
>             if not kfield in ks:
>                 ks += [kfield]
>             fields = ks
>         else:
>             ks = [kfield]
>             fields = 'all'
>         self.fields = fields
>         self.label = label
>         self.ktable = ktable
>         self.kfield = kfield
>         self.ks = ks
>         self.error_message = error_message
>         self.theset = None
>         self.orderby = orderby
>         self.groupby = groupby
>         self.cache = cache
>         self.multiple = multiple
>         self.zero = zero
>         self.sort = sort
>         self._and = _and
>         self.ornull = ornull
>         self.null = null
>
>     def set_self_id(self, id):
>         if self._and:
>             self._and.record_id = id
>
>     def build_set(self):
>         if self.fields == 'all':
>             fields = [f for f in self.dbset.db[self.ktable]]
>         else:
>             fields = [self.dbset.db[self.ktable][k] for k in self.fields]
>         if self.dbset.db._dbname != 'gae':
>             orderby = self.orderby or reduce(lambda a,b:a|b,fields)
>             groupby = self.groupby
>             dd = dict(orderby=orderby, groupby=groupby, cache=self.cache)
>             records = self.dbset.select(*fields, **dd)
>         else:
>             orderby = self.orderby or reduce(lambda a,b:a|b,(f for f in 
> fields if not f.name=='id'))
>             dd = dict(orderby=orderby, cache=self.cache)
>             records = self.dbset.select(self.dbset.db[self.ktable].ALL, 
> **dd)
>         self.theset = [str(r[self.kfield]) for r in records]
>         if isinstance(self.label,str):
>             self.labels = [self.label % dict(r) for r in records]
>         else:
>             self.labels = [self.label(r) for r in records]
>
>     def options(self):
>         self.build_set()
>         items = [(k, self.labels[i]) for (i, k) in enumerate(self.theset)]
>         if self.sort:
>             items.sort(options_sorter)
>         if self.zero != None and not self.multiple:
>             items.insert(0,('',self.zero))
>         return items
>
>     def __call__(self, value):
>         unused_value, empty = is_empty(value)
>         """if self.multiple:
>             if isinstance(value,list):
>                 values=value
>             elif value:
>                 values = [value]
>             else:
>                 values = []
>             if isinstance(self.multiple,(tuple,list)) and \
>                     not self.multiple[0]<=len(values)<self.multiple[1]:
>                 return (values, translate(self.error_message))
>             if not [x for x in values if not x in self.theset]:
>                 return (values, None)
>         elif self.theset:
>             if value in self.theset:
>                 if self._and:
>                    return self._and(value)
>                 else:
>                     return (value, None)"""
>         if self.ornull:
>             if self.multiple:
>                 if isinstance(value,list):
>                     values=value
>                 elif value:
>                     values = [value]
>                 else:
>                     values = []
>                 if isinstance(self.multiple,(tuple,list)) and \
>                         not self.multiple[0]<=len(values)<self.multiple[1]:
>                     return (values, translate(self.error_message))
>                 if not [x for x in values if not x in self.theset]:
>                     return (values, None)
>             elif self.theset:
>                 if value in self.theset:
>                     if self._and:
>                         return self._and(value)
>                     else:
>                         return (value, None)
>             if empty:
>                 return (self.null, None)
>         else:
>             (ktable, kfield) = str(self.field).split('.')
>             field = self.dbset.db[ktable][kfield]
>             if self.dbset(field == value).count():
>                 if self._and:
>                     return self._and(value)
>                 else:
>                     return (value, None)
>         return (value, translate(self.error_message))
>
>
> But I am still stock with the NULL in both field that goes trought the 
> database overriding my ONLY_ONE_CAN_BE_FILLED() validator...
>
> I also try to add a _and= option to my ONLY_ONE_CAN_BE_FILLED() validator, 
> but remove the dropbox...
>
> The only solution that I can see now is to merge IS_IN_DB 
> with ONLY_ONE_CAN_BE_FILLED() that is not going to be really DRY...
>
> If someone can see an other solution, I am really open to the idea...
>
> Richard
>
>
> On Wed, Jun 22, 2011 at 10:31 AM, Richard Vézina <ml.richa...@gmail.com>wrote:
>
>> Hello Anthony, 
>>
>> The "_and=" works perfectly and bring back the dropbox, but as you 
>> mention, not all the logic of the validator that I pass in the _and= option 
>> is working... The IS_EMPTY_OR is overriding the 
>>
>> Here the proper syntax to get the dropbox :
>>  
>> db.table.field1.requires =\
>>     IS_EMPTY_OR(IS_IN_DB(db,'table.field1'),
>>          
>> _and=ONLY_ONE_CAN_BE_FILLED([request.vars.field2],error_message='Select only 
>> one')))
>>
>> I try to remove the IS_EMPTY_OR, but as expected the 
>> IS_IN_DB  prevent insertion of a null...
>>
>> Don't know what the best option to make it works properly...
>>
>> Adding option to IS_EMPTY_OR() to allow inter independency with 
>> my ONLY_ONE_CAN_BE_FILLED() or make a _and= option to 
>> my ONLY_ONE_CAN_BE_FILLED() to make it works with IS_IN_DB??
>>
>> Richard
>>  
>> On Tue, Jun 21, 2011 at 9:11 PM, Richard Vézina <ml.richa...@gmail.com>wrote:
>>
>>> Great thanks Anthony, I will try that tomorrow first time and I will 
>>> report back.
>>>
>>> Richard 
>>>  
>>>
>>> On Tue, Jun 21, 2011 at 5:35 PM, Anthony <abas...@gmail.com> wrote:
>>>
>>>> When you need to use additional validators with IS_IN_DB but still want 
>>>> the dropbox, you can add the additional validators to the IS_IN_DB 
>>>> validator 
>>>> via its '_and' argument -- see 
>>>> http://web2py.com/book/default/chapter/07#Database-Validators. However, 
>>>> I'm not sure if that works when IS_IN_DB is inside an IS_NULL_OR 
>>>> validator. 
>>>> (Actually, IS_NULL_OR has been deprecated in favor of IS_EMPTY_OR.)
>>>>  
>>>> Anthony
>>>>   
>>>> On Tuesday, June 21, 2011 5:16:12 PM UTC-4, Richard wrote:
>>>>
>>>>> Hello, 
>>>>>
>>>>> I would like to know if the problem I face coming from the validator 
>>>>> that I write or is a IS_IN_DB behavior in case of multiple validators??
>>>>>
>>>>> Here my validator :
>>>>>
>>>>>  class ONLY_ONE_CAN_BE_FILLED(object)**: 
>>>>>     """Class representing a validator requiring at least one non-empty 
>>>>> field in a set. """ 
>>>>>     def __init__(
>>>>>         self, 
>>>>>         others, 
>>>>>         error_message='Enter a value in at least one field'
>>>>>         ): 
>>>>>         self.others = others 
>>>>>         self.error_message = error_message 
>>>>>
>>>>>     def __call__(self, value): 
>>>>>         okay = (value, None) 
>>>>>         error = (value, self.error_message) 
>>>>>         values = [] 
>>>>>         values.append(value) 
>>>>>         values.extend(self.others) 
>>>>>         empties = [] 
>>>>>         for v in values: 
>>>>>             unused_v, empty = is_empty(v) 
>>>>>             empties.append(empty) 
>>>>>         if empties.count(False) == 1:
>>>>>             return okay
>>>>>         else:
>>>>>             return error
>>>>>
>>>>>
>>>>> But when i use it like this I lost my dropbox for the FK field1 :
>>>>>
>>>>>  db.table.field1.requires =\
>>>>>     [IS_NULL_OR(IS_IN_DB(db,'other**table.id <http://othertable.id>
>>>>> ','%(fieldrepresent)s'**,orderby=('fieldrepresent'))),
>>>>>      
>>>>> ONLY_ONE_CAN_BE_FILLED([**request.vars.field2],error_**message='Select 
>>>>> a volume or an folder')]
>>>>>
>>>>> I remember I read something about IS_IN_DB and [IS_IN_DB]...
>>>>>
>>>>> Can I have the dropbox and the multiple validators at the same time??
>>>>>
>>>>> Thanks
>>>>>
>>>>> Richard
>>>>>
>>>>>
>>>>>
>>>
>>
>

Reply via email to