Skip to content

Instantly share code, notes, and snippets.

@robacarp
Created May 25, 2022 16:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save robacarp/2345c0c5410c2941e8bb28ca525a6de0 to your computer and use it in GitHub Desktop.
Save robacarp/2345c0c5410c2941e8bb28ca525a6de0 to your computer and use it in GitHub Desktop.
export default class Builder {
static tag(name, text) {
const tag = document.createElement(name)
tag.textContent = text
return tag
}
static link(href, text) {
const link = Builder.tag("a", text)
link.href = href
return link
}
static option(text, value = null) {
if (value == null)
value = text
const option = Builder.tag("option",text)
option.value = value
return option
}
static img(image) {
const tag = document.createElement('img')
tag.src = image.url
tag.dataset.imageId = image.id
return tag
}
static form(method, action) {
const tag = Builder.tag('form')
tag.method = method
tag.action = action
return tag
}
static input(type, name, value) {
const tag = document.createElement('input')
tag.type = type
tag.name = name
tag.value = value
return tag
}
}
import Builder from './builder.js'
class Confirm {
constructor(link) {
this.link = link
link.addEventListener('click', this.click)
}
click = evt => {
const response = window.confirm(this.link.dataset.confirm)
if (response !== true) {
evt.stopImmediatePropagation()
evt.preventDefault()
}
}
}
class MethodOverride {
constructor(link) {
this.link = link
link.addEventListener('click', this.click)
}
click = evt => {
evt.preventDefault()
const form = Builder.form('post', this.link.href)
const submit = Builder.input('submit')
form.appendChild(Builder.input('hidden', '_method', this.link.dataset.method))
form.appendChild(submit)
if (! UJS.isCrossDomain(this.link.href))
form.appendChild(Builder.input('hidden', UJS.csrfParam, UJS.csrfToken))
form.target = this.link.target
form.style.display = 'none'
document.body.appendChild(form)
submit.click()
}
}
export default class UJS {
static start () {
document.querySelectorAll('[data-confirm]').forEach(link => new Confirm(link))
document.querySelectorAll('[data-method]').forEach(link => new MethodOverride(link))
this.updateFormCsrfTokens()
}
static updateFormCsrfTokens () {
const token = this.csrfToken
document.querySelectorAll(`input[name="${this.csrfParam}"]`).forEach(input => input.value = token)
}
static get csrfToken () {
const meta = document.querySelector('meta[name=csrf-token]')
return meta.content
}
static get csrfParam () {
const meta = document.querySelector('meta[name=csrf-param]')
return meta.content
}
static isCrossDomain (url) {
const baseUrl = new URL(location.href)
const candidateUrl = new URL(url)
return baseUrl.host != candidateUrl.host
|| baseUrl.protocol != candidateUrl.protocol
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment