Skip to content

Commit 8f87531

Browse files
committed
Remove jquery dependency from sir-trevor block mixins
1 parent 6ea7cb4 commit 8f87531

File tree

3 files changed

+167
-126
lines changed

3 files changed

+167
-126
lines changed
Lines changed: 69 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,104 +1,115 @@
1-
import { fetchAutocompleteJSON } from 'spotlight/admin/search_typeahead';
1+
import { fetchAutocompleteJSON } from "spotlight/admin/search_typeahead"
22

3-
(function ($){
3+
;(function () {
44
SirTrevor.BlockMixins.Autocompleteable = {
55
mixinName: "Autocompleteable",
66
preload: true,
77

8-
initializeAutocompleteable: function() {
9-
this.on("onRender", this.addAutocompletetoSirTrevorForm);
8+
initializeAutocompleteable: function () {
9+
this.on("onRender", this.addAutocompletetoSirTrevorForm)
1010

11-
if (this['autocomplete_url'] === undefined) {
12-
this.autocomplete_url = function() { return $('form[data-autocomplete-url]').data('autocomplete-url'); };
11+
if (this["autocomplete_url"] === undefined) {
12+
this.autocomplete_url = function () {
13+
const form = document.querySelector("form[data-autocomplete-url]")
14+
return form ? form.dataset.autocompleteUrl : null
15+
}
1316
}
1417

15-
if (this['autocomplete_fetch'] === undefined) {
16-
this.autocomplete_fetch = this.fetchAutocompleteResults;
18+
if (this["autocomplete_fetch"] === undefined) {
19+
this.autocomplete_fetch = this.fetchAutocompleteResults
1720
}
1821

19-
if (this['transform_autocomplete_results'] === undefined) {
20-
this.transform_autocomplete_results = (val) => val
22+
if (this["transform_autocomplete_results"] === undefined) {
23+
this.transform_autocomplete_results = val => val
2124
}
2225

23-
if (this['highlight'] === undefined) {
24-
this.highlight = function(value) {
25-
if (!value) return '';
26-
const queryValue = this.getQueryValue().trim();
27-
return queryValue ? value.replace(new RegExp(queryValue, 'gi'), '<strong>$&</strong>') : value;
26+
if (this["highlight"] === undefined) {
27+
this.highlight = function (value) {
28+
if (!value) return ""
29+
const queryValue = this.getQueryValue().trim()
30+
return queryValue
31+
? value.replace(new RegExp(queryValue, "gi"), "<strong>$&</strong>")
32+
: value
2833
}
2934
}
3035

31-
if (this['autocomplete_control'] === undefined) {
32-
this.autocomplete_control = function() {
33-
const autocompleteID = this.autocompleteID();
36+
if (this["autocomplete_control"] === undefined) {
37+
this.autocomplete_control = function () {
38+
const autocompleteID = this.autocompleteID()
3439
return `
3540
<auto-complete src="${this.autocomplete_url()}" for="${autocompleteID}-popup" fetch-on-empty>
3641
<input type="text" name="${autocompleteID}" placeholder="${i18n.t("blocks:autocompleteable:placeholder")}" data-default-typeahead>
3742
<ul id="${autocompleteID}-popup"></ul>
3843
<div id="${autocompleteID}-popup-feedback" class="visually-hidden"></div>
3944
</auto-complete>
40-
` };
45+
`
46+
}
4147
}
4248

43-
if (this['autocomplete_element_template'] === undefined) {
44-
this.autocomplete_element_template = function(item) {
49+
if (this["autocomplete_element_template"] === undefined) {
50+
this.autocomplete_element_template = function (item) {
4551
return `<li role="option" data-autocomplete-value="${item.id}">${this.autocomplete_template(item)}</li>`
4652
}
4753
}
4854
},
4955

50-
queryTokenizer: function(query) {
51-
return query.trim().toLowerCase().split(/\s+/).filter(Boolean);
56+
queryTokenizer: function (query) {
57+
return query.trim().toLowerCase().split(/\s+/).filter(Boolean)
5258
},
5359

54-
filterResults: function(data, query) {
55-
const queryStrings = this.queryTokenizer(query);
60+
filterResults: function (data, query) {
61+
const queryStrings = this.queryTokenizer(query)
5662
return data.filter(item => {
57-
const lowerTitle = item.title.toLowerCase();
58-
return queryStrings.some(queryString => lowerTitle.includes(queryString));
59-
});
63+
const lowerTitle = item.title.toLowerCase()
64+
return queryStrings.some(queryString =>
65+
lowerTitle.includes(queryString)
66+
)
67+
})
6068
},
6169

62-
fetchAutocompleteResults: async function(url) {
63-
const result = await fetchAutocompleteJSON(url);
64-
const transformed = this.transform_autocomplete_results(result);
65-
this.fetchedData = {};
66-
transformed.map(item => this.fetchedData[item.id] = item);
67-
return transformed.map(item => this.autocomplete_element_template(item)).join('');
70+
fetchAutocompleteResults: async function (url) {
71+
const result = await fetchAutocompleteJSON(url)
72+
const transformed = this.transform_autocomplete_results(result)
73+
this.fetchedData = {}
74+
transformed.map(item => (this.fetchedData[item.id] = item))
75+
return transformed
76+
.map(item => this.autocomplete_element_template(item))
77+
.join("")
6878
},
6979

70-
fetchOnceAndFilterLocalResults: async function(url) {
80+
fetchOnceAndFilterLocalResults: async function (url) {
7181
if (this.fetchedData === undefined) {
72-
await this.fetchAutocompleteResults(url);
82+
await this.fetchAutocompleteResults(url)
7383
}
74-
const query = url.searchParams.get('q');
75-
const data = Object.values(this.fetchedData);
76-
const filteredData = query ? this.filterResults(data, query) : data;
77-
return filteredData.map(item => this.autocomplete_element_template(item)).join('');
84+
const query = url.searchParams.get("q")
85+
const data = Object.values(this.fetchedData)
86+
const filteredData = query ? this.filterResults(data, query) : data
87+
return filteredData
88+
.map(item => this.autocomplete_element_template(item))
89+
.join("")
7890
},
7991

80-
autocompleteID: function() {
81-
return this.blockID + '-autocomplete';
92+
autocompleteID: function () {
93+
return this.blockID + "-autocomplete"
8294
},
8395

84-
getQueryValue: function() {
85-
const completer = this.inner.querySelector("auto-complete > input");
86-
return completer.value;
96+
getQueryValue: function () {
97+
const completer = this.inner.querySelector("auto-complete > input")
98+
return completer.value
8799
},
88100

89-
addAutocompletetoSirTrevorForm: function() {
90-
const completer = this.inner.querySelector("auto-complete");
91-
completer.fetchResult = this.autocomplete_fetch.bind(this);
92-
completer.addEventListener('auto-complete-change', (e) => {
93-
const data = this.fetchedData[e.relatedTarget.value];
101+
addAutocompletetoSirTrevorForm: function () {
102+
const completer = this.inner.querySelector("auto-complete")
103+
completer.fetchResult = this.autocomplete_fetch.bind(this)
104+
completer.addEventListener("auto-complete-change", e => {
105+
const data = this.fetchedData[e.relatedTarget.value]
94106
if (e.relatedTarget.value && data) {
95-
e.value = e.relatedTarget.value = '';
96-
this.createItemPanel({ ...data, display: "true" });
107+
e.value = e.relatedTarget.value = ""
108+
this.createItemPanel({ ...data, display: "true" })
97109
}
98-
});
99-
},
100-
},
101-
110+
})
111+
}
112+
}
102113

103-
SirTrevor.Block.prototype.availableMixins.push("autocompleteable");
104-
})(jQuery);
114+
SirTrevor.Block.prototype.availableMixins.push("autocompleteable")
115+
})()
Lines changed: 78 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,78 +1,109 @@
1-
(function ($){
1+
;(function () {
22
SirTrevor.BlockMixins.Formable = {
33
mixinName: "Formable",
44
preload: true,
55

6-
initializeFormable: function() {
7-
8-
if (this['afterLoadData'] === undefined) {
9-
this['afterLoadData'] = function(data) { };
6+
initializeFormable: function () {
7+
if (this["afterLoadData"] === undefined) {
8+
this["afterLoadData"] = function (data) {}
109
}
1110
},
1211

13-
formId: function(id) {
14-
return this.blockID + "_" + id;
12+
formId: function (id) {
13+
return this.blockID + "_" + id
1514
},
1615

17-
_serializeData: function() {
18-
19-
var data = $(":input,textarea,select", this.inner).not(':input:radio').serializeJSON();
20-
21-
$(':input:radio:checked', this.inner).each(function(index, input) {
22-
var key = $(input).data('key') || input.getAttribute('name');
23-
16+
_serializeData: function () {
17+
const data = {}
18+
const formElements = this.inner.querySelectorAll(
19+
":input,textarea,select:not(input[type=radio])"
20+
)
21+
22+
// Process regular form elements (except radio buttons)
23+
formElements.forEach(element => {
24+
if (element.name) {
25+
// Handle simple case
26+
data[element.name] = element.value
27+
}
28+
})
29+
30+
// Process checked radio buttons
31+
const checkedRadios = this.inner.querySelectorAll(
32+
"input[type=radio]:checked"
33+
)
34+
checkedRadios.forEach(radio => {
35+
const key = radio.dataset.key || radio.getAttribute("name")
2436
if (!key.match("\\[")) {
25-
data[key] = $(input).val();
37+
data[key] = radio.value
2638
}
27-
});
39+
})
2840

29-
/* Simple to start. Add conditions later */
41+
// Handle text blocks
3042
if (this.hasTextBlock()) {
31-
data.text = this.getTextBlockHTML();
32-
data.format = 'html';
33-
if (data.text && data.text.length > 0 && this.options.convertToMarkdown) {
34-
data.text = stToMarkdown(data.text, this.type);
35-
data.format = 'markdown';
43+
data.text = this.getTextBlockHTML()
44+
data.format = "html"
45+
if (
46+
data.text &&
47+
data.text.length > 0 &&
48+
this.options.convertToMarkdown
49+
) {
50+
data.text = stToMarkdown(data.text, this.type)
51+
data.format = "markdown"
3652
}
3753
}
3854

39-
return data;
55+
return data
4056
},
4157

42-
loadData: function(data){
58+
loadData: function (data) {
4359
if (this.hasTextBlock()) {
44-
if (data.text && data.text.length > 0 && this.options.convertFromMarkdown && data.format !== "html") {
45-
this.setTextBlockHTML(SirTrevor.toHTML(data.text, this.type));
60+
if (
61+
data.text &&
62+
data.text.length > 0 &&
63+
this.options.convertFromMarkdown &&
64+
data.format !== "html"
65+
) {
66+
this.setTextBlockHTML(SirTrevor.toHTML(data.text, this.type))
4667
} else {
47-
this.setTextBlockHTML(data.text);
68+
this.setTextBlockHTML(data.text)
4869
}
4970
}
50-
this.loadFormDataByKey(data);
51-
this.afterLoadData(data);
71+
this.loadFormDataByKey(data)
72+
this.afterLoadData(data)
5273
},
5374

54-
loadFormDataByKey: function(data) {
55-
$(':input', this.inner).not('button,:input[type=hidden]').each(function(index, input) {
56-
var key = $(input).data('key') || input.getAttribute('name');
75+
loadFormDataByKey: function (data) {
76+
const inputs = this.inner.querySelectorAll(
77+
":input:not(button):not([type=hidden])"
78+
)
5779

58-
if (key) {
80+
inputs.forEach(input => {
81+
const key = input.dataset.key || input.getAttribute("name")
5982

60-
if (key.match("\\[\\]$")) {
61-
key = key.replace("[]", "");
83+
if (key) {
84+
let processedKey = key
85+
if (processedKey.match("\\[\\]$")) {
86+
processedKey = processedKey.replace("[]", "")
6287
}
6388

64-
// by wrapping it in an array, this'll "just work" for radio and checkbox fields too
65-
var input_data = data[key];
66-
67-
if (!(input_data instanceof Array)) {
68-
input_data = [input_data];
89+
let inputData = data[processedKey]
90+
if (inputData !== undefined) {
91+
// Convert to array if not already
92+
if (!(inputData instanceof Array)) {
93+
inputData = [inputData]
94+
}
95+
96+
// Set value based on input type
97+
if (input.type === "checkbox" || input.type === "radio") {
98+
input.checked = inputData.includes(input.value)
99+
} else {
100+
input.value = inputData[0] !== undefined ? inputData[0] : ""
101+
}
69102
}
70-
$(this).val(input_data);
71103
}
72-
});
73-
},
74-
},
75-
104+
})
105+
}
106+
}
76107

77-
SirTrevor.Block.prototype.availableMixins.push("formable");
78-
})(jQuery);
108+
SirTrevor.Block.prototype.availableMixins.push("formable")
109+
})()
Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
1-
(function ($){
1+
;(function () {
22
SirTrevor.BlockMixins.Plustextable = {
33
mixinName: "Textable",
44
preload: true,
55

6-
initializeTextable: function() {
7-
if (this['formId'] === undefined) {
8-
this.withMixin(SirTrevor.BlockMixins.Formable);
6+
initializeTextable: function () {
7+
if (this["formId"] === undefined) {
8+
this.withMixin(SirTrevor.BlockMixins.Formable)
99
}
10-
11-
if (this['show_heading'] === undefined) {
12-
this.show_heading = true;
10+
11+
if (this["show_heading"] === undefined) {
12+
this.show_heading = true
1313
}
1414
},
15-
16-
align_key:"text-align",
17-
text_key:"item-text",
15+
16+
align_key: "text-align",
17+
text_key: "item-text",
1818
heading_key: "title",
19-
20-
text_area: function() {
19+
20+
text_area: function () {
2121
return `
2222
<div class="row">
2323
<div class="col-md-8">
@@ -40,19 +40,18 @@
4040
</div>
4141
</div>`
4242
},
43-
44-
heading: function() {
45-
if(this.show_heading) {
43+
44+
heading: function () {
45+
if (this.show_heading) {
4646
return `<div class="field">
4747
<label for="${this.formId(this.heading_key)}" class="col-form-label">${i18n.t("blocks:textable:heading")}</label>
4848
<input type="text" class="form-control" id="${this.formId(this.heading_key)}" name="${this.heading_key}" />
4949
</div>`
5050
} else {
51-
return "";
51+
return ""
5252
}
53-
},
54-
};
55-
53+
}
54+
}
5655

57-
SirTrevor.Block.prototype.availableMixins.push("plustextable");
58-
})(jQuery);
56+
SirTrevor.Block.prototype.availableMixins.push("plustextable")
57+
})()

0 commit comments

Comments
 (0)