Skip to content

Commit 8d7b5d7

Browse files
committed
Keep track of preselected cache options in localStorage
Resolves #9447
1 parent 462b071 commit 8d7b5d7

File tree

9 files changed

+95
-36
lines changed

9 files changed

+95
-36
lines changed

CHANGELOG-WIP.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
- The `maxCachedCloudImageSize` config setting is now set to `0` by default. ([#17997](https://github.com/craftcms/cms/pull/17997))
4747
- System message emails are now rendered using GitHub-flavored Markdown. ([#18058](https://github.com/craftcms/cms/discussions/18058))
4848
- Drag-and-drop icons are now longer shown for devices that don’t support pointer events. ([#18067](https://github.com/craftcms/cms/pull/18067))
49+
- The Caches utility now keeps track of which options were previously selected. ([#9447](https://github.com/craftcms/cms/discussions/9447))
4950

5051
### Development
5152
- Reference tags now support fallback values when no attribute is specified. ([#17688](https://github.com/craftcms/cms/pull/17688))
@@ -118,6 +119,7 @@
118119
- `craft\services\ElementSources::sourceExists()` now has a `$page` argument. ([#17779](https://github.com/craftcms/cms/pull/17779))
119120
- `craft\web\Request::accepts()` now accepts wildcard characters (`*`) in the `$contentType` argument, to check for a range of MIME types (e.g. `application/*+json`).
120121
- `craft\web\Request::getAcceptsJson()` now returns `true` for requests with `Content-Type` headers that match `application/*+json`, in addition to `application/json`.
122+
- Checkbox selects can now be configured with a `storageKey` setting.
121123
- Deprecated `craft\fields\BaseRelationField::$showCardsInGrid`.
122124
- Deprecated `craft\fields\Matrix::$showCardsInGrid`.
123125
- Deprecated `craft\helpers\StringHelper::capitalizePersonalName()`. `toPascalCase()` should be used instead.

src/templates/_components/utilities/ClearCaches.twig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
options: cacheOptions,
1212
showAllOption: true,
1313
values: '*',
14+
storageKey: 'cache-options',
1415
}) }}
1516

1617
<div class="buttons">

src/templates/_includes/forms/checkboxSelect.twig

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
{%- set values = values ?? [] %}
44
{%- set disabled = disabled ?? false %}
55
{%- set sortable = sortable ?? false %}
6+
{%- set storageKey = storageKey ?? null %}
67

78
{% set options = options|map((value, key) => value is iterable ? value : {
89
label: value,
@@ -25,6 +26,9 @@
2526
{% set containerAttributes = {
2627
id,
2728
class: ['checkbox-select']|merge((class ?? [])|explodeClass),
29+
data: {
30+
'storage-key': storageKey,
31+
},
2832
}|merge(containerAttributes ?? [], recursive=true) %}
2933

3034
{%- if block('attr') is defined %}

src/web/assets/cp/dist/cp.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/web/assets/cp/dist/cp.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/web/assets/cp/src/js/Craft.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3089,7 +3089,9 @@ $.extend($.fn, {
30893089
checkboxselect: function () {
30903090
return this.each(function () {
30913091
if (!$.data(this, 'checkboxSelect')) {
3092-
new Garnish.CheckboxSelect(this);
3092+
new Garnish.CheckboxSelect(this, {
3093+
storageKey: this.getAttribute('data-storage-key'),
3094+
});
30933095
}
30943096
});
30953097
},

src/web/assets/garnish/dist/garnish.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/web/assets/garnish/dist/garnish.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/web/assets/garnish/src/CheckboxSelect.js

Lines changed: 81 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -5,43 +5,93 @@ import $ from 'jquery';
55
/**
66
* Checkbox select class
77
*/
8-
export default Base.extend({
9-
$container: null,
10-
$all: null,
11-
$options: null,
8+
export default Base.extend(
9+
{
10+
$container: null,
11+
$all: null,
12+
$options: null,
1213

13-
init: function (container) {
14-
this.$container = $(container);
14+
init: function (container, settings) {
15+
this.$container = $(container);
16+
this.setSettings(settings, Garnish.CheckboxSelect.defaults);
1517

16-
// Is this already a checkbox select?
17-
if (this.$container.data('checkboxSelect')) {
18-
console.warn('Double-instantiating a checkbox select on an element');
19-
this.$container.data('checkboxSelect').destroy();
20-
}
18+
// Is this already a checkbox select?
19+
if (this.$container.data('checkboxSelect')) {
20+
console.warn('Double-instantiating a checkbox select on an element');
21+
this.$container.data('checkboxSelect').destroy();
22+
}
2123

22-
this.$container.data('checkboxSelect', this);
24+
this.$container.data('checkboxSelect', this);
2325

24-
var $checkboxes = this.$container.find('input');
25-
this.$all = $checkboxes.filter('.all:first');
26-
this.$options = $checkboxes.not(this.$all);
26+
var $checkboxes = this.$container.find('input');
27+
this.$all = $checkboxes.filter('.all:first');
28+
this.$options = $checkboxes.not(this.$all);
2729

28-
this.addListener(this.$all, 'change', 'onAllChange');
29-
},
30+
this.addListener(this.$all, 'change', 'onAllChange');
3031

31-
onAllChange: function () {
32-
var isAllChecked = this.$all.prop('checked');
32+
if (this.settings.storageKey) {
33+
const selectedOptions = Craft.getLocalStorage(this.settings.storageKey);
34+
if (selectedOptions) {
35+
// all?
36+
if (this.$all.length && selectedOptions.includes(this.$all.val())) {
37+
if (!this.isAllChecked()) {
38+
this.$all.prop('checked', true).trigger('change');
39+
}
40+
} else {
41+
if (this.isAllChecked()) {
42+
this.$all.prop('checked', false).trigger('change');
43+
}
44+
this.$options.each((i, checkbox) => {
45+
const included = selectedOptions.includes(checkbox.value);
46+
const checked = checkbox.checked;
47+
if (included !== checked) {
48+
checkbox.checked = included;
49+
$(checkbox).trigger('change');
50+
}
51+
});
52+
}
53+
}
3354

34-
this.$options.prop({
35-
checked: isAllChecked,
36-
disabled: isAllChecked,
37-
});
38-
},
55+
$checkboxes.on('change', () => {
56+
const selectedOptions = [];
57+
if (this.$all.prop('checked')) {
58+
selectedOptions.push(this.$all.val());
59+
} else {
60+
this.$options.each((i, checkbox) => {
61+
if (checkbox.checked) {
62+
selectedOptions.push(checkbox.value);
63+
}
64+
});
65+
}
66+
Craft.setLocalStorage(this.settings.storageKey, selectedOptions);
67+
});
68+
}
69+
},
70+
71+
isAllChecked: function () {
72+
return this.$all.prop('checked');
73+
},
74+
75+
onAllChange: function () {
76+
const isAllChecked = this.isAllChecked();
77+
78+
this.$options.prop({
79+
checked: isAllChecked,
80+
disabled: isAllChecked,
81+
});
82+
},
3983

40-
/**
41-
* Destroy
42-
*/
43-
destroy: function () {
44-
this.$container.removeData('checkboxSelect');
45-
this.base();
84+
/**
85+
* Destroy
86+
*/
87+
destroy: function () {
88+
this.$container.removeData('checkboxSelect');
89+
this.base();
90+
},
4691
},
47-
});
92+
{
93+
defaults: {
94+
storageKey: null,
95+
},
96+
}
97+
);

0 commit comments

Comments
 (0)