Skip to content

Commit 3201b90

Browse files
committed
Improve the access change edit form
It now uses the "big" class that the settings form uses, so the fieldsets are laid out horizontally when possible. This commit adds some JavaScript to make the search field for the members list filter the list of members. There's a little change to the form.big styling so a help block at the start of a fieldset gets the right margin-top.
1 parent e813679 commit 3201b90

File tree

4 files changed

+168
-119
lines changed

4 files changed

+168
-119
lines changed

numbas_lti/static/lockdown_settings_form.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@ function toggle_lockdown_fields() {
88
Object.entries(lockdown_fields).forEach(([value, fields]) => {
99
for(let f of fields) {
1010
const show = shown_fields.indexOf(f) >= 0;
11-
let group = document.getElementById(`id_${f}`).parentElement;
11+
const input = document.getElementById(`id_${f}`);
12+
if(!input) {
13+
continue;
14+
}
15+
let group = input.parentElement;
1216
group.classList.toggle('hidden',!show);
1317
}
1418
});

numbas_lti/static/nrps_form.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
const search_input = document.getElementById('nrps-member-search');
2+
3+
function filter_members(e) {
4+
let query = search_input.value;
5+
if(e.inputType == 'insertReplacementText') {
6+
const pk = e.data;
7+
const tr = document.querySelector(`#nrps-member-table tr[data-user-id="${pk}"]`);
8+
if(tr) {
9+
query = tr.querySelector('.name').textContent;
10+
}
11+
search_input.value = query;
12+
}
13+
query = query.trim().toLowerCase();
14+
for(let tr of document.querySelectorAll('#nrps-member-table tr.member')) {
15+
const data = ['name', 'username', 'email'].map(s => tr.getAttribute(`data-${s}`));
16+
const matches = data.some(d => d.toLowerCase().includes(query));
17+
if(matches) {
18+
tr.classList.remove('hidden');
19+
} else {
20+
tr.classList.add('hidden');
21+
}
22+
}
23+
}
24+
25+
search_input.addEventListener('input', filter_members);

numbas_lti/static/numbas_lti.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,10 @@ form.big fieldset .help-block {
336336
text-align: right;
337337
}
338338

339+
form.big fieldset legend + .help-block {
340+
margin-top: 0;
341+
}
342+
339343
form.big .fieldsets {
340344
display: flex;
341345
flex-wrap: wrap;

numbas_lti/templates/numbas_lti/management/access_change/edit.html

Lines changed: 134 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -23,135 +23,150 @@ <h1>{% if create %}{% translate "Create an access change" %}{% else %}{% transla
2323
{% endif %}
2424
<p class="help-block">{% blocktranslate %}Only fill in the fields you wish to change. Fields left blank will not override the resource's normal settings.{% endblocktranslate %}</p>
2525

26-
<form class="form-inline" method="POST" action="{% if create %}{% url_with_lti 'create_access_change' resource.pk %}{% else %}{% url_with_lti 'update_access_change' object.pk %}{% endif %}">
26+
<form class="big" method="POST" action="{% if create %}{% url_with_lti 'create_access_change' resource.pk %}{% else %}{% url_with_lti 'update_access_change' object.pk %}{% endif %}">
2727
{{form.resource}}
2828
{% csrf_token %}
2929
{% get_current_timezone as TIME_ZONE %}
3030

31-
<fieldset>
32-
<legend>{% translate "About this access change" %}</legend>
33-
{{form.description.label_tag}}
34-
{{form.description}}
35-
</fieldset>
36-
37-
<fieldset>
38-
<legend>{% translate "Availability dates" %}</legend>
39-
<p class="help-block">{% blocktranslate with TIME_ZONE=TIME_ZONE %}All times are in the timezone <strong>{{TIME_ZONE}}</strong>.{% endblocktranslate %}</p>
40-
41-
{{form.available_from.label_tag}}
42-
{{form.available_from}}
43-
<p class="help-block">
44-
{% translate "Instead of" %} {% time_tag resource.available_from %}.
45-
</p>
46-
47-
{{form.available_until.label_tag}}
48-
{{form.available_until}}
49-
<p class="help-block">
50-
{% translate "Instead of" %} {% time_tag resource.available_until %}.
51-
</p>
52-
53-
<label>{% translate "Extend the deadline by" %}</label>
54-
{{form.extend_deadline_days}}
55-
<label for="{{form.extend_deadline_days.auto_id}}">{{form.extend_deadline_days.label}}</label>
56-
{% translate "and" %}
57-
{{form.extend_deadline_minutes}}
58-
<label for="{{form.extend_deadline_minutes.auto_id}}">{{form.extend_deadline_minutes.label}}</label>
59-
60-
<p class="help-block">
61-
{% blocktranslate %}Use "Extend the deadline by" to move the resource's normal "Available until" date.{% endblocktranslate %}
62-
</p>
63-
</fieldset>
64-
65-
{% if resource.exam.has_duration %}
66-
<fieldset>
67-
<legend>{% translate "Exam duration" %}</legend>
68-
<p>
69-
<label for="{{form.extend_duration.id_for_label}}">{{form.extend_duration.label}}</label>
70-
{{form.extend_duration}}
71-
{{form.extend_duration_units}}
72-
</p>
73-
<p>
74-
<label for="{{form.disable_duration.id_for_label}}">{{form.disable_duration.label}}</label>
75-
{{form.disable_duration}}
76-
</p>
77-
<p class="help-block">
78-
{% blocktranslate %}Change the length of time the student has to complete an attempt after starting it.{% endblocktranslate %}
79-
</p>
80-
</fieldset>
81-
{% endif %}
82-
<fieldset>
83-
<legend>{% translate "Number of attempts" %}</legend>
84-
85-
{{form.max_attempts.label_tag}}
86-
{{form.max_attempts}}
87-
<p class="help-block">
88-
{% blocktranslate with value=resource.max_attempts %}Instead of {{value}}.{% endblocktranslate %}
89-
</p>
90-
</fieldset>
91-
<fieldset>
92-
<legend>{% trans "Lockdown app" %}</legend>
93-
{{form.require_lockdown_app}}
94-
{{form.lockdown_app_password}}
95-
{{form.seb_settings}}
96-
</fieldset>
97-
<fieldset>
98-
<legend>{% translate "Applies to" %}</legend>
99-
100-
{% if nrps_members %}
101-
<label for="nrps-member-search">Search for a student by name:</label>
102-
<input id="nrps-member-search" type="search" list="nrps_members_list" placeholder="{% translate "Enter a student's name" %}">
103-
<datalist id="nrps_members_list">
104-
{% for member in nrps_members %}
105-
<option value="{{member.user_id}}">{{member.name}}</option>
106-
{% endfor %}
107-
</datalist>
108-
109-
<table>
110-
<thead>
111-
<tr>
112-
<th scope="col">{% translate "Apply?" %}</th>
113-
<th scope="col">{% translate "Name" %}</th>
114-
<th scope="col">{% translate "Username" %}</th>
115-
<th scope="col">{% translate "Email address" %}</th>
116-
</tr>
117-
</thead>
118-
<tbody>
119-
{% for member in nrps_members %}
120-
{% if member.student %}
121-
{% with id="nrps_applies_to-"|add:member.user_id %}
122-
<tr>
123-
<td><input id="{{id}}" type="checkbox" name="nrps_applies_to" value="{{member.user_id}}" {% if member.user_id in form.nrps_applies_to.value %}checked{% endif %}></td>
124-
<td><label for="{{id}}">{{member.name}}</label></td>
125-
{% if member.ext_user_username %}
126-
<td><code>{% if member.ext_user_username %}{{member.ext_user_username}}{% else %}{{member.user_id}}{% endif %}</code></td>
127-
{% endif %}
128-
<td>
129-
{% if member.email %}
130-
<code>{{member.email}}</code>
131-
{% endif %}
132-
</td>
133-
</li>
134-
{% endwith %}
135-
{% endif %}
136-
{% endfor %}
137-
</table>
31+
<div class="fieldsets">
32+
<fieldset>
33+
<legend>{% translate "About this access change" %}</legend>
34+
{{form.description.label_tag}}
35+
{{form.description}}
36+
</fieldset>
37+
38+
<fieldset>
39+
<legend>{% translate "Availability dates" %}</legend>
40+
<p class="help-block">{% blocktranslate with TIME_ZONE=TIME_ZONE %}All times are in the timezone <strong>{{TIME_ZONE}}</strong>.{% endblocktranslate %}</p>
13841

139-
{% else %}
42+
<p>
43+
{{form.available_from.label_tag}}
44+
{{form.available_from}}
45+
</p>
46+
<p class="help-block">
47+
{% translate "Instead of" %} {% time_tag resource.available_from %}.
48+
</p>
14049

141-
{{form.usernames}}
50+
<p>
51+
{{form.available_until.label_tag}}
52+
{{form.available_until}}
53+
</p>
54+
<p class="help-block">
55+
{% translate "Instead of" %} {% time_tag resource.available_until %}.
56+
</p>
57+
58+
<p>
59+
<label>{% translate "Extend the deadline by" %}</label>
60+
{{form.extend_deadline_days}}
61+
<label for="{{form.extend_deadline_days.auto_id}}">{{form.extend_deadline_days.label}}</label>
62+
{% translate "and" %}
63+
{{form.extend_deadline_minutes}}
64+
<label for="{{form.extend_deadline_minutes.auto_id}}">{{form.extend_deadline_minutes.label}}</label>
65+
</p>
14266
<p class="help-block">
143-
{% blocktranslate with username=user.username %}Your username is <code>{{username}}</code>.{% endblocktranslate %}
67+
{% blocktranslate %}Use "Extend the deadline by" to move the resource's normal "available until" date.{% endblocktranslate %}
68+
</p>
69+
</fieldset>
70+
71+
{% if resource.exam.has_duration %}
72+
<fieldset>
73+
<legend>{% translate "Exam duration" %}</legend>
74+
<p>
75+
<label for="{{form.extend_duration.id_for_label}}">{{form.extend_duration.label}}</label>
76+
{{form.extend_duration}}
77+
{{form.extend_duration_units}}
78+
</p>
79+
<p>
80+
<label for="{{form.disable_duration.id_for_label}}">{{form.disable_duration.label}}</label>
81+
{{form.disable_duration}}
14482
</p>
145-
{{form.emails}}
14683
<p class="help-block">
147-
{% if user.email %}
148-
{% blocktranslate with email=user.email %}Your email address is <code>{{email}}</code>.{% endblocktranslate %}
149-
{% else %}
150-
{% translate "The LTI connection doesn't seem to share email addresses. You might not be able to identify students by email address." %}
151-
{% endif %}
84+
{% blocktranslate %}Change the length of time the student has to complete an attempt after starting it.{% endblocktranslate %}
15285
</p>
86+
</fieldset>
15387
{% endif %}
154-
</fieldset>
88+
<fieldset>
89+
<legend>{% translate "Number of attempts" %}</legend>
90+
91+
<p>
92+
{{form.max_attempts.label_tag}}
93+
{{form.max_attempts}}
94+
</p>
95+
<p class="help-block">
96+
{% blocktranslate with value=resource.max_attempts %}Instead of {{value}}.{% endblocktranslate %}
97+
</p>
98+
</fieldset>
99+
<fieldset>
100+
<legend>{% trans "Lockdown app" %}</legend>
101+
{{form.require_lockdown_app}}
102+
<p>
103+
{{form.lockdown_app_password.label_tag}}
104+
{{form.lockdown_app_password}}
105+
</p>
106+
<p>
107+
{{form.seb_settings.label_tag}}
108+
{{form.seb_settings}}
109+
</p>
110+
</fieldset>
111+
<fieldset>
112+
<legend>{% translate "Applies to" %}</legend>
113+
114+
{% if nrps_members %}
115+
<label for="nrps-member-search">Search for a student by name:</label>
116+
<input id="nrps-member-search" type="search" list="nrps_members_list" placeholder="{% translate "Enter a student's name" %}">
117+
<datalist id="nrps_members_list">
118+
{% for member in nrps_members %}
119+
<option value="{{member.user_id}}">{{member.name}}</option>
120+
{% endfor %}
121+
</datalist>
122+
123+
<table id="nrps-member-table">
124+
<thead>
125+
<tr>
126+
<th scope="col">{% translate "Apply?" %}</th>
127+
<th scope="col">{% translate "Name" %}</th>
128+
<th scope="col">{% translate "Username" %}</th>
129+
<th scope="col">{% translate "Email address" %}</th>
130+
</tr>
131+
</thead>
132+
<tbody>
133+
{% for member in nrps_members %}
134+
{% if member.student %}
135+
{% with id="nrps_applies_to-"|add:member.user_id %}
136+
<tr class="member" data-user-id="{{member.user_id}}" data-name="{{member.name}}" data-username="{{member.ext_user_username}}" data-email="{{member.email}}">
137+
<td><input id="{{id}}" type="checkbox" name="nrps_applies_to" value="{{member.user_id}}" {% if member.user_id in form.nrps_applies_to.value %}checked{% endif %}></td>
138+
<td><label for="{{id}}" class="name">{{member.name}}</label></td>
139+
{% if member.ext_user_username %}
140+
<td><code class="username">{% if member.ext_user_username %}{{member.ext_user_username}}{% else %}{{member.user_id}}{% endif %}</code></td>
141+
{% endif %}
142+
<td>
143+
{% if member.email %}
144+
<code>{{member.email}}</code>
145+
{% endif %}
146+
</td>
147+
</li>
148+
{% endwith %}
149+
{% endif %}
150+
{% endfor %}
151+
</table>
152+
153+
{% else %}
154+
155+
{{form.usernames}}
156+
<p class="help-block">
157+
{% blocktranslate with username=user.username %}Your username is <code>{{username}}</code>.{% endblocktranslate %}
158+
</p>
159+
{{form.emails}}
160+
<p class="help-block">
161+
{% if user.email %}
162+
{% blocktranslate with email=user.email %}Your email address is <code>{{email}}</code>.{% endblocktranslate %}
163+
{% else %}
164+
{% translate "The LTI connection doesn't seem to share email addresses. You might not be able to identify students by email address." %}
165+
{% endif %}
166+
</p>
167+
{% endif %}
168+
</fieldset>
169+
</div>
155170
<p><button class="button large primary" type="submit">{% translate "Save" %}</button> <a class="button link" href="{% url_with_lti 'resource_access_changes' resource.pk %}">{% translate "Cancel" %}</a></p>
156171
</form>
157172
{% endblock management_content %}
@@ -160,6 +175,7 @@ <h1>{% if create %}{% translate "Create an access change" %}{% else %}{% transla
160175
{{block.super}}
161176
{{form.media}}
162177
<script src="{% static 'lockdown_settings_form.js' %}" defer></script>
178+
<script src="{% static 'nrps_form.js' %}" defer></script>
163179
{% endblock javascripts %}
164180

165181
{% block stylesheets %}

0 commit comments

Comments
 (0)