Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set tabindex on forms fields?

Tags:

django

How do i set the html attribute "tabindex" on form fields?

My template currently looks like..

<div class="field text username">
   <label>Email Address</label>
   {{ form.email }}
</div>
like image 201
John Mee Avatar asked Jan 28 '10 04:01

John Mee


2 Answers

The tab index is a feature of the layout, and so it feels like it really belongs in the template, not in the view. Here's a straightforward approach that achieves this:

First, define a custom template filter that adds a tabindex attribute to the widget of a bound field:

@register.filter
def tabindex(value, index):
    """
    Add a tabindex attribute to the widget for a bound field.
    """
    value.field.widget.attrs['tabindex'] = index
    return value

Then, add |tabindex:n to the fields in the template. For example:

<tr>
<th>{{ form.first_name.label_tag }}<td>{{ form.first_name|tabindex:1 }}
<th>{{ form.email.label_tag }}<td>{{ form.email|tabindex:3 }}
<tr>
<th>{{ form.last_name.label_tag }}<td>{{ form.last_name|tabindex:2 }}
<th>{{ form.active.label_tag }}<td>{{ form.active|tabindex:4 }}
like image 69
Gareth Rees Avatar answered Sep 22 '22 05:09

Gareth Rees


All credit to Alex, but just to fill out the solution:

When using the django auto formfield generation (widgets), forget about the templates you have to do it in the form definition like this:

class AuthenticationForm(forms.Form):
    email    = forms.CharField(label=_("Email Address"), max_length=75)

becomes:

class AuthenticationForm(forms.Form):
    email    = forms.CharField(
                   label=_("Email Address"), max_length=75,
                   widget=forms.TextInput(attrs={'tabindex':'1'})
                )

But if you're willing to abandon the widgets and keep presentation in the template you can also do it this way:

<div class="field text username">
   <label>Email Address</label>
   <input id="id_email" type="text" name="email" 
       tabindex="1" maxlength="75" 
       value="{{form.email.data|default:''}}"/>
</div>

I'm inclined toward the latter.

like image 29
John Mee Avatar answered Sep 24 '22 05:09

John Mee