Skip to content

Instantly share code, notes, and snippets.

@abiriadev
Created November 25, 2021 03:24
Show Gist options
  • Save abiriadev/58e3575db229b14e73370f25904386dc to your computer and use it in GitHub Desktop.
Save abiriadev/58e3575db229b14e73370f25904386dc to your computer and use it in GitHub Desktop.
refactored vote site
class LocalStorageHook {
#key
#getHook
#setHook
#data
constructor(
key,
{
getHook = _ => _,
setHook = _ => _,
initHook
}
) {
this.#key = key.toString()
this.#getHook = getHook
this.#setHook = setHook
this.#data = (initHook ?? setHook)(localStorage.getItem(this.#key))
}
get() { return this.#getHook(this.#data) }
set(data) {
this.#data = data.toString()
localStorage.setItem(
this.#key,
this.#setHook(this.#data)
)
return this
}
}
export class App {
#increment
#btns
#isVoted
#results
static #listenerF(
isVoted,
{
preHook = _ => _,
postHook = _ => _
}
) {
return function (ev) {
preHook(ev)
this
.#results
.map(syn => syn.set(
parseInt(syn.get()) +
(
isVoted ?
this.#increment :
-this.#increment
),
),
)
this.#isVoted.set(isVoted)
postHook(ev)
}
}
constructor({
btns,
results,
options: {
defaultResultValue,
increment = 1
},
}) {
this.#results = [...Object.entries(results)].map(
([key, el]) =>
new LocalStorageHook(key, {
setHook: data =>
(el.innerHTML = data ?? defaultResultValue),
}),
)
this.#increment = increment
this.#btns = btns
this.#btns.voteBtn.addEventListener(
'click',
App.#listenerF(true, {
preHook: _ => (
alert(
'청원 동의 철회 및 댓글 수정은 불가능하오니 신중하게 참여해주시기 바랍니다',
),
alert('잠시만 기다려 주세요\n곧 참여인원이 올라갑니다.')
),
}).bind(this),
)
this.#btns.cancelBtn.addEventListener(
'click',
App.#listenerF(false, {
postHook: _ => alert('Canceled! :)'),
}).bind(this),
)
this.#isVoted = new LocalStorageHook('isVoted', {
setHook: data =>
data && data === 'true'
? (
this
.#btns
.voteBtn
.setAttribute('disabled', 'disabled'),
this
.#btns
.cancelBtn
.removeAttribute('disabled'),
data
)
: (
this
.#btns
.voteBtn
.removeAttribute('disabled'),
this
.#btns
.cancelBtn
.setAttribute('disabled', 'disabled'),
data
),
})
}
isVoted() { return this.#isVoted.get() }
}
<!--
this is an example HTML file that describes how to run the above code
-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Simple Petition site</title>
<script type="module">
import { App } from './app.js'
new App({
btns: {
voteBtn: document.getElementById('agbtn'),
cancelBtn: document.getElementById('cancelbtn'),
},
results: {
rel1: document.getElementById('result1'),
rel2: document.getElementById('result2'),
},
options: { defaultResultValue: 23 },
})
</script>
</head>
<body>
<output id="result1">Loading...</output>
<output id="result2">Loading...</output>
<form>
<input type="button" value="I agree" id="agbtn" />
<input type="button" value="cancel" id="cancelbtn" disabled />
</form>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment