@carry0987/check-box
Advanced tools
Comparing version 1.0.0 to 1.0.1
@@ -1,336 +0,1 @@ | ||
(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.CheckBox = factory()); | ||
})(this, (function () { 'use strict'; | ||
let reportInfo = function(vars, showType = false) { | ||
if (showType === true) { | ||
console.log('Data Type : ' + typeof vars, '\nValue : ' + vars); | ||
} else if(typeof showType !== 'boolean') { | ||
console.log(showType); | ||
} else { | ||
console.log(vars); | ||
} | ||
}; | ||
/* Util */ | ||
const Util = { | ||
getElem(ele, mode, parent) { | ||
if (typeof ele === 'object') { | ||
return ele; | ||
} else if (mode === undefined && parent === undefined) { | ||
return (isNaN(ele * 1)) ? document.querySelector(ele) : document.getElementById(ele); | ||
} else if (mode === 'all' || mode === null) { | ||
return (parent === undefined) ? document.querySelectorAll(ele) : parent.querySelectorAll(ele); | ||
} else if (typeof mode === 'object' && parent === undefined) { | ||
return mode.querySelector(ele); | ||
} | ||
}, | ||
isObject(item) { | ||
return item && typeof item === 'object' && !Array.isArray(item); | ||
}, | ||
deepMerge(target, ...sources) { | ||
const source = sources.shift(); | ||
if (!source) return target; | ||
if (Util.isObject(target) && Util.isObject(source)) { | ||
for (const key in source) { | ||
if (Util.isObject(source[key])) { | ||
if (!target[key]) Object.assign(target, { [key]: {} }); | ||
Util.deepMerge(target[key], source[key]); | ||
} else { | ||
Object.assign(target, { [key]: source[key] }); | ||
} | ||
} | ||
} | ||
return Util.deepMerge(target, ...sources); | ||
}, | ||
createEvent(name) { | ||
let evt; | ||
if (!window.CustomEvent || typeof window.CustomEvent !== 'function') { | ||
evt = document.createEvent('CustomEvent'); | ||
evt.initCustomEvent(name, false, false, undefined); | ||
} else { | ||
evt = new CustomEvent(name); | ||
} | ||
return evt; | ||
}, | ||
removeItem(array, what) { | ||
let a = arguments, L = a.length, ax; | ||
while (L && array.length) { | ||
what = a[--L]; | ||
while ((ax = array.indexOf(what)) !== -1) { | ||
array.splice(ax, 1); | ||
} | ||
} | ||
return array; | ||
}, | ||
injectStylesheet(stylesObject, id) { | ||
let style = document.createElement('style'); | ||
style.id = 'checkbox-style' + id; | ||
style.appendChild(document.createTextNode('')); | ||
document.head.appendChild(style); | ||
let stylesheet = document.styleSheets[document.styleSheets.length - 1]; | ||
for (let selector in stylesObject) { | ||
if (stylesObject.hasOwnProperty(selector)) { | ||
Util.compatInsertRule(stylesheet, selector, Util.buildRules(stylesObject[selector]), id); | ||
} | ||
} | ||
}, | ||
buildRules(ruleObject) { | ||
let ruleSet = ''; | ||
for (let [property, value] of Object.entries(ruleObject)) { | ||
ruleSet += `${property}:${value};`; | ||
} | ||
return ruleSet; | ||
}, | ||
compatInsertRule(stylesheet, selector, cssText, id) { | ||
let modifiedSelector = selector.replace('.check-box', '.check-box-' + id); | ||
stylesheet.insertRule(modifiedSelector + '{' + cssText + '}', 0); | ||
}, | ||
removeStylesheet(id) { | ||
let styleElement = Util.getElem('#checkbox-style' + id); | ||
if (styleElement) { | ||
styleElement.parentNode.removeChild(styleElement); | ||
} | ||
}, | ||
createUniqueID(length = 8) { | ||
return Math.random().toString(36).substring(2, 2 + length); | ||
}, | ||
getTemplate(id) { | ||
let template = ` | ||
<div class="checkbox check-box-${id}"> | ||
<label class="checkbox-label"></label> | ||
</div> | ||
`; | ||
return template; | ||
}, | ||
isEmpty(str) { | ||
return (!str?.length); | ||
}, | ||
toggleCheckAll(ele, total) { | ||
let checkAll = Util.getElem(ele); | ||
if (!checkAll) return; | ||
if (total && total.checked && total.row) { | ||
checkAll.checked = (total.checked !== total.row || total.checked === 0) ? false : true; | ||
checkAll.setAttribute('checked', checkAll.checked ? 'checked' : null); | ||
} else { | ||
checkAll.checked = false; | ||
checkAll.removeAttribute('checked'); | ||
} | ||
} | ||
}; | ||
let throwError = function(msg) { | ||
throw new Error(msg); | ||
}; | ||
class CheckBox { | ||
constructor(elements, option = {}) { | ||
this.init(elements, option, CheckBox.instance.length); | ||
CheckBox.instance.push(this); | ||
if (CheckBox.instance.length === 1) reportInfo('CheckBox is loaded, version:' + CheckBox.version); | ||
} | ||
static destroyAll() { | ||
CheckBox.instance.forEach((instance) => { | ||
instance.destroy(); | ||
}); | ||
CheckBox.instance = []; | ||
} | ||
init(elements, option, id) { | ||
let elem = Util.getElem(elements, 'all'); | ||
if (!elem || elem.length < 1) throwError('Cannot find elements : ' + elements); | ||
this.id = id; | ||
this.element = elements; | ||
this.allElement = []; // Store all elements here which will be used in destroy method | ||
this.option = Util.deepMerge({}, CheckBox.defaultOption, option); | ||
this.total = { | ||
checked: [], | ||
list: [], | ||
input: [], | ||
row: 0 | ||
}; | ||
// Inject stylesheet | ||
if (this.option?.styles && Object.keys(this.option.styles).length > 0) { | ||
let styles = Util.deepMerge({}, this.option.styles); | ||
Util.injectStylesheet(styles, this.id); | ||
} | ||
// Handle onChange event | ||
Util.toggleCheckAll(this.option.checkAll, this.total); | ||
this.onChange = (total) => {if (this.option?.onChange) this.option.onChange(total);}; | ||
// Handle checkbox | ||
elem.forEach((ele, index) => { | ||
if (ele.type !== 'checkbox') return; | ||
if (ele.hasAttribute('data-checkbox')) return; | ||
ele.setAttribute('data-checkbox', 'true'); | ||
// Handle checkbox title | ||
let labelSibling = ele.nextElementSibling; | ||
let title = ele?.title || ele?.dataset?.checkboxTitle; | ||
let bindLabel = this.option.bindLabel; | ||
let ramainLabel = false, | ||
randomID = null; | ||
if (labelSibling && labelSibling.tagName === 'LABEL') { | ||
title = (() => { // using IIFE | ||
if (!Util.isEmpty(ele.id)) { | ||
if (labelSibling.htmlFor === ele.id) { | ||
bindLabel = ramainLabel = true; | ||
return true; | ||
} | ||
if (labelSibling.dataset?.checkboxFor === ele.id) { | ||
return true; | ||
} | ||
} | ||
if (ele.dataset?.checkboxId && labelSibling.dataset?.checkboxFor === ele.dataset?.checkboxId) { | ||
randomID = Util.isEmpty(ele.id) && Util.isEmpty(labelSibling.htmlFor) ? 'check-' + Util.createUniqueID(6) : null; | ||
return true; | ||
} | ||
return null; | ||
})(); | ||
if (title === true) { | ||
title = labelSibling.textContent; | ||
labelSibling.parentNode.removeChild(labelSibling); | ||
} | ||
} | ||
// Handle checkbox checked status | ||
if (ele.checked) { | ||
ele.setAttribute('checked', 'checked'); | ||
} else { | ||
if (this.option?.checked) { | ||
if (typeof this.option.checked === 'boolean' && elem.length === 1) { | ||
ele.checked = true; | ||
ele.setAttribute('checked', 'checked'); | ||
} | ||
if ((ele?.value === this.option.checked) || (index === this.option.checked)) { | ||
ele.checked = true; | ||
ele.setAttribute('checked', 'checked'); | ||
} | ||
if (typeof this.option.checked === 'string') { | ||
this.option.checked = [this.option.checked]; | ||
} | ||
if (Array.isArray(this.option.checked)) { | ||
if (this.option.checked.includes(ele.name) || this.option.checked.includes(ele.id)) { | ||
ele.checked = true; | ||
ele.setAttribute('checked', 'checked'); | ||
} | ||
} | ||
} | ||
} | ||
// Insert checkbox | ||
let template = Util.getTemplate(this.id); | ||
let templateNode = document.createElement('div'); | ||
templateNode.innerHTML = template.trim(); | ||
let labelNode = Util.getElem('label', templateNode); | ||
let cloneEle = ele.cloneNode(true); | ||
if (randomID) { | ||
cloneEle.removeAttribute('data-checkbox-id'); | ||
cloneEle.id = randomID; | ||
labelNode.htmlFor = randomID; | ||
} | ||
if (ramainLabel === true) { | ||
labelNode.htmlFor = cloneEle.id; | ||
} | ||
labelNode.parentNode.insertBefore(cloneEle, labelNode); | ||
ele.parentNode.replaceChild(templateNode.firstElementChild, ele); | ||
// Insert checkbox title | ||
if (title === null) { | ||
labelNode.parentNode.removeChild(labelNode); | ||
} else { | ||
labelNode.textContent = title; | ||
if (bindLabel) { | ||
labelNode.classList.add('checkbox-labeled'); | ||
labelNode.addEventListener('click', (e) => { | ||
e.preventDefault(); | ||
cloneEle.click(); | ||
}); | ||
} | ||
} | ||
// Add event listener | ||
cloneEle.addEventListener('change', (e) => { | ||
this.checkBoxChange(); | ||
}); | ||
this.allElement.push(cloneEle); // Store each checkbox element | ||
}); | ||
//Handle checkAll checkbox | ||
if (this.option?.checkAll) { | ||
const checkAll = Util.getElem(this.option.checkAll); | ||
if (checkAll && this.allElement.length) { | ||
checkAll.addEventListener('change', (e) => { | ||
const checked = e.target.checked; | ||
this.allElement.forEach((ele) => { | ||
ele.checked = checked; | ||
checked ? ele.setAttribute('checked', 'checked') : ele.removeAttribute('checked'); | ||
}); | ||
this.checkBoxChange(); | ||
}); | ||
} | ||
} | ||
return this; | ||
} | ||
checkBoxChange() { | ||
const total = this.total; | ||
let selector = this.element + ' input[type=checkbox]:checked'; | ||
total.checked = Array.from(Util.getElem(selector, 'all')); | ||
total.list = []; | ||
total.input = []; | ||
total.checked.forEach((checkbox) => { | ||
total.list.push(checkbox.value); | ||
total.input.push(checkbox); | ||
}); | ||
total.checked = total.checked.length; | ||
selector = this.element + ' input[type=checkbox]'; | ||
total.row = Util.getElem(selector, 'all').length; | ||
Util.toggleCheckAll(this.option.checkAll, total); | ||
this.onChange(total); | ||
const event = Util.createEvent('checkbox-change'); | ||
event.total = total; | ||
document.dispatchEvent(event); | ||
} | ||
getCheckBox() { | ||
return this.total; | ||
} | ||
refresh() { | ||
this.init(this.element, this.option); | ||
} | ||
destroy() { | ||
//Remove event listeners from all elements | ||
this.allElement.forEach(element => { | ||
element.removeEventListener('change', this.checkBoxChange); | ||
element.removeEventListener('change', this.onChange); | ||
element.removeEventListener('change', this.option.onChange); | ||
}); | ||
Util.removeStylesheet(this.id); | ||
CheckBox.instance.splice(this.id, 1); | ||
return this; | ||
} | ||
} | ||
CheckBox.version = '1.0.0'; | ||
CheckBox.instance = []; | ||
CheckBox.defaultOption = { | ||
checkAll: null, // Selector of the checkbox which is used to check all checkboxes | ||
onChange: null, | ||
onCheckAll: null, | ||
bindLabel: true, | ||
styles: {} | ||
}; | ||
return CheckBox; | ||
})); | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).CheckBox=t()}(this,(function(){"use strict";const e={getElem:(e,t,n)=>"object"==typeof e?e:void 0===t&&void 0===n?isNaN(1*e)?document.querySelector(e):document.getElementById(e):"all"===t||null===t?void 0===n?document.querySelectorAll(e):n.querySelectorAll(e):"object"==typeof t&&void 0===n?t.querySelector(e):void 0,isObject:e=>e&&"object"==typeof e&&!Array.isArray(e),deepMerge(t,...n){const i=n.shift();if(!i)return t;if(e.isObject(t)&&e.isObject(i))for(const n in i)e.isObject(i[n])?(t[n]||Object.assign(t,{[n]:{}}),e.deepMerge(t[n],i[n])):Object.assign(t,{[n]:i[n]});return e.deepMerge(t,...n)},createEvent(e){let t;return window.CustomEvent&&"function"==typeof window.CustomEvent?t=new CustomEvent(e):(t=document.createEvent("CustomEvent"),t.initCustomEvent(e,!1,!1,void 0)),t},injectStylesheet(t,n){let i=document.createElement("style");i.id="checkbox-style"+n,i.appendChild(document.createTextNode("")),document.head.appendChild(i);let o=document.styleSheets[document.styleSheets.length-1];for(let i in t)t.hasOwnProperty(i)&&e.compatInsertRule(o,i,e.buildRules(t[i]),n)},buildRules(e){let t="";for(let[n,i]of Object.entries(e))t+=`${n}:${i};`;return t},compatInsertRule(e,t,n,i){let o=t.replace(".check-box",".check-box-"+i);e.insertRule(o+"{"+n+"}",0)},removeStylesheet(t){let n=e.getElem("#checkbox-style"+t);n&&n.parentNode.removeChild(n)},createUniqueID:(e=8)=>Math.random().toString(36).substring(2,2+e),getTemplate:e=>`\n <div class="checkbox check-box-${e}">\n <label class="checkbox-label"></label>\n </div>\n `,isEmpty:e=>!e?.length,handleCheckboxTitle(t,n){let i=!1,o=null,l=t?.title||t?.dataset?.checkboxTitle;return n&&"LABEL"===n.tagName&&(l=(()=>{if(!e.isEmpty(t.id)){if(n?.htmlFor===t.id)return i=!0,!0;if(n?.dataset?.checkboxFor===t.id)return!0}return t?.dataset?.checkboxId&&n?.dataset?.checkboxFor===t?.dataset?.checkboxId?(o=e.isEmpty(t.id)&&e.isEmpty(n.htmlFor)?"check-"+e.createUniqueID(6):null,!0):null})()),[l,i,o]},insertCheckbox(t,n,i,o){let l=e.getTemplate(t),c=document.createElement("div");c.innerHTML=l.trim();let h=e.getElem("label",c),s=n.cloneNode(!0);return i&&(s.removeAttribute("data-checkbox-id"),s.id=i),!0===o&&(h.htmlFor=s.id),h.parentNode.insertBefore(s,h),[s,c,h]},insertCheckboxTitle(e,t,n,i){null===e?n.parentNode.removeChild(n):(n.textContent=e,!0===t&&(n.classList.add("checkbox-labeled"),n.addEventListener("click",(e=>{e.preventDefault(),i.click()}))))},toggleCheckStatus(e,t){t?(e.checked=!0,e.setAttribute("checked","checked")):(e.checked=!1,e.removeAttribute("checked"))},toggleCheckAll(t,n){let i=e.getElem(t);i&&(n&&n.checked&&n.input?e.toggleCheckStatus(i,!1==(n.checked.length!==n.input.length||0===n.checked.length)):e.toggleCheckStatus(i,!1))}};class t{constructor(e,n={}){this.init(e,n,t.instance.length),t.instance.push(this),1===t.instance.length&&function(e,t=!1){!0===t?console.log("Data Type : "+typeof e,"\nValue : "+e):"boolean"!=typeof t?console.log(t):console.log(e)}("CheckBox is loaded, version:"+t.version)}static destroyAll(){t.instance.forEach((e=>{e.destroy()})),t.instance=[]}init(n,i,o){let l=e.getElem(n,"all");if((!l||l.length<1)&&function(e){throw new Error(e)}("Cannot find elements : "+n),this.id=o,this.element=n,this.allElement=[],this.option=e.deepMerge({},t.defaultOption,i),this.total={checked:[],list:[],input:[]},this.option?.styles&&Object.keys(this.option.styles).length>0){let t=e.deepMerge({},this.option.styles);e.injectStylesheet(t,this.id)}if(this.onChange=e=>{this.option?.onChange&&this.option.onChange(e)},l.forEach(((t,n)=>{if("checkbox"!==t.type)return;if(t.hasAttribute("data-checkbox"))return;t.setAttribute("data-checkbox","true");let i=t.nextElementSibling,o=this.option.bindLabel,[c,h,s]=e.handleCheckboxTitle(t,i);o=!0===h||o,!0===c&&(c=i.textContent,i.parentNode.removeChild(i)),t.checked?e.toggleCheckStatus(t,!0):this.option?.checked&&("boolean"==typeof this.option.checked&&1===l.length&&e.toggleCheckStatus(t,!0),t?.value!==this.option.checked&&n!==this.option.checked||e.toggleCheckStatus(t,!0),"string"==typeof this.option.checked&&(this.option.checked=[this.option.checked]),Array.isArray(this.option.checked)&&(this.option.checked.includes(t.name)||this.option.checked.includes(t.id))&&e.toggleCheckStatus(t,!0));let[r,a,d]=e.insertCheckbox(this.id,t,s,h);t.parentNode.replaceChild(a.firstElementChild,t),e.insertCheckboxTitle(c,o,d,r);let u=this.checkBoxChange.bind(this);r.addEventListener("change",u),r.checkBoxChange=u,this.allElement.push(r)})),this.option?.checkAll){const t=e.getElem(this.option.checkAll);if(t&&"checkbox"===t?.type){let n=t.nextElementSibling,i=this.option?.bindLabel,[o,l,c]=e.handleCheckboxTitle(t,n);i=!0===l||i,!0===o&&(o=n.textContent,n.parentNode.removeChild(n));let[h,s,r]=e.insertCheckbox(this.id,t,c,l);t.parentNode.replaceChild(s.firstElementChild,t),e.insertCheckboxTitle(o,i,r,h);let a=(t=>{const n=t.target.checked;this.allElement.forEach((t=>{e.toggleCheckStatus(t,n)})),this.checkBoxChange(!1),this.option?.onCheckAll&&n&&this.option.onCheckAll(n)}).bind(this);h.addEventListener("change",a),h.checkAllChange=a,this.checkAll=h}}return this}checkBoxChange(t=!0){const n=this.total;n.list=[],n.input=[],n.checked=[],this.allElement.forEach((e=>{n.input.push(e),e.checked&&(n.list.push(e.value),n.checked.push(e))})),t&&e.toggleCheckAll(this.option.checkAll,n),this.onChange(n);const i=e.createEvent("checkbox-change");i.total=n,document.dispatchEvent(i)}getCheckBox(){return this.total}refresh(){this.init(this.element,this.option)}destroy(){return this.allElement.forEach((e=>{e.removeEventListener("change",e.checkBoxChange)})),this.checkAll&&this.checkAll.removeEventListener("change",this.checkAll.checkAllChange),this.allElement=[],this.total={},e.removeStylesheet(this.id),t.instance.splice(this.id,1),this}}return t.version="1.0.1",t.instance=[],t.defaultOption={checkAll:null,onChange:null,onCheckAll:null,bindLabel:!0,styles:{}},t})); |
{ | ||
"name": "@carry0987/check-box", | ||
"version": "1.0.0", | ||
"version": "1.0.1", | ||
"description": "A library for create and manage checkbox elements", | ||
@@ -5,0 +5,0 @@ "type": "module", |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
9834
24
1