Reputation: 133
I have this form and model for a group:
class GroupForm(forms.ModelForm):
class Meta:
model = Group
fields = ('leader', 'description', 'size', 'max_size', 'motto')
widgets = {
'size': forms.CheckboxInput(attrs={'id': 'size'}),
'max_size': forms.TextInput(attrs={'type': 'hidden', 'id': 'maxSize'}),
}
The creator of the group has an option to check yes for size
and on doing so, I used javascript to change the type of max_size
to show
.
In my create_group.html
template:
<script>
let size = document.getElementById('size')
let maxSize = document.getElementById('maxSize')
let checked = false
size.onclick = () => {
checked = !checked
if (checked === true) {
maxSize.type = 'show'
} else {
maxSize.type = 'hidden'
}
}
</script>
Now, this works fine, the only problem is that the fields are displayed out of order.
When the page loads, max_size
is false
and its field is not displayed. Which is good. However, when the user checks that group has a size, and, subsequently, the max_size
has a display of show
, the field shows up after the motto field and not in its correct order according to fields = ('leader', 'description', 'size', 'max_size', 'motto')
.
Furthermore, the max_size
field is included inside the motto
element itself and not as its own field:
vs. the other fields which are all in their own <p></p>
.
Upvotes: 0
Views: 72
Reputation: 133
If anyone else comes across this issue, it's also possible to just use js and css. Right now, I'm using javascript to see if size
is checked and if it is then maxSize.style.display = 'block'
vs maxSize.style.display = 'none'
if size
isn't checked.
Then I had the issue of django's form label still being visible. To fix that I saw an answer on dev.to which you can see for yourself.
My issue now is that I don't know how to add a label that is only visible when the form field is visible.
Upvotes: 0
Reputation: 8222
I'm guessing that {{form.as_p}}
etc. render all the visible fields first, then the hidden ones.
You can explicitly render the fields in the order you want in your template. Rather than hardcoding the order in your template, maybe this (I've never tried this):
FIELD_ORDER = ( ('leader', 'description', 'size', 'max_size', 'motto')
class GroupForm(forms.ModelForm):
class Meta:
model = Group
fields = FIELD_ORDER
Pass to your template a list of fields explicitly in the order you want:
fields_in_order = [ form[x] for x in FIELD_ORDER ]
In the template
{% for field in fields_in_order %}
{{field}}
{% endfor %}
Or, you can make the hiding of this field something done by JS
Upvotes: 1