Skip to content

Commit

Permalink
feat!: Component is now WCAG 2.1 compliant
Browse files Browse the repository at this point in the history
BREAKING CHANGE: `no_result_text` and `narrow_search_text` replaced by
the `custom_strings` dictionary.

Release-As: 0.6.0
  • Loading branch information
lucbelliveau committed Feb 9, 2023
1 parent 2f42521 commit 3c040f3
Show file tree
Hide file tree
Showing 41 changed files with 1,376 additions and 154 deletions.
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"python.linting.enabled": true,
"python.formatting.provider": "black",
"cSpell.words": [
"htmx"
"htmx",
"textinput"
]
}
1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ include LICENSE
include README.md
recursive-include autocomplete/templates *
recursive-include autocomplete/static *
recursive-include autocomplete/locale *
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,3 +101,35 @@ This Django app provides a client-side autocomplete component powered by
</body>
</html>
```

## Customization

### Strings

The strings listed in the table below can be overriden by creating the appropriate
template in your own project, matching the `autocomplete/strings/{name}.html` pattern.
By default all strings are available in both French and English.

| Name | Description | Default English | Default French |
| ----------------- | --------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ | ------------------------------------------------------------------- |
| no_results | Text displayed when no results are found. | No results found. | Aucun résultat trouvé. |
| more_results | When `max_results` is set, text displayed when there are additional results available. | Displaying maximum {{ count }} out of {{ total_results }} results. | Affichage maximum de {{ count }} résultats sur {{ total_results }}. |
| available_results | Text anounced to sceen readers when results are available. If max_results is set, the more_results text is spoken instead. | {{ count }} results available. | {{ count }} résultats disponibles. |
| nothing_selected | Text anounced to screen readers when there are no selections. | Nothing selected. | Rien de sélectionné. |

Individual instances can override strings by providing a dictionary of `custom_strings`.

```python
class GetItemsMultiAutoComplete(HTMXAutoComplete):
name = "members"
multiselect = True
custom_strings = {
"no_results": "no results text",
"more_results": _("More results text")
}

class Meta:
model = Person


```
44 changes: 26 additions & 18 deletions autocomplete/autocomplete.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,17 @@ class Meta:
frontend, or None for all.
Defaults to None.
narrow_search_text (str): Text to display when the results are cut off due to
max_results.
Default: "Narrow your search for more results."
custom_strings (dict): Dictionary containing custom strings to use for this
instance. Available keys are:
- no_results The string displayed when no
results are found.
- more_results Text to display when the results
are cut off due to max_results.
- available_results Text anounced to sceen readers
when results are available. If
max_results is set, the
more_results text is spoken
instead.
minimum_search_length (int): The minimum search length to perform a search
and show the dropdown.
Expand Down Expand Up @@ -138,11 +146,8 @@ class Meta:
# Values in this set are stripped from any toggle operation.
strip_values = set(["undefined"])

# Text to display when the results are cut off due to max_results.
narrow_search_text = "Narrow your search for more results"

# The text displayed when no results are found.
no_result_text = "No results found."
# String overrides
custom_strings = dict()

# If True will allow the user to select multiple items
multiselect = False
Expand Down Expand Up @@ -501,16 +506,18 @@ def sort_items(item):
print("ERROR: Requested item to toggle not found.")
return HttpResponseNotFound()

if not self.multiselect:
for item in items:
item["selected"] = False

if target_item.get("selected"):
items.remove(target_item)
target_item["selected"] = False
else:
target_item["selected"] = True

if not self.multiselect:
for item in items:
if item != target_item:
item["selected"] = False


template = loader.get_template("autocomplete/item.html")
return HttpResponse(
template.render(
Expand All @@ -520,12 +527,12 @@ def sort_items(item):
"indicator": self.indicator,
"placeholder": self.placeholder,
"required": self.required,
"no_result_text": self.no_result_text,
"narrow_search_text": self.narrow_search_text,
"custom_strings": self.custom_strings,
"route_name": self.get_route_name(),
"component_id": self.get_component_id(override_component_id),
"multiselect": self.multiselect,
"values": list(self.item_values(items, True)),
"item_as_list": [target_item],
"item": target_item,
"toggle": items,
"swap_oob": data.get("remove", False),
Expand Down Expand Up @@ -581,6 +588,8 @@ def get(self, request, method):
items (dict[]): List of items
"""
items_selected = request.GET.getlist(self.name)
if items_selected == [""]:
items_selected = []

override_component_id = request.GET.get("component_id", "")

Expand All @@ -602,8 +611,7 @@ def get(self, request, method):
"multiselect": self.multiselect,
"values": list(self.item_values(selected_options)),
"selected_items": list(selected_options),
"no_result_text": self.no_result_text,
"narrow_search_text": self.narrow_search_text,
"custom_strings": self.custom_strings,
},
request,
)
Expand All @@ -627,8 +635,8 @@ def get(self, request, method):
"required": self.required,
"placeholder": self.placeholder,
"indicator": self.indicator,
"no_result_text": self.no_result_text,
"narrow_search_text": self.narrow_search_text,
"custom_strings": self.custom_strings,
"multiselect": self.multiselect,
"route_name": self.get_route_name(),
"component_id": self.get_component_id(override_component_id),
"show": show,
Expand Down
50 changes: 50 additions & 0 deletions autocomplete/locale/en/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-02-08 20:30+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"

#: templates/autocomplete/strings/available_results.html:2
#, python-format
msgid "%(count)s result available."
msgid_plural "%(count)s results available."
msgstr[0] ""
msgstr[1] ""

#: templates/autocomplete/strings/item_selected.html:2
#, python-format
msgid "%(item)s selected,"
msgstr ""

#: templates/autocomplete/strings/more_results.html:2
#, python-format
msgid "Displaying maximum %(count)s out of %(total_results)s results."
msgid_plural "Displaying maximum %(count)s out of %(total_results)s results."
msgstr[0] ""
msgstr[1] ""

#: templates/autocomplete/strings/multiselect.html:2
msgid "multiselect"
msgstr ""

#: templates/autocomplete/strings/no_results.html:2
msgid "No results found."
msgstr ""

#: templates/autocomplete/strings/nothing_selected.html:2
msgid "Nothing selected."
msgstr ""
50 changes: 50 additions & 0 deletions autocomplete/locale/fr/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-02-08 20:30+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"

#: templates/autocomplete/strings/available_results.html:2
#, python-format
msgid "%(count)s result available."
msgid_plural "%(count)s results available."
msgstr[0] "%(count)s résultat disponible"
msgstr[1] "%(count)s résultats disponibles"

#: templates/autocomplete/strings/item_selected.html:2
#, python-format
msgid "%(item)s selected,"
msgstr "%(item)s sélectionné"

#: templates/autocomplete/strings/more_results.html:2
#, python-format
msgid "Displaying maximum %(count)s out of %(total_results)s results."
msgid_plural "Displaying maximum %(count)s out of %(total_results)s results."
msgstr[0] "Affichage maximum de %(count)s résultat sur %(total_results)s."
msgstr[1] "Affichage maximum de %(count)s résultats sur %(total_results)s."

#: templates/autocomplete/strings/multiselect.html:2
msgid "multiselect"
msgstr "sélection multiple"

#: templates/autocomplete/strings/no_results.html:2
msgid "No results found."
msgstr "Aucun résultat trouvé."

#: templates/autocomplete/strings/nothing_selected.html:2
msgid "Nothing selected."
msgstr "Rien de sélectionné."
Loading

0 comments on commit 3c040f3

Please sign in to comment.