FORM() and HTML5 autofocus

163 views
Skip to first unread message

Dave S

unread,
Mar 1, 2017, 5:19:14 AM3/1/17
to web2py-users
When using FORM(), how does one set an input field to have the autofocus attribute?

/dps

Anthony

unread,
Mar 1, 2017, 7:24:18 AM3/1/17
to web2py-users
INPUT(..., _autofocus=True)

You'll get autofocus="autofocus" in the HTML, but that will work.

Anthony

Dave S

unread,
Mar 2, 2017, 2:37:19 AM3/2/17
to web2py-users
On Wednesday, March 1, 2017 at 4:24:18 AM UTC-8, Anthony wrote:
INPUT(..., _autofocus=True)

You'll get autofocus="autofocus" in the HTML, but that will work.

Anthony


Thanks!  It does indeed work (Chrome Version 56.0.2924.87).  I had remembered the underscore, but didn't think of the =True.

/dps

Dave S

unread,
Mar 2, 2017, 5:25:27 AM3/2/17
to web2py-users
On Wednesday, March 1, 2017 at 11:37:19 PM UTC-8, Dave S wrote:
On Wednesday, March 1, 2017 at 4:24:18 AM UTC-8, Anthony wrote:
INPUT(..., _autofocus=True)

You'll get autofocus="autofocus" in the HTML, but that will work.

Anthony


Thanks!  It does indeed work (Chrome Version 56.0.2924.87).  I had remembered the underscore, but didn't think of the =True.


For an SQLFORM(), things are a little trickier, because the **attributes applies to the whole FORM object, and can't be directed to the input field.  So I tried using 
form.elements(input, _id=table_field, replace=lambda i: i[0:-2] + "autofocus" + i[-1])

but i is a gluon.html.INPUT object and not sliceable (the slices become empty strings); there is also a ticket for trying to concatenate a string to a list, just to keep me confused.  Do I need to use javascript to set the focus?

/dps



Anthony

unread,
Mar 2, 2017, 8:26:38 AM3/2/17
to web2py-users
For an SQLFORM(), things are a little trickier, because the **attributes applies to the whole FORM object, and can't be directed to the input field.  So I tried using 
form.elements(input, _id=table_field, replace=lambda i: i[0:-2] + "autofocus" + i[-1])

but i is a gluon.html.INPUT object and not sliceable (the slices become empty strings); there is also a ticket for trying to concatenate a string to a list, just to keep me confused.  Do I need to use javascript to set the focus?

You don't need to replace the input -- just update it:

form.element(...)['_autofocus'] = True

But if it is a SQLFORM, a better approach is probably to change the widget associated with the DAL Field:

db.mytable.myfield.widget = lambda f, v: SQLFORM.widgets.string.widget(f, v, _autofocus=True)

If you always want autofocus set for that field, you can do the above within the DAL table definition.

Anthony
 

/dps



黄祥

unread,
Mar 2, 2017, 5:40:10 PM3/2/17
to web2py-users
i've tested using SQLFORM.widget after submit (form validation) the size of the form field is changed smaller than the form field size before submit, how to create form field size remain same before and after submit (form validation) ?
e.g.
models/db.py
def on_define_address(table): 
table.address.requires = IS_NOT_EMPTY()
table.address.widget = lambda field,value: SQLFORM.widgets.text.widget(field, value, _autofocus = True, 
  _placeholder = T('Address should be filled') )

db.define_table('address', 
Field('address', 'text'), 
on_define = on_define_address, 
format = lambda r: '%s' % (r.address) )

thanks and best regards,
stifan

Dave S

unread,
Mar 3, 2017, 5:00:16 AM3/3/17
to web2py-users
Thanks, these all work.   The table def is probably what I'll stick with.

I haven't had to touch widgets much, and like many an unlearned feature they seemed mysterious or even spooky.  Perhaps I'll get a little more comfortable with them now.  One thing that I'm seeing is if my  validator returns a fail, the text box will resize smaller, which isn't a serious issue for me.

/dps "cue Addams Family theme"


Dave S

unread,
Mar 11, 2017, 6:28:17 AM3/11/17
to web...@googlegroups.com


On Thursday, March 2, 2017 at 5:26:38 AM UTC-8, Anthony wrote:
For an SQLFORM(), things are a little trickier, because the **attributes applies to the whole FORM object, and can't be directed to the input field.  So I tried using 
form.elements(input, _id=table_field, replace=lambda i: i[0:-2] + "autofocus" + i[-1])

