TL;DR
How can I change the search term CharField (of any of the rows in the image below) to another field type (e.g. ChoiceField, DateField, etc) based on the type of the selected database field (in the first select list on that row – see screenshot below)?
Long version
I have a cool hierarchical advanced search interface, e.g.:
Each row specifies a search term/condition and reads as a search, like:
<field>
<condition>
<term>
e.g.
age
>
5
where the form field names are:
fld
(for “database field”)ncmp
(for “negatable comparison type”)val
(for the search term)
There is a hidden field called pos
for the hierarchy and group type data, but that’s irrelevant to my question.
Rows and subgroups can be dynamically added/removed to/from the hierarchy and can be and-ed
or or-ed
together.
It works great. But the problem I want to solve is that it is somewhat limited by field type. I would like to be able to dynamically change the contents of the condition
select list (ncmp
) and the type of search term field (val
) based on the selected database field (fld
) (or the selected condition
, e.g. if isnull
: hide the term field). Here are some examples of what I want:
- If the selected
field
is a timestamp, I’d like thecondition
list to have selections likebefore/after/on day/etc
and theterm
field to be a “timestamp” field with like a calendar widget or something - If the
field
is a number type DB field, remove thecontains/ends with/starts with/etc
condition
items and use a number validator on theterm
field - If the
field
is an enumeration DB field, populate thecondition
select list withis/is not/is null/is not null/etc
and make theterm
field a select list
Are there any standard ways to do this? Ideally, the form would still only have the 3 fields (fld
, ncmp
, and val
) so that I wouldn’t have to overhaul the hierarchy javascript that controls the formsets, but I can do that if necessary.
Advertisement
Answer
I don’t have a completely comprehensive answer to this yet, but I have implemented ways to:
- update the
ncmp
select list based on the selected value in thefld
select list. - change the
val
form field type between a text field (for number/string database fields), a select list (for enumerated/”choices” database fields), and hidden (whenncmp
is something like “is null” or “is not null”).
I haven’t figured out a way to use different Django widgets and accomplished the above using javascript. There are a few things to keep in mind:
- The Django form class must define the
ncmp
field with all possible values regardless of whichfld
is currently selected and the javascript simply repopulates the select list on the subset corresponding to the currentfld
selection. - For the
val
field, I changed the Django form class’sval
field to be a hidden field, and render a number of initially hidden form fields in javascript on each row, which I hide/show based on the currentfld
andncmp
value. Every javascript copy of theval
field updates the value of the always hiddenval
field.
I imagine that any other representation of the val
field would have to also be done in javascript and must be able to update a single hidden val
field. So if you had multiple javascript-generated fields to enter the val
(e.g. 3 text entries for a phone number or social security number), the javascript would have to condense that into a single string to update the hidden val
field.