📜 ⬆️ ⬇️

Advanced shapes - multi select with autocomplete

Our users keep track of airline special offers and cheap flights, each is interested in their direction, departure and arrival points are thousands, users want to simultaneously monitor several cities, countries or regions. There was a task - how to provide a convenient subscription mechanism? Without long poking into the multi select, without the buttons “Add departure point”. The answer is:

The solution was a control from Facebook and Contact - users are familiar with it, which means there is no need to explain how it works. It remains to cross it with django.

This control is suitable for many cases when you need to select from a large list - hundreds or thousands of elements.
A living example is on the form of choosing cities for tracking stocks of airlines.

From the user's side, we use a ready-made jquery plug-in available on www.emposha.com/javascript/fcbkcomplete.html , download it and put css and js in the media folder (in my case - media / css and media / js)
Add the form code to foms.py-
class MultiOriginSelect (forms . SelectMultiple):
class Media :
css = {
'all' : ( '/media/css/fcbkinput.css' ,)
}
js = ( '/media/js/jquery.fcbkcomplete.js' )

class SubscriptionFilterForm (forms . Form):

CHOICES = []
........
orgs = forms . MultipleChoiceField(widget = MultiOriginSelect, choices = CHOICES, required = False , initial = [])
dsts = forms . MultipleChoiceField(widget = MultiOriginSelect, choices = CHOICES, required = False , initial = [])
........

def __init__ ( self , * args, ** kwargs):
super (SubscriptionFilterForm, self ) . __init__( * args, ** kwargs)

fcbkcomplete_fields = [ u'orgs' , u'dsts' ]
for field in fcbkcomplete_fields:
# check whether we have init parameters
if args:
loc_list = args[ 0 ] . getlist(field)
.....
# generate dynamic choices for fcbk fields from args, like [id, name]
self . fields[field] . choices = ([( int (o), name(o)) for o in loc_list] )

The last line is the main one; if the form has initialization values, fill in the choices.

Add the initialization of controls to the html file with the form:
<head>
<script>
$( document ).ready( function (){
$( "#id_orgs, #id_dsts" ).fcbkcomplete({
json_url : '/subscribe_autocomplete' ,
first_selected : false ,
filter_hide : true ,
filter_case : false ,
complete_text : "Enter country, city or airport." ,
maxitems : 100
});
});
</script>
</head>

<body>
....
<form>
......
{{form.orgs}}
{{form.dsts}}
<input type = "submit" >
</form>
......
</body>

')
In order for autocomplete to work, we will add a view that will generate the necessary json. In our case, it is located at / subscribe_autocomplete. So add - in urls.py:
.....
url(r'^subscribe_autocomplete', subscribe_autocomplete, name='subscribe_autocomplete'),
.....


in views.py:

def subscribe_autocomplete (request):
q = request . GET . get( 'tag' , '' )
# skip too short requests
if len (q) <3 : return HttpResponse( '' )

# filter any instances according to tag
qr = Objects . objects . filter(Q( .... ))

#generate json
#message format - [{"caption":"London", "value":4}]
s =[...];

return HttpResponse(s)


now the form on the page works for us and successfully generated form from the post request (form = SubscriptionFilterForm (request.POST))

To generate a form from a model - I use a separate function (in my case, ModelsForm did not fit)

def subs_form_from_model (s):
src_d = {}
src_d[ 'subscriptionemail' ] = s . email
,,,,

qd = django . http . QueryDict( '' )
qd = qd . copy() # to make muttable
qd . update(src_d)

# fill form fields
qd . setlist( 'orgs' , [ unicode (o . id) for o in s . orgs . all()])
qd . setlist( 'dsts' , [ unicode (d . id) for d in s . dsts . all()])

# create form
form = SubscriptionFilterForm(qd)
..........

return form </ code >


Most users see the field already filled (by geo ip) and understand what's what.
The same form can (and should) be used in the admin panel, for large meni-tu-meni fields.

PS And in order not to get up two times - if you liked the buruki (or you are already using our search and mailing list) - we will be happy to communicate with a skilled typesetter and acrobat JSa.

Source: https://habr.com/ru/post/107372/


All Articles