Create New Item
Item Type
File
Folder
Item Name
Search file in folder and subfolders...
Are you sure want to rename?
Downloads
/
vfm-admin
/
admin-panel
/
plugins
/
tagin
:
tagin.js
Voltar
Back Up
Advanced Editor
Save
/*! * Tagin v2.0.2 (https://tagin.netlify.app/) * Copyright 2020-2021 Erwin Heldy G * Licensed under MIT (https://github.com/erwinheldy/tagin/blob/master/LICENSE) */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Tagin = factory()); })(this, (function () { 'use strict'; class Tagin { classElement = 'tagin'; classWrapper = 'tagin-wrapper'; classTag = 'tagin-tag'; classRemove = 'tagin-tag-remove'; classInput = 'tagin-input'; classInputHidden = 'tagin-input-hidden'; target; wrapper; input; separator; placeholder; duplicate; transform; enter; constructor(inputElement, options) { this.target = inputElement; this.separator = options?.separator || inputElement.dataset.taginSeparator || ','; this.placeholder = options?.placeholder || inputElement.dataset.taginPlaceholder || ''; this.duplicate = options?.duplicate || inputElement.dataset.taginDuplicate !== undefined; this.transform = options?.transform || inputElement.dataset.taginTransform || 'input => input'; this.enter = options?.enter || inputElement.dataset.taginEnter !== undefined; this.createWrapper(); this.autowidth(); this.addEventListener(); } createWrapper() { const tags = this.getValue() === '' ? '' : this.getValues().map(val => this.createTag(val)).join(''); const input = document.createElement('input'); input.type = 'text'; input.className = this.classInput; input.placeholder = this.placeholder; const wrapper = document.createElement('div'); wrapper.className = `${this.classWrapper} ${this.target.className}`; wrapper.classList.remove(this.classElement); wrapper.insertAdjacentHTML('afterbegin', tags); wrapper.insertAdjacentElement('beforeend', input); this.target.insertAdjacentElement('afterend', wrapper); // insert wrapper after input this.wrapper = wrapper; this.input = input; } createTag(value) { const onclick = `this.closest('div').dispatchEvent(new CustomEvent('tagin:remove', { detail: this }))`; return `<span class="${this.classTag}">${value}<span onclick="${onclick}" class="${this.classRemove}"></span></span>`; } getValue() { return this.target.value.trim(); } getValues() { return this.getValue().split(this.separator); } getTags() { return Array.from(this.wrapper.getElementsByClassName(this.classTag)).map(tag => tag.textContent); } getTag() { return this.getTags().join(this.separator); } updateValue() { this.target.value = this.getTag(); this.target.dispatchEvent(new Event('change')); } autowidth() { const fakeEl = document.createElement('div'); fakeEl.classList.add(this.classInput, this.classInputHidden); const string = this.input.value || this.input.placeholder || ''; fakeEl.innerHTML = string.replace(/ /g, ' '); document.body.appendChild(fakeEl); this.input.style.setProperty('width', Math.ceil(parseInt(window.getComputedStyle(fakeEl).width.replace('px', ''))) + 1 + 'px'); fakeEl.remove(); } addEventListener() { const wrapper = this.wrapper; const input = this.input; // Focus to input wrapper.addEventListener('click', () => input.focus()); // Toggle focus class input.addEventListener('focus', () => wrapper.classList.add('focus')); input.addEventListener('blur', () => wrapper.classList.remove('focus')); // Add tag when input input.addEventListener('input', () => { this.appendTag(); this.autowidth(); }); // Add tag when blur input.addEventListener('blur', () => { this.appendTag(true); this.autowidth(); }); input.addEventListener('keydown', (e) => { // Remove with backspace if (input.value === '' && e.key === 'Backspace' && wrapper.getElementsByClassName(this.classTag).length) { wrapper.querySelector(`.${this.classTag}:last-of-type`).remove(); this.updateValue(); } // Add with Enter if (input.value !== '' && e.key === 'Enter' && this.enter) { this.appendTag(true); this.autowidth(); e.preventDefault(); } }); wrapper.addEventListener('tagin:remove', (e) => { if (e['detail'] instanceof HTMLSpanElement) { e['detail'].parentElement.remove(); this.updateValue(); } }); this.target.addEventListener('change', () => this.updateTag()); } appendTag(force = false) { const input = this.input; const value = eval(this.transform)(input.value.trim()); if (value === '') input.value = ''; if (input.value.includes(this.separator) || (force && input.value !== '')) { value .split(this.separator) .filter((i) => i !== '') .forEach((val) => { if (this.getTags().includes(val) && this.duplicate === false) { this.alertExist(val); } else { input.insertAdjacentHTML('beforebegin', this.createTag(val)); this.updateValue(); } }); input.value = ''; input.removeAttribute('style'); } } alertExist(value) { for (const el of this.wrapper.getElementsByClassName(this.classTag)) { if (el.textContent === value && el instanceof HTMLSpanElement) { el.style.transform = 'scale(1.09)'; setTimeout(() => { el.removeAttribute('style'); }, 150); } } } updateTag() { if (this.getValue() !== this.getTag()) { [...this.wrapper.getElementsByClassName(this.classTag)].map(tag => tag.remove()); this.getValue().trim() !== '' && this.input.insertAdjacentHTML('beforebegin', this.getValues().map(val => this.createTag(val)).join('')); } } addTag(tag) { this.input.value = (Array.isArray(tag) ? tag.join(this.separator) : tag) + this.separator; this.input.dispatchEvent(new Event('input')); } } return Tagin; }));