mirror of
https://github.com/freedombox/FreedomBox.git
synced 2026-07-29 12:09:37 +00:00
ui: js: Make select all checkbox option available more broadly
- Make the code work outside backups module. - Move code to main.js so that any app can use this functionality. - Make the code work for multiple such form fields in the same page. - Use only pure JS, don't use jQuery. - Add event handlers only after DOM content is loaded to avoid race conditions. Tests performed: - Checking the select-all button checks all options. - De-checking the select-all button de-checks all options. - De-checking one option when everything is checked, de-checks the select-all button. - Checking the last option when everything else is checked, checks the select-all button. - When loading a schedule page with all options checked, select-all button is checked. - When loading a schedule page with some option unchecked, select-all button is unchecked. Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org> Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
This commit is contained in:
parent
77face68b0
commit
9b8388734d
@ -54,7 +54,7 @@ class CreateArchiveForm(forms.Form):
|
||||
regex=r'^[^{}/]*$', required=False, strip=True)
|
||||
selected_apps = forms.MultipleChoiceField(
|
||||
label=_('Included apps'), help_text=_('Apps to include in the backup'),
|
||||
widget=forms.CheckboxSelectMultiple)
|
||||
widget=forms.CheckboxSelectMultiple(attrs={'class': 'has-select-all'}))
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Initialize the form with selectable apps."""
|
||||
@ -71,7 +71,7 @@ class CreateArchiveForm(forms.Form):
|
||||
class RestoreForm(forms.Form):
|
||||
selected_apps = forms.MultipleChoiceField(
|
||||
label=_('Select the apps you want to restore'),
|
||||
widget=forms.CheckboxSelectMultiple)
|
||||
widget=forms.CheckboxSelectMultiple(attrs={'class': 'has-select-all'}))
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Initialize the form with selectable apps."""
|
||||
|
||||
@ -1,66 +0,0 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
/*
|
||||
This file is part of FreedomBox.
|
||||
|
||||
@licstart The following is the entire license notice for the
|
||||
JavaScript code in this page.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
@licend The above is the entire license notice
|
||||
for the JavaScript code in this page.
|
||||
*/
|
||||
|
||||
function addSelectAll() {
|
||||
let ul = document.getElementById('id_backups-selected_apps');
|
||||
let li = document.createElement('li');
|
||||
|
||||
let label = document.createElement('label');
|
||||
label.for = "select_all";
|
||||
|
||||
let checkbox = document.createElement('input');
|
||||
checkbox.type = "checkbox";
|
||||
checkbox.checked = "checked";
|
||||
checkbox.id = "select-all";
|
||||
|
||||
label.appendChild(checkbox);
|
||||
li.appendChild(label);
|
||||
|
||||
ul.insertBefore(li, ul.childNodes[0]);
|
||||
};
|
||||
|
||||
addSelectAll();
|
||||
|
||||
/*
|
||||
* When there is a change on the "select all" checkbox,set the
|
||||
* checked property of all the checkboxes to the value of the
|
||||
* "select all" checkbox
|
||||
*/
|
||||
$("#select-all").change(function() {
|
||||
$("[type=checkbox]").prop('checked', $(this).prop("checked"));
|
||||
});
|
||||
|
||||
|
||||
$('[type=checkbox]').change(function() {
|
||||
// If the rest of the checkbox items are checked check the "select all" checkbox as well
|
||||
if ($('[type=checkbox]:checked').length == ($('[type=checkbox]').length - 1)) {
|
||||
$("#select-all").prop('checked', true);
|
||||
}
|
||||
// Uncheck "select all" if one of the listed checkbox item is unchecked
|
||||
if (false == $(this).prop("checked")) {
|
||||
$("#select-all").prop('checked', false);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@ -21,7 +21,3 @@
|
||||
</form>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block page_js %}
|
||||
<script type="text/javascript" src="{% static 'backups/select_all.js' %}"></script>
|
||||
{% endblock %}
|
||||
|
||||
@ -29,7 +29,3 @@
|
||||
</p>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block page_js %}
|
||||
<script type="text/javascript" src="{% static 'backups/select_all.js' %}"></script>
|
||||
{% endblock %}
|
||||
|
||||
@ -454,7 +454,8 @@ def backup_create(browser, app_name, archive_name=None):
|
||||
|
||||
buttons = browser.find_link_by_href('/plinth/sys/backups/create/')
|
||||
submit(browser, buttons.first)
|
||||
browser.find_by_id('select-all').uncheck()
|
||||
eventually(browser.find_by_css, args=['.select-all'])
|
||||
browser.find_by_css('.select-all').first.uncheck()
|
||||
if archive_name:
|
||||
browser.find_by_id('id_backups-name').fill(archive_name)
|
||||
|
||||
|
||||
@ -121,3 +121,66 @@ window.addEventListener('pageshow', function(event) {
|
||||
element.remove();
|
||||
}
|
||||
});
|
||||
|
||||
/*
|
||||
* Select all option for multiple checkboxes.
|
||||
*/
|
||||
document.addEventListener('DOMContentLoaded', function(event) {
|
||||
let parents = document.querySelectorAll('ul.has-select-all');
|
||||
for (const parent of parents) {
|
||||
let li = document.createElement('li');
|
||||
|
||||
let label = document.createElement('label');
|
||||
label.for = "select_all";
|
||||
|
||||
let checkbox = document.createElement('input');
|
||||
checkbox.type = "checkbox";
|
||||
checkbox.setAttribute('class', 'select-all');
|
||||
|
||||
label.appendChild(checkbox);
|
||||
li.appendChild(label);
|
||||
|
||||
parent.insertBefore(li, parent.childNodes[0]);
|
||||
setSelectAllValue(parent);
|
||||
|
||||
checkbox.addEventListener('change', onSelectAllChanged);
|
||||
|
||||
options = parent.querySelectorAll('input.has-select-all');
|
||||
for (const option of options) {
|
||||
option.addEventListener('change', onSelectAllOptionsChanged);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// When there is a change on the "select all" checkbox, set the checked property
|
||||
// of all the checkboxes to the value of the "select all" checkbox
|
||||
function onSelectAllChanged(event) {
|
||||
const selectAllCheckbox = event.currentTarget;
|
||||
const parent = selectAllCheckbox.parentElement.parentElement.parentElement;
|
||||
const options = parent.querySelectorAll('input.has-select-all');
|
||||
for (const option of options) {
|
||||
option.checked = selectAllCheckbox.checked;
|
||||
}
|
||||
}
|
||||
|
||||
// When there is a change on a checkbox controlled by a select all checkbox,
|
||||
// update the value of checkbox.
|
||||
function onSelectAllOptionsChanged(event) {
|
||||
const parent = event.currentTarget.parentElement.parentElement.parentElement;
|
||||
setSelectAllValue(parent);
|
||||
}
|
||||
|
||||
// Set/reset the checked property of "select all" checkbox based on whether all
|
||||
// checkboxes it controls are checked.
|
||||
function setSelectAllValue(parent) {
|
||||
const options = parent.querySelectorAll('input.has-select-all');
|
||||
let enableSelectAll = true;
|
||||
for (const option of options) {
|
||||
if (!option.checked) {
|
||||
enableSelectAll = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
parent.querySelector('.select-all').checked = enableSelectAll;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user