Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor autocomplete #772

Merged
merged 1 commit into from
Nov 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions rdmo/core/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,7 @@
('radio', _('Radio buttons'), 'rdmo.projects.widgets.RadioWidget'),
('select', _('Select drop-down'), 'rdmo.projects.widgets.SelectWidget'),
('autocomplete', _('Autocomplete'), 'rdmo.projects.widgets.AutocompleteWidget'),
('freeautocomplete', _('Free autocomplete'), 'rdmo.projects.widgets.FreeAutocompleteWidget'),
('range', _('Range slider'), 'rdmo.projects.widgets.RangeWidget'),
('date', _('Date picker'), 'rdmo.projects.widgets.DateWidget'),
('file', _('File upload'), 'rdmo.projects.widgets.FileWidget')
Expand Down
75 changes: 64 additions & 11 deletions rdmo/projects/static/projects/js/project_questions/services.js
Original file line number Diff line number Diff line change
Expand Up @@ -941,7 +941,6 @@ angular.module('project_questions')
}
}
} else {
console.log('next');
service.next();
}
} else {
Expand Down Expand Up @@ -1372,12 +1371,22 @@ angular.module('project_questions')

// unset the searching flag
value.searching = false;

// activate the first item
if (question.widget_type == 'autocomplete' && angular.isDefined(value.items[0])) {
value.items[0].active = true;
}
});
}
} else {
// if no search was performed, do the searching on the client
value.autocomplete_search = false;
value.items = question.options_fuse.search(value.autocomplete_input);

// activate the first item
if (question.widget_type == 'autocomplete' && angular.isDefined(value.items[0])) {
value.items[0].active = true;
}
}
} else {
value.items = [];
Expand Down Expand Up @@ -1420,8 +1429,19 @@ angular.module('project_questions')
value.autocomplete_input = next.text;
}
} else if ($event.code == 'Enter' || $event.code == 'NumpadEnter') {
if (angular.isDefined(active)) {
if (value.autocomplete_input == '') {
service.resetAutocomplete(value);
} else if (angular.isDefined(active)) {
service.selectAutocomplete(value, value.items[active]);
} else if (question.widget_type == 'freeautocomplete') {
var matchingOptions = $filter('filter')(value.items, function(item) {
return item.text.toLowerCase() == value.autocomplete_input.toLowerCase();
})
if (matchingOptions.length > 0) {
service.selectAutocomplete(value, matchingOptions[0]);
} else {
service.selectAutocomplete(value, null);
}
}
} else if ($event.code == 'Escape') {
if (value.selected === '') {
Expand All @@ -1437,24 +1457,57 @@ angular.module('project_questions')
// called when the user clicks on an option of the autocomplete field
service.selectAutocomplete = function(value, option) {
value.autocomplete_locked = true;
value.selected = option.id.toString();
value.autocomplete_text = option.text;

if (option === null) {
value.text = value.autocomplete_input;
value.selected = '';
value.autocomplete_text = value.text;
} else {
value.text = '';
value.selected = option.id.toString();
value.autocomplete_text = option.text;
value.autocomplete_input = option.text;
}

service.changed(value, true);
}

// called when the user clicks outside the autocomplete field
service.blurAutocomplete = function(value) {
if (value.selected === '') {
value.autocomplete_input = '';
value.autocomplete_text = '';
value.items = null;
service.blurAutocomplete = function(question, value) {
if (question.widget_type == 'freeautocomplete') {
if (value.autocomplete_input == '') {
service.resetAutocomplete(value);
} else {
var matchingOptions = $filter('filter')(value.items, function(item) {
return item.text.toLowerCase() == value.autocomplete_input.toLowerCase();
})
if (matchingOptions.length > 0) {
service.selectAutocomplete(value, matchingOptions[0]);
} else {
service.selectAutocomplete(value, null);
}
}
} else {
value.autocomplete_locked = true;
value.autocomplete_input = value.autocomplete_text;
if (value.selected === '') {
service.resetAutocomplete(value);
} else {
value.autocomplete_locked = true;
value.autocomplete_input = value.autocomplete_text;
}
}
}

// called when an empty string is entered in the autocomplete field
service.resetAutocomplete = function(value) {
value.text = '';
value.selected = '';
value.autocomplete_input = '';
value.autocomplete_text = '';
value.items = null;

service.changed(value, true);
}

// called when the user clicks in the autocomplete field
service.unlockAutocomplete = function(question, value, set_prefix, set_index, index) {
value.autocomplete_locked = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,8 @@

<div class="question col-md-{$ question.width || 12 $}" ng-show="element.isQuestion" ng-init="question = element">
<div ng-hide="valueset.hidden.questions[question.id]">
{% for widget in widgets %}
{% if widget.template_name %}
{% include widget.template_name %}
{% endif %}
{% for template_name in widgets %}
{% include template_name %}
{% endfor %}
</div>
</div>
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{% load i18n %}

<div class="form-group" ng-if="question.widget_type === 'autocomplete'">
<div class="form-group" ng-if="question.widget_type === 'autocomplete' || question.widget_type === 'freeautocomplete'">
{% include 'projects/project_questions_question_label.html' %}
{% include 'projects/project_questions_question_help.html' %}
{% include 'projects/project_questions_question_warning.html' %}
Expand Down Expand Up @@ -30,7 +30,7 @@
ng-focus="service.filterAutocomplete(question, value)"
ng-change="service.filterAutocomplete(question, value);"
ng-keydown="service.keydownAutocomplete(question, value, $event)"
ng-blur="service.blurAutocomplete(value)"
ng-blur="service.blurAutocomplete(question, value)"
ng-class="{'default-value': service.isDefaultValue(question, value)}"
placeholder="{% trans 'Please type and select.' %}"/>

Expand Down
2 changes: 1 addition & 1 deletion rdmo/projects/views/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ def get(self, request, *args, **kwargs):
return redirect('project_error', pk=self.object.pk)
else:
context = self.get_context_data(object=self.object)
context['widgets'] = get_widgets()
context['widgets'] = {widget.template_name for widget in get_widgets() if widget.template_name}
return self.render_to_response(context)


Expand Down
5 changes: 5 additions & 0 deletions rdmo/projects/widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ class AutocompleteWidget(Widget):
widget_class = 'autocomplete'


class FreeAutocompleteWidget(Widget):
template_name = 'projects/project_questions_form_group_autocomplete.html'
widget_class = 'autocomplete'


class DateWidget(Widget):
template_name = 'projects/project_questions_form_group_date.html'
widget_class = 'date'
Expand Down
14 changes: 0 additions & 14 deletions rdmo/questions/constants.py

This file was deleted.