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
fieldis a timestamp, I’d like theconditionlist to have selections likebefore/after/on day/etcand thetermfield to be a “timestamp” field with like a calendar widget or something - If the
fieldis a number type DB field, remove thecontains/ends with/starts with/etcconditionitems and use a number validator on thetermfield - If the
fieldis an enumeration DB field, populate theconditionselect list withis/is not/is null/is not null/etcand make thetermfield 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
ncmpselect list based on the selected value in thefldselect list. - change the
valform field type between a text field (for number/string database fields), a select list (for enumerated/”choices” database fields), and hidden (whenncmpis 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
ncmpfield with all possible values regardless of whichfldis currently selected and the javascript simply repopulates the select list on the subset corresponding to the currentfldselection. - For the
valfield, I changed the Django form class’svalfield 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 currentfldandncmpvalue. Every javascript copy of thevalfield updates the value of the always hiddenvalfield.
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.
