Skip to content

Instantly share code, notes, and snippets.

@laphilosophia
Created December 9, 2020 15:03
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 laphilosophia/e215c32a617a6a4dd261c83292d97ac7 to your computer and use it in GitHub Desktop.
Save laphilosophia/e215c32a617a6a4dd261c83292d97ac7 to your computer and use it in GitHub Desktop.
Typescript spinner sample
export default class Spinner {
#elements: NodeListOf<HTMLElement> = document.querySelectorAll('[data-zm-spinner]')
#config: {
title: string,
max: number,
min: number,
} = {
title: 'ADET',
max: 10,
min: 1,
}
#classnames: {
element: string,
title: string,
wrapper: string,
minus: string,
plus: string,
input: string,
} = {
element: 'zm-spinner',
title: 'zm-spinner__title',
wrapper: 'zm-spinner__wrapper',
minus: 'zm-spinner__button zm-spinner__button--minus',
plus: 'zm-spinner__button zm-spinner__button--plus',
input: 'zm-spinner__input',
}
private setConfigs (element: HTMLElement) {
const attr = element.dataset.zmSpinner
this.#config = JSON.parse(attr!)
}
private async createLayout (element: HTMLElement) {
const title = document.createElement('p')
const wrapper = document.createElement('div')
const input = document.createElement('input')
const minus = document.createElement('button')
const plus = document.createElement('button')
const inputAttrs: {
[keys: string]: any
} = {
type: 'text',
class: this.#classnames.input,
name: this.#classnames.element,
value: this.#config.min,
disabled: true,
readonly: true
}
element.className = this.#classnames.element
title.className = this.#classnames.title
wrapper.className = this.#classnames.wrapper
minus.className = this.#classnames.minus
plus.className = this.#classnames.plus
title.insertAdjacentText('afterbegin', this.#config.title)
minus.insertAdjacentText('afterbegin', '-')
plus.insertAdjacentText('afterbegin', '+')
for (let key in inputAttrs) {
if (inputAttrs.hasOwnProperty(key)) {
input.setAttribute(key, inputAttrs[key])
}
}
wrapper?.append(minus)
wrapper?.append(input)
wrapper?.append(plus)
element?.append(title)
element?.append(wrapper)
element.removeAttribute('data-zm-spinner')
}
private increaseHandler (input: Element | null, settings: { max: number }) {
if (!input) return;
if ((input as any).value < settings?.max) {
let value = parseInt((input as any).value, 10)
value = isNaN(value) ? 0 : value
value++
(input as any).value = String(value)
}
}
private decreaseHandler (input: Element | null, settings: { min: number }) {
if ((input as any).value > settings?.min) {
let value = parseInt((input as any).value, 10)
value = isNaN(value) ? 0 : value
value--
(input as any).value = String(value)
}
}
private checkValues (
input: any,
button: {
setAttribute: (arg0: string, arg1: string) => void;
removeAttribute: (arg0: string) => void
} | null,
compare: any) {
if ((input as any)?.value == compare) {
button?.setAttribute('disabled', 'true')
} else {
button?.removeAttribute('disabled')
}
}
private async bind (element: HTMLElement) {
await this.createLayout(element);
const minus = element.querySelector('.zm-spinner__button--minus')
const plus = element.querySelector('.zm-spinner__button--plus')
const input = element.querySelector('.zm-spinner__input')
plus ? plus.addEventListener('click', () => {
this.increaseHandler(input, this.#config);
this.checkValues(input, plus, this.#config.max)
this.checkValues(input, minus, this.#config.min)
}, false) : null
minus ? minus.addEventListener('click', () => {
this.decreaseHandler(input, this.#config);
this.checkValues(input, plus, this.#config.max)
this.checkValues(input, minus, this.#config.min)
}, false) : null
this.checkValues(input, plus, this.#config.max)
this.checkValues(input, minus, this.#config.min)
}
public async mount () {
for await (const element of this.#elements) {
this.setConfigs(element)
this.bind(element)
}
}
}
@laphilosophia
Copy link
Author

<!-- usage -->
<div data-zm-spinner='{"title": "ADET", "max": 10, "min": 1}'></div>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment