Skip to content

Commit

Permalink
Remove jQuery from LinkDialog
Browse files Browse the repository at this point in the history
remove the usage of jQuery in LinkDialog and replace it with vanilla Javascript. Also restructure smaller parts of the class to improve the overview.
  • Loading branch information
sascha-karnatz committed Mar 22, 2024
1 parent 9d65218 commit 601bab5
Showing 1 changed file with 73 additions and 59 deletions.
132 changes: 73 additions & 59 deletions app/javascript/alchemy_admin/link_dialog.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,7 @@ export class LinkDialog extends Alchemy.Dialog {
replace(data) {
// let Dialog class handle the content replacement
super.replace(data)
// Store some jQuery objects for further reference
this.$internal_link = $("#internal_link", this.dialog_body)
this.$element_anchor = $("#element_anchor", this.dialog_body)
this.linkForm = document.querySelector('[data-link-form-type="internal"]')

// attach events we handle
this.attachEvents()
this.#attachEvents()
}

/**
Expand All @@ -45,74 +39,94 @@ export class LinkDialog extends Alchemy.Dialog {
* @returns {Promise<unknown>}
*/
open() {
super.open(...arguments)
super.open()
return new Promise((resolve) => (this.resolve = resolve))
}

updatePage(page) {
this.$internal_link.val(page != null ? page.url_path : undefined)(
(this.linkForm.querySelector("alchemy-anchor-select").page =
page != null ? page.id : undefined)
)
}

// Attaches click events to forms in the link dialog.
attachEvents() {
/**
* Attaches click events to forms in the link dialog.
*/
#attachEvents() {
// enable the dom selection in internal link tab
this.linkForm.addEventListener("Alchemy.PageSelect.ItemRemoved", (e) =>
this.updatePage()
const internalForm = document.querySelector(
'[data-link-form-type="internal"]'
)
this.linkForm.addEventListener("Alchemy.PageSelect.ItemAdded", (e) =>
this.updatePage(e.detail)
internalForm.addEventListener("Alchemy.PageSelect.ItemRemoved", (e) =>
this.#updatePage()
)
internalForm.addEventListener("Alchemy.PageSelect.ItemAdded", (e) =>
this.#updatePage(e.detail)
)

$("[data-link-form-type]", this.dialog_body).on("submit", (e) => {
e.preventDefault()
this.link_type = e.target.dataset.linkFormType
// get url and remove a possible hash fragment
let url = $(`#${this.link_type}_link`).val().replace(/#\w+$/, "")
if (this.link_type === "internal" && this.$element_anchor.val() !== "") {
url += "#" + this.$element_anchor.val()
}

// Create the link
this.createLink({
url,
title: $(`#${this.link_type}_link_title`).val(),
target: $(`#${this.link_type}_link_target`).val()
document.querySelectorAll("[data-link-form-type]").forEach((form) => {
form.addEventListener("submit", (e) => {
e.preventDefault()
this.#submitForm(e.target.dataset.linkFormType)
})
})
}

// Creates a link if no validation errors are present.
// Otherwise shows an error notice.
createLink(options) {
if (
this.link_type === "external" &&
!options.url.match(Alchemy.link_url_regexp)
) {
this.showValidationError()
} else {
this.setLink(options)
this.close()
}
/**
* update page select and set anchor select
* @param page
*/
#updatePage(page = null) {
document.getElementById("internal_link").value =
page != null ? page.url_path : undefined

document.querySelector(
'[data-link-form-type="internal"] alchemy-anchor-select'
).page = page != null ? page.id : undefined
}

// Sets the link either in TinyMCE or on an Ingredient.
setLink(options) {
this.resolve({
url: options.url.trim(),
title: options.title,
target: options.target,
type: this.link_type
/**
* submit the form itself
* @param linkType
*/
#submitForm(linkType) {
// get url and remove a possible hash fragment
let url = document
.getElementById(`${linkType}_link`)
.value.replace(/#\w+$/, "")

const elementAnchor = document.getElementById("element_anchor")
if (linkType === "internal" && elementAnchor.value !== "") {
url += "#" + elementAnchor.value
}

// Create the link
this.#createLink({
url: url.trim(),
title: document.getElementById(`${linkType}_link_title`).value,
target: document.getElementById(`${linkType}_link_target`)?.value,
type: linkType
})
}

// Shows validation errors
showValidationError() {
$("#errors ul", this.dialog_body).html(
/**
* Creates a link if no validation errors are present.
* Otherwise shows an error notice.
* @param options
*/
#createLink(options) {
const invalidInput =
options.type === "external" && !options.url.match(Alchemy.link_url_regexp)

if (invalidInput) {
this.#showValidationError()
} else {
this.resolve(options)
this.close()
}
}

/**
* Shows validation errors
*/
#showValidationError() {
const errors = document.getElementById("errors")
errors.querySelector("ul").innerHTML =
`<li>${Alchemy.t("url_validation_failed")}</li>`
)
return $("#errors", this.dialog_body).show()
errors.style.display = "block"
}
}

0 comments on commit 601bab5

Please sign in to comment.