-
Notifications
You must be signed in to change notification settings - Fork 0
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
Differentiate display from user ID and improve user selection #23
Comments
I can use the actors_from_ids mechanism to show better actors, and I can update the design of the |
From https://alphagov.github.io/accessible-autocomplete/#progressive-enhancement
Instances with more than a few hundred users will be rare, I'm going to do that. |
I tried getting the alphagov one working - it's pretty glitchy for me: I had to hack the source code and add the selected text here to disable the 1Password icon on it too: Here's my prototype: diff --git a/datasette_acl/templates/manage_acl_group.html b/datasette_acl/templates/manage_acl_group.html
index b293f42..529b6e8 100644
--- a/datasette_acl/templates/manage_acl_group.html
+++ b/datasette_acl/templates/manage_acl_group.html
@@ -3,6 +3,8 @@
{% block title %}{{ name }}{% endblock %}
{% block extra_head %}
+<script src="{{ urls.static_plugins("datasette-acl", "accessible-autocomplete.min.js") }}"></script>
+<link rel="stylesheet" href="{{ urls.static_plugins("datasette-acl", "accessible-autocomplete.min.css") }}">
<style>
.remove-button {
background-color: #fff;
@@ -75,14 +77,22 @@
<form action="{{ request.path }}" method="post">
<input type="hidden" name="csrftoken" value="{{ csrftoken() }}">
- <p><label>User ID <input type="text" data-1p-ignore name="add"{% if valid_actor_ids %} list="actor-ids"{% endif %}></label> <input type="submit" value="Add member"></p>
- {% if valid_actor_ids %}
- <datalist id="actor-ids">{% for actor_id in valid_actor_ids %}
- <option value="{{ actor_id }}"></option>
+ <p><label for="id_add">User ID</label> <select id="id_add" name="add">
+ {% for actor_id in valid_actor_ids %}
+ <option>{{ actor_id }}</option>
{% endfor %}
- </datalist>
- {% endif %}
+ </select>
</form>
+
+
+<script>
+const userSelect = document.querySelector('#id_add');
+
+accessibleAutocomplete.enhanceSelectElement({
+ selectElement: userSelect
+});
+document.getElementById('add').setAttribute('data-1p-ignore', '');
+</script>
{% endif %}
{% endif %} |
Got this working with https://projects.verou.me/awesomplete/ |
I'd prefer it if selecting the item submitted the form, you have to enter twice right now. |
Here's that prototype so far (the custom event thing doesn't work though): diff --git a/datasette_acl/templates/manage_acl_group.html b/datasette_acl/templates/manage_acl_group.html
index b293f42..9bbf7f3 100644
--- a/datasette_acl/templates/manage_acl_group.html
+++ b/datasette_acl/templates/manage_acl_group.html
@@ -3,6 +3,8 @@
{% block title %}{{ name }}{% endblock %}
{% block extra_head %}
+<script src="{{ urls.static_plugins("datasette-acl", "awesomplete.min.js") }}"></script>
+<link rel="stylesheet" href="{{ urls.static_plugins("datasette-acl", "awesomplete.css") }}">
<style>
.remove-button {
background-color: #fff;
@@ -75,7 +77,7 @@
<form action="{{ request.path }}" method="post">
<input type="hidden" name="csrftoken" value="{{ csrftoken() }}">
- <p><label>User ID <input type="text" data-1p-ignore name="add"{% if valid_actor_ids %} list="actor-ids"{% endif %}></label> <input type="submit" value="Add member"></p>
+ <p><label>User ID <input id="id_add" type="text" data-minchars="1" data-1p-ignore name="add"{% if valid_actor_ids %} list="actor-ids"{% endif %}></label> <input type="submit" value="Add member"></p>
{% if valid_actor_ids %}
<datalist id="actor-ids">{% for actor_id in valid_actor_ids %}
<option value="{{ actor_id }}"></option>
@@ -118,10 +120,16 @@
{% endif %}
<script>
-// Focus on add input if we just added a member
-if (window.location.hash === '#focus-add') {
- document.querySelector('input[name="add"]').focus();
-}
+document.addEventListener('DOMContentLoaded', function() {
+ document.querySelector('#id_add').addEventListener('awesomplete-select', (ev) => {
+ console.log(ev);
+ // this.closest('form').submit();
+ });
+ // Focus on add input if we just added a member
+ if (window.location.hash === '#focus-add') {
+ document.querySelector('input[name="add"]').focus();
+ }
+});
</script>
{% endblock %} |
I'm going to try https://choices-js.github.io/Choices/ |
That prototoype so far: diff --git a/datasette_acl/templates/manage_acl_group.html b/datasette_acl/templates/manage_acl_group.html
index b293f42..12b1c0b 100644
--- a/datasette_acl/templates/manage_acl_group.html
+++ b/datasette_acl/templates/manage_acl_group.html
@@ -3,6 +3,8 @@
{% block title %}{{ name }}{% endblock %}
{% block extra_head %}
++<script src="{{ urls.static_plugins("datasette-acl", "choices-9.0.1.min.js") }}"></script>
++<link rel="stylesheet" href="{{ urls.static_plugins("datasette-acl", "choices-9.0.1.min.css") }}">
<style>
.remove-button {
background-color: #fff;
@@ -75,13 +77,17 @@
<form action="{{ request.path }}" method="post">
<input type="hidden" name="csrftoken" value="{{ csrftoken() }}">
- <p><label>User ID <input type="text" data-1p-ignore name="add"{% if valid_actor_ids %} list="actor-ids"{% endif %}></label> <input type="submit" value="Add member"></p>
- {% if valid_actor_ids %}
- <datalist id="actor-ids">{% for actor_id in valid_actor_ids %}
- <option value="{{ actor_id }}"></option>
- {% endfor %}
- </datalist>
- {% endif %}
+ <div style="display: flex; align-items: center; gap: 10px; max-width: 500px">
+ <label for="id_add" style="flex-shrink: 0;">User ID</label>
+ <div class="choices" data-type="select-one" tabindex="0" style="flex-grow: 1;">
+ <select id="id_add" name="add">
+ <option></option>
+ {% for actor_id in valid_actor_ids %}
+ <option>{{ actor_id }}</option>
+ {% endfor %}
+ </select>
+ </div>
+ </div>
</form>
{% endif %}
{% endif %}
@@ -118,10 +124,17 @@
{% endif %}
<script>
-// Focus on add input if we just added a member
-if (window.location.hash === '#focus-add') {
- document.querySelector('input[name="add"]').focus();
-}
+document.addEventListener('DOMContentLoaded', function() {
+ const select = document.querySelector('#id_add');
+ const choices = new Choices(select);
+ select.addEventListener('addItem', (ev) => {
+ ev.target.closest('form').submit()
+ });
+ // Focus on add input if we just added a member
+ if (window.location.hash === '#focus-add') {
+ choices.showDropdown();
+ }
+});
</script>
{% endblock %} |
Claude artifact showing what it could look like if I use this rather than the table of checkboxes: https://claude.site/artifacts/3b83782b-74d3-4759-ac68-523fe2a905eb <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Group Permissions UI</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/choices.js/10.2.0/choices.min.css">
<style>
body {
font-family: Arial, sans-serif;
margin: 20px;
background-color: #f0f0f0;
}
.container {
background-color: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
h1 {
color: #333;
}
.group-row {
display: flex;
align-items: center;
margin-bottom: 10px;
padding: 10px;
background-color: #f9f9f9;
border-radius: 4px;
}
.group-name {
width: 150px;
font-weight: bold;
color: #4a4a4a;
}
select[multiple] {
min-width: 200px;
}
/* Choices.js custom styles */
.choices__inner {
min-height: 30px;
padding: 4px 7.5px 4px 3.75px;
}
.choices__list--multiple .choices__item {
font-size: 12px;
padding: 2px 5px;
margin-bottom: 0;
}
</style>
</head>
<body>
<div class="container">
<h1>Group Permissions</h1>
<div id="groups-container">
<div class="group-row">
<span class="group-name">staff (1)</span>
<select multiple id="select-staff">
<option value="insert-row">insert-row</option>
<option value="delete-row">delete-row</option>
<option value="update-row">update-row</option>
<option value="alter-table" selected>alter-table</option>
<option value="drop-table">drop-table</option>
</select>
</div>
<div class="group-row">
<span class="group-name">devs (5)</span>
<select multiple id="select-devs">
<option value="insert-row" selected>insert-row</option>
<option value="delete-row" selected>delete-row</option>
<option value="update-row" selected>update-row</option>
<option value="alter-table" selected>alter-table</option>
<option value="drop-table">drop-table</option>
</select>
</div>
<div class="group-row">
<span class="group-name">newgroup (0)</span>
<select multiple id="select-newgroup">
<option value="insert-row">insert-row</option>
<option value="delete-row">delete-row</option>
<option value="update-row">update-row</option>
<option value="alter-table" selected>alter-table</option>
<option value="drop-table">drop-table</option>
</select>
</div>
<div class="group-row">
<span class="group-name">muppets (5)</span>
<select multiple id="select-muppets">
<option value="insert-row">insert-row</option>
<option value="delete-row">delete-row</option>
<option value="update-row">update-row</option>
<option value="alter-table">alter-table</option>
<option value="drop-table">drop-table</option>
</select>
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/choices.js/10.2.0/choices.min.js"></script>
<script>
document.addEventListener('DOMContentLoaded', function() {
const selects = document.querySelectorAll('select[multiple]');
selects.forEach(select => {
new Choices(select, {
removeItemButton: true,
classNames: {
containerOuter: 'choices custom-choices',
}
});
});
});
</script>
</body>
</html> Conversation transcript: https://gist.github.com/simonw/7b87b24cd53daf8ea05170c3c8013e3c |
I implemented Choices for permission selection and user selection here: Still need to differentiate user ID from user display though. |
New |
I'm going to rename |
The autocomplete from this issue:
Isn't fit for purpose on Datasette Cloud, where user IDs are integers.
Need to be able to display their "display names" in lists of e.g. members of a group, and also autocomplete against those when adding users to groups or to table permissions.
Also: the
<datalist>
autocomplete really isn't very good - it still allows freeform text input and, at least on Firefox, shows a whole butch of irrelevant suggestions mixed in with the "valid" options:The text was updated successfully, but these errors were encountered: