How to add a read-only field to a SQLFORM.factory

95 views
Skip to first unread message

João Matos

unread,
Mar 29, 2019, 3:39:58 PM3/29/19
to web2py-users
Hello,

How can I add a read-only field to a SQLFORM.factory?

Thanks,

JM

Jim S

unread,
Mar 29, 2019, 4:12:45 PM3/29/19
to web2py-users
Set writable=False

Field('end', 'date', requires=IS_DATE('%m/%d/%Y'), default=default_end, writable=False)

-Jim

João Matos

unread,
Mar 29, 2019, 4:32:27 PM3/29/19
to web2py-users
Tried that, doesn't work.
With writable=False the field isn't shown.

Jim Steil

unread,
Mar 29, 2019, 4:43:42 PM3/29/19
to web...@googlegroups.com
Is readable set to True?

-Jim

--
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 a topic in the Google Groups "web2py-users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/web2py/U7zQi02p2MY/unsubscribe.
To unsubscribe from this group and all its topics, send an email to web2py+un...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Anthony

unread,
Mar 29, 2019, 4:51:10 PM3/29/19
to web2py-users
By default, non-writable fields are excluded from create forms (though shown in edit forms if readable=True). However, you can override that behavior by specifying the "fields" argument with a list of field names to include in the form.

Anthony

João Matos

unread,
Mar 29, 2019, 5:02:22 PM3/29/19
to web...@googlegroups.com
@jim
It is readable and editable.

João Matos

unread,
Mar 29, 2019, 5:04:41 PM3/29/19
to web...@googlegroups.com
@Anthony
This is a SQLFORM.factory not a SQLFORM.
There is no database.
Are you sure fields parameter is applicable to SQLFORM.factory w/o a db?

Jim Steil

unread,
Mar 29, 2019, 5:20:27 PM3/29/19
to web...@googlegroups.com
Can you show some code?  Mine is working fine without a db and specifying writable=False.

-Jim

On Fri, Mar 29, 2019 at 4:02 PM João Matos <jcrm...@gmail.com> wrote:
It is readable and editable.

João Matos

unread,
Mar 29, 2019, 5:25:48 PM3/29/19
to web2py-users
The field I want to make read-only is sn.

    form = SQLFORM.factory(
       
Field('equipment_id',
              label
=T('Equipment'),
              requires
=IS_IN_DB(db, 'equipment.id', '%(name)s', zero=None),
       
),
       
Field('sn', 'integer', label=T('SN'), writable=False),
       
Field('code', label=T('WO'), requires=IS_EMPTY_OR(
            IS_IN_DB
(db(query), 'wo.code', distinct=True))),
       
Field('client_id',
              label
=T('Client'),
              requires
=IS_IN_DB(db, 'client.id', '%(name)s', zero=T('Choose one...')),
       
),
       
Field('manual_lang_id',
              label
=T('Manual language'),
              requires
=IS_IN_DB(db,
                               
'manual_lang.id',
                               
'%(name)s',
                                zero
=T('Choose one...'),
             
),
       
),
       
Field('co_code', 'string', default='', label=T('Customer order')),
       
Field('so_code', 'string', default='', label=T('Supplier order')),
       
Field('export', 'boolean', default=False, label=T('Export')),
       
Field('notes', 'string', default='', label=T('Notes')),
       
Field('observations', 'string', default='', label=T('Observations')),
       
Field('est_finish', 'date', label=T('Estimated finish'), notnull=True,
              required
=True,
              requires
=IS_DATE_IN_RANGE(  # format=T('%Y-%m-%d'),
                                        minimum
=request.now.date() + timedelta(days=1),
                                       
# maximum=request.now.date() + ,
                                        error_message
=T('Must be a future date.')
             
)
       
),
       
*factory_fields,
        hidden
={'mon': wo.modified_on},
   
)



sexta-feira, 29 de Março de 2019 às 21:20:27 UTC, Jim S escreveu:
Can you show some code?  Mine is working fine without a db and specifying writable=False.

-Jim

On Fri, Mar 29, 2019 at 4:02 PM João Matos <jcrm...@gmail.com> wrote:
It is readable and editable.

--
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 a topic in the Google Groups "web2py-users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/web2py/U7zQi02p2MY/unsubscribe.
To unsubscribe from this group and all its topics, send an email to web...@googlegroups.com.

João Matos

unread,
Mar 29, 2019, 5:42:10 PM3/29/19
to web...@googlegroups.com
Found a solution (more like a kludge) :)

form.element('#no_table_sn')['_readonly'] = 'readonly'

I even tried adding

_readonly='readonly'

to the Field, but didn't work.

Only works after the form exists.

Is there a better way?

Anthony

unread,
Mar 29, 2019, 10:58:21 PM3/29/19
to web2py-users
On Friday, March 29, 2019 at 5:04:41 PM UTC-4, João Matos wrote:
@Anthony
This is a SQLFORM.factory not a SQLFORM.
There is no database.
Are you sure fields parameter is applicable to SQLFORM.factory w/o a db?

Yes, it does work with SQLFORM.factory.

Anthony

unread,
Mar 29, 2019, 11:01:27 PM3/29/19
to web2py-users
On Friday, March 29, 2019 at 5:42:10 PM UTC-4, João Matos wrote:
Found a solution (more like a kludge) :)

form.element('#no_table_sn')['_readonly'] = 'readonly' 
I even tried adding

_readonly='readonly'

to the Field, but didn't work.

Only works after the form exists.

Field('sn', widget=lambda f, v: SQLFORM.widgets.string.widget(f, v, _readonly=True))


Is there a better way?

As noted earlier, you can use the "fields" argument.

Anthony

João Matos

unread,
Mar 30, 2019, 9:31:10 AM3/30/19
to web2py-users
I used your
widget=lambda f, v: SQLFORM.widgets.string.widget(f, v, _readonly=True)
suggestion.

I don't see any advantage in using the fields parameter because the change I found
form.element('#no_table_sn')['_readonly'] = 'readonly'
and the suggestion you made
widget=lambda f, v: SQLFORM.widgets.string.widget(f, v, _readonly=True)
only change 1 line, and using the fields would make me change all the Fields lines (if I'm not mistaken).

Thanks.

Anthony

unread,
Mar 30, 2019, 2:27:11 PM3/30/19
to web...@googlegroups.com
I don't see any advantage in using the fields parameter because the change I found
form.element('#no_table_sn')['_readonly'] = 'readonly'
and the suggestion you made
widget=lambda f, v: SQLFORM.widgets.string.widget(f, v, _readonly=True)
only change 1 line, and using the fields would make me change all the Fields lines (if I'm not mistaken).

No, "fields" is an argument of SQLFORM:

form = SQLFORM.factory(..., fields=['field1', 'field2', ...])

Anyway, setting the _readonly attribute of the input widget and setting writable=False in the Field() definition do two different things. The former makes the input element read-only in the UI but is less secure because it does not prevent writes on the server. The latter does not use an input element to display the data in the UI, and it also prevents writes on the server.

Anthony

João Matos

unread,
Mar 30, 2019, 2:37:27 PM3/30/19
to web2py-users
How can I use the fields argument without a db?
I tried
fields=['sn']
but it returns an KeyError.

Anthony

unread,
Mar 30, 2019, 3:03:40 PM3/30/19
to web2py-users
Hard to say without seeing your code, but it definitely works for me.

João Matos

unread,
Mar 30, 2019, 3:31:41 PM3/30/19
to web2py-users
This is my code
    form = SQLFORM.factory(
       
Field('equipment_id',
              label
=T('Equipment'),

              requires
=IS_IN_SET({wo.equipment_id: db.equipment(wo.equipment_id).name},

                                 zero
=None),
       
),
       
Field('sn',

              label
=T('SN'),
              widget
=lambda field, value: (
                SQLFORM
.widgets.string.widget(field, value, _readonly=True)),

       
),
       
Field('code',
              label
=T('WO'),

              requires
=IS_EMPTY_OR(IS_IN_DB(db(query), 'wo.code', distinct=True)),

       
),
       
Field('client_id',
              label
=T('Client'),
              requires
=IS_IN_DB(db, 'client.id', '%(name)s', zero=T('Choose one...')),
       
),
       
Field('manual_lang_id',
              label
=T('Manual language'),
              requires
=IS_IN_DB(db,
                               
'manual_lang.id',
                               
'%(name)s',
                                zero
=T('Choose one...'),
             
),
       
),

       
Field('co_code', default='', label=T('Customer order')),
       
Field('so_code', default='', label=T('Supplier order')),

       
Field('export', 'boolean', default=False, label=T('Export')),

       
Field('notes', default='', label=T('Notes')),
       
Field('observations', default='', label=T('Observations')),

       
Field('est_finish',
             
'date',
              label
=T('Estimated finish'),
              notnull
=True,
              required
=True,
              requires
=IS_DATE_IN_RANGE(  # format=T('%Y-%m-%d'),
                                        minimum
=request.now.date() + timedelta(days=1),
                                       
# maximum=request.now.date() + ,
                                        error_message
=T('Must be a future date.')
             
)
       
),
       
*factory_fields,

   
)

Jim Steil

unread,
Mar 30, 2019, 3:43:46 PM3/30/19
to web...@googlegroups.com
Just change it to

Field('sn', label=T('SN'), writable=False)

Doesn't that work?


Jim




--
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 a topic in the Google Groups "web2py-users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/web2py/U7zQi02p2MY/unsubscribe.
To unsubscribe from this group and all its topics, send an email to web2py+un...@googlegroups.com.

João Matos

unread,
Mar 30, 2019, 7:39:51 PM3/30/19
to web2py-users
No, it doesn't.
It simply doesn't show the field.
To unsubscribe from this group and all its topics, send an email to web...@googlegroups.com.

Anthony

unread,
Mar 30, 2019, 11:31:13 PM3/30/19
to web2py-users
Need to see the code that generated the KeyError, as well as the full traceback, and details about how/when the error was generated.

João Matos

unread,
Apr 13, 2019, 4:47:21 AM4/13/19
to web2py-users
Had to revert to my old code

form.element('#no_table_sn')['_readonly'] = 'readonly'

instead of

            widget=lambda field, value:
                SQLFORM
.widgets.string.widget(field, value), _readonly=True),

because otherwise after onvalidation web2py would remove "form-control " from the field's class and the appearence of the field would change.
Is this a bug?



sábado, 30 de Março de 2019 às 03:01:27 UTC, Anthony escreveu:
Reply all
Reply to author
Forward
0 new messages