From: Damien Lespiau Date: Sat, 27 Sep 2014 22:44:25 +0000 (+0100) Subject: filters: Rewrite the submitter autocompletion code X-Git-Tag: v1.1.0~172 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=73a4f9a414239bdee5a5d5b4bb490538bebd2c48;p=thirdparty%2Fpatchwork.git filters: Rewrite the submitter autocompletion code We now have a nice(r) autocompletion widget that will popup the list of options directly underneath the input fild. A few changes are done in this commit that couldn't be split any further: - Use jQuery's $.ajax() for the completion query - Use the application/json content type on the completion answer to allow jQuery to directly create an object from it instead of giving back a string (because of the text/plain content type) - Crafted more logical objects in the json answer ie all properties are at the same level instead of the default queryset serializer that put the object fields in a 'field' sub-object. - Use selectize.js for the autocompletion widget logic A slight change in behaviour is that we now don't allow "free form" submitter search, ie we need a valid completion to search with that specific person (through its primary key). I didn't remove the backend logic that allows the "free form" mechanism, but maybe we should. v2: Squash the unit tests fixes into this patch (Jeremy Kerr) Signed-off-by: Damien Lespiau --- diff --git a/patchwork/filters.py b/patchwork/filters.py index 3f8bd3e7..db671ffc 100644 --- a/patchwork/filters.py +++ b/patchwork/filters.py @@ -87,6 +87,11 @@ class SubmitterFilter(Filter): self.person = None self.person_match = None submitter_id = None + + str = str.strip() + if str == '': + return + try: submitter_id = int(str) except ValueError: @@ -128,15 +133,8 @@ class SubmitterFilter(Filter): return '' def _form(self): - name = '' - if self.person: - name = self.person.name - return mark_safe(('' % escape(name)) + - '') + return mark_safe(('')) def key(self): if self.person: diff --git a/patchwork/templates/patchwork/filters.html b/patchwork/templates/patchwork/filters.html index 842e6435..6ab8108b 100644 --- a/patchwork/templates/patchwork/filters.html +++ b/patchwork/templates/patchwork/filters.html @@ -19,127 +19,40 @@ function filter_click() } -function enable_selected_submitter(select, input) -{ - select.name = 'submitter'; - input.name = ''; -} -function filter_form_submit(form) -{ - var i; - - var submitter_select = document.getElementById("submitter_select"); - var submitter_input = document.getElementById("submitter_input"); - if (!submitter_select || !submitter_input) { - req = null; - return; - } - - /* submitter handling. if possible, use the select box, otherwise leave - * as-is (and so the text box is used). */ - - if (submitter_select.options.length == 0) { - /* if there's no match, just use the input */ - - } else if (submitter_select.options.length == 1) { - /* if there's only one match, request by id */ - submitter_select.selectedIndex = 0; - enable_selected_submitter(submitter_select, submitter_input); - - } else if (submitter_select.selectedIndex != -1) { - /* if the user has explicitly selected, request by id */ - enable_selected_submitter(submitter_select, submitter_input); - - } - for (i = 0; i < form.elements.length; i++) { - var e = form.elements[i]; - if (e.type == 'submit') { - continue; - } - - /* handle submitter data */ - if (e.type == 'select-one') { - if (e.name == '') { - e.disabled = true; - } - if (e.selectedIndex != -1 - && e.options[e.selectedIndex].value == '') { - e.disabled = true; +$(document).ready(function() { + $('#submitter_input').selectize({ + valueField: 'pk', + labelField: 'name', + searchField: ['name', 'email'], + maxItems: 1, + persist: false, + render: { + option: function(item, escape) { + return '
' + escape(item.name) + ' <' + + escape(item.email) + '>' + '
'; + }, + item: function(item, escape) { + return '
' + escape(item.name) + '
'; } - - continue; - } - - if (e.value == '') { - e.disabled = true; - } - } -} - -var req = null; - -function submitter_complete_response() -{ - if (req.readyState != 4) { - return - } - - var completions; - eval("completions = " + req.responseText); - - if (completions.length == 0) { - req = null; - return; - } - - var submitter_select = document.getElementById("submitter_select"); - var submitter_input = document.getElementById("submitter_input"); - if (!submitter_select || !submitter_input) { - req = null; - return; - } - - for (i = 0; i < completions.length; i++) { - name = completions[i]['fields']['name']; - if (name) { - name = completions[i]['fields']['name'] + - ' <' + completions[i]['fields']['email'] + '>'; - } else { - name = completions[i]['fields']['email']; + }, + load: function(query, callback) { + if (query.length < 4) + return callback(); + + req = $.ajax({ + url: '{% url 'patchwork.views.submitter_complete' %}?q=' + + encodeURIComponent(query) + '&l=10', + error: function() { + callback(); + }, + success: function(res) { + callback(res); + } + }); } - o = new Option(name, completions[i]['pk']); - submitter_select.options[i] = o; - } - - /* remove remaining options */ - for (; i < submitter_select.length; i++) { - submitter_select.options[i] = null; - } - - submitter_select.disabled = false; - req = null; -} - -function submitter_field_change(field) -{ - var limit = 20; - var value = field.value; - if (value.length < 4) { - return; - } - - if (req) { - return; - } - - var url = '{% url 'patchwork.views.submitter_complete' %}?q=' + value + - '&l=' + limit; - req = new XMLHttpRequest(); - req.onreadystatechange = submitter_complete_response; - req.open("GET", url, true); - req.send(''); -} + }); +});
@@ -162,8 +75,7 @@ function submitter_field_change(field) {% endif %}