but i is a gluon.html.INPUT object and not sliceable (the slices become empty strings); there is also a ticket for trying to concatenate a string to a list, just to keep me confused.  Do I need to use javascript to set the focus?

You don't need to replace the input -- just update it:

form.element(...)['_autofocus'] = True

Just to keep things interesting, I tried this with a form from SQLFORM.factory() (used as a LOAD item).  It keeps ending up in a ticket,


File "C:/Users/Dave/web2py_win/web2py_win 2.14.6/web2py/applications/badlist/controllers/default.py", line 46, in getpic
form.element(input, _id="no_table_image_url")['_autofocus'] = True
File "C:\Users\Dave\web2py_win\web2py_win 2.14.6\web2py\gluon\html.py", line 1200, in element
elements = self.elements(*args, **kargs)
File "C:\Users\Dave\web2py_win\web2py_win 2.14.6\web2py\gluon\html.py", line 1104, in elements
args = [a.strip() for a in args[0].split(',')]
AttributeError: 'builtin_function_or_method' object has no attribute 'split'

File C:\Users\Dave\web2py_win\web2py_win 2.14.6\web2py\gluon\html.py in elements at line 1104

Function argument list

(self=<gluon.sqlhtml.SQLFORM object>, *args=(<built-in function input>,), **kargs={'_id': 'no_table_image_url', 'first_only': True})

1103.
1104.

1105.
1106.
1107.
1108.
        >>> b = a.elements('span.efg', find_text=re.compile('x|y|z'), replace='hello')
>>>
print a
<div><div><span class="abc">x</span><div><span class="efg">hello</span><span class="abc">z</span></div></div></div>
"""
if len(args) == 1:
args = [a.strip() for a in args[0].split(',')]
 

But if it is a SQLFORM, a better approach is probably to change the widget associated with the DAL Field:

db.mytable.myfield.widget = lambda f, v: SQLFORM.widgets.string.widget(f, v, _autofocus=True)

If you always want autofocus set for that field, you can do the above within the DAL table definition.


I tried setting the widget in the factoryfield def, and that doesn't seem to have an error, but doesn't autofocus.  When the LOAD'ed form is submitted, I'm hoping to have the focus be on the factoryfield; when loading the page, the focus should be on the starting field of the main form (which is just SQLFORM()'d). [Edit:] Normal loading, and submitting of the main form, does indeed put focus on that starting field of the main form.

Anthony
 

/dps



(It's me again) 
/dps

Anthony

unread,
Mar 11, 2017, 10:25:49 AM3/11/17
to web2py-users

Just to keep things interesting, I tried this with a form from SQLFORM.factory() (used as a LOAD item).  It keeps ending up in a ticket,

File "C:/Users/Dave/web2py_win/web2py_win 2.14.6/web2py/applications/badlist/controllers/default.py", line 46, in getpic
form.element(input, _id="no_table_image_url")['_autofocus'] = True
File "C:\Users\Dave\web2py_win\web2py_win 2.14.6\web2py\gluon\html.py", line 1200, in element
elements = self.elements(*args, **kargs)
File "C:\Users\Dave\web2py_win\web2py_win 2.14.6\web2py\gluon\html.py", line 1104, in elements
args = [a.strip() for a in args[0].split(',')]
AttributeError: 'builtin_function_or_method' object has no attribute 'split'

Should be form.element('input', ...), not form.element(input, ...).
 


I tried setting the widget in the factoryfield def, and that doesn't seem to have an error, but doesn't autofocus.  When the LOAD'ed form is submitted, I'm hoping to have the focus be on the factoryfield; when loading the page, the focus should be on the starting field of the main form (which is just SQLFORM()'d). [Edit:] Normal loading, and submitting of the main form, does indeed put focus on that starting field of the main form.

Need to see some code.

Anthony

Dave S

unread,
Mar 12, 2017, 3:43:14 AM3/12/17
to web2py-users


On Saturday, March 11, 2017 at 7:25:49 AM UTC-8, Anthony wrote:

Just to keep things interesting, I tried this with a form from SQLFORM.factory() (used as a LOAD item).  It keeps ending up in a ticket,

File "C:/Users/Dave/web2py_win/web2py_win 2.14.6/web2py/applications/badlist/controllers/default.py", line 46, in getpic
form.element(input, _id="no_table_image_url")['_autofocus'] = True
File "C:\Users\Dave\web2py_win\web2py_win 2.14.6\web2py\gluon\html.py", line 1200, in element
elements = self.elements(*args, **kargs)
File "C:\Users\Dave\web2py_win\web2py_win 2.14.6\web2py\gluon\html.py", line 1104, in elements
args = [a.strip() for a in args[0].split(',')]
AttributeError: 'builtin_function_or_method' object has no attribute 'split'

Should be form.element('input', ...), not form.element(input, ...).
 

Partial 'doh!'  -- that change indeed stops the flow of tickets.  Does not help focus (focus is not on an input in either the main form or the LOAD'ed form; I'm not quite sure where it is).



I tried setting the widget in the factoryfield def, and that doesn't seem to have an error, but doesn't autofocus.  

As above, not sure where the focus is.  Hitting tab or shift-tab may highlight the stuff on the menu or maybe the links.  I can't always see the cursor until I've moved it a few times.
 
When the LOAD'ed form is submitted, I'm hoping to have the focus be on the factoryfield; when loading the page, the focus should be on the starting field of the main form (which is just SQLFORM()'d). [Edit:] Normal loading, and submitting of the main form, does indeed put focus on that starting field of the main form.

Need to see some code.

Anthony

Views are pretty much from the Welcome app, with the toolbar removed.

in main view (default/index.html)

{{left_sidebar_enabled,right_sidebar_enabled=False,('message' in globals())}}
{{extend 'layout.html'}}
[usual block header stuff]
[A couple of strings, with each having an {{=A(...)}} helper.]
{{=form}}
{{=getter}}



LOAD view: (default/getitem.load)
{{if len(response._vars)==1:}}
{{=response._vars.values()[0]}}
{{pass}}




default.py/index():
   
[housekeeping for PostDate]
    form
= SQLFORM(db.mylist)
   
if form.process().accepted:
        response
.flash = T("Thank you!")
   
elif form.errors:
        response
.flash = T("Please correct the errors in the form")
   
else:
        response
.flash = T("Please fill out the form")
   
return dict(form=form, getter=LOAD(url=URL(r=request,f='getitem.load'),ajax=True))



default.py/getitem():
    form
= SQLFORM.factory(
       
Field('item', requires=IS_NOT_EMPTY(), widget = lambda f, v: SQLFORM.widgets.string.widget(f, v, _autofocus=True)) ,
       
Field('tags'))
   
# form.element("input", _id="no_table_image_url")['_autofocus'] = True
   
if form.process().accepted:
        response
.flash = form.vars.image_url + ' accepted'
        session
.your_image = form.vars.image_url
        details
=figureoutdetails(form.vars.item)
        newrow
={'item': form.vars.item, 'details': details, 'tags' : form.vars.tags,
               
'PostDate':str(request.now.year)+"-"+str(request.now.month)+"-"+str(request.now.day)}
        db
.myitem.insert(**newrow)
   
elif form.errors:
        response
.flash = 'form has errors'
   
return dict(form=form)



(Yeah, both tables keep track of the posting date of their contents.  I don't think it's an OCD symptom, though.)

I may be asking for moon ... expecting a "junior" autofocus to be "scoped" to the DIV it's form is loaded in.  Browsers may instead consider 2 autofoci to be undefined behavior.  In which case, turning to javascript may be my best choice.  I've got my fingers crossed, though.

/dps


Anthony

unread,
Mar 12, 2017, 12:20:26 PM3/12/17
to web2py-users
I may be asking for moon ... expecting a "junior" autofocus to be "scoped" to the DIV it's form is loaded in.  Browsers may instead consider 2 autofoci to be undefined behavior.  In which case, turning to javascript may be my best choice.  I've got my fingers crossed, though.

Yeah, you'll probably have to use some JS to do what you want.

Anthony

Dave S

unread,
Mar 12, 2017, 3:16:24 PM3/12/17
to web2py-users
Oh, well.  

Slightly off-topic -- the insert() in the getitem function seems to skip the requires=[IS_NOT_IN_DB, ...] my model includes.  Is that worth a new thread?

/dps

Anthony

unread,
Mar 12, 2017, 8:32:53 PM3/12/17
to web2py-users
Oh, well.  

Slightly off-topic -- the insert() in the getitem function seems to skip the requires=[IS_NOT_IN_DB, ...] my model includes.  Is that worth a new thread?

The DAL .insert() method doesn't do anything with validators. The validators in the "requires" attribute are used by SQLFORM. You can also have them applied when using the DAL .validate_and_insert() or .validate_and_update() methods.

Anthony

Dave S

unread,
Mar 13, 2017, 4:51:36 PM3/13/17
to web2py-users

Ooops!

Thanks for getting me facing in the right direction.

/dps
 
 
Reply all
Reply to author
Forward
0 new messages