Last active
January 29, 2024 05:40
-
-
Save aalfiann/c03284330015ec7f3b5336a2c224a7a7 to your computer and use it in GitHub Desktop.
Select with checkbox pure javascript
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"use strict"; | |
/** | |
* Getmedik Select with Checkbox | |
* | |
* Note: | |
* Example required config | |
* | |
* { | |
* "element": "", | |
* "name": "", | |
* "placeholder": "-- Select --", | |
* "replaceholder": false, | |
* "data": [{"value": "", "text": "", "checked": false}] | |
* } | |
*/ | |
class GMSelectBox { | |
constructor (option) { | |
this._show = true; | |
this.placeholder = '-- Select --'; | |
this.replaceholder = false; | |
this.data = []; | |
if(typeof option === 'object' && option.constructor === Object){ | |
for(var key in option) { | |
if(option.hasOwnProperty(key)) { | |
this[key] = option[key]; | |
} | |
} | |
this._render(); | |
document.addEventListener('click', this._clickHandler); | |
} else { | |
throw new Error('Option must be an object type!'); | |
} | |
} | |
_render() { | |
var list = this.data; | |
var name = this.name; | |
var _listText = []; | |
for(var i=0; i<list.length; i++) { | |
if(list[i].checked) { | |
_listText.push(list[i].text); | |
} | |
} | |
if(this.replaceholder) { | |
if(_listText.length > 0) { | |
_listText = _listText.join(', '); | |
} else { | |
_listText = this.placeholder; | |
} | |
} else { | |
_listText = this.placeholder; | |
} | |
var dom = `<div id="section_${name}" class="gm-multipleSelection"> | |
<div class="gm-selectBox ${name}_parent" id="select_${name}"> | |
<select class="form-control"> | |
<option id="${name}_select" data-replace="${this.replaceholder}" data-placeholder="${this.placeholder}">${_listText}</option> | |
</select> | |
<div class="gm-overSelect"></div> | |
</div> | |
<div class="gm-checkBoxes" id="${name}"> | |
${list.map(function(item, index) { | |
return `<label class="${name}_label" for="${name}_item_${(index+1)}"> | |
<input type="checkbox" id="${name}_item_${(index+1)}" name="${name}_item_${(index+1)}" value="${item.value}" ${(item.checked?'checked':'')}/> | |
<span class="gm-textBoxes">${item.text.substring(0, 34)}</span> | |
</label>`; | |
}).join('')} | |
</div> | |
</div>`; | |
document.getElementById(this.element).innerHTML = dom; | |
} | |
get(_parseInt) { | |
_parseInt = (_parseInt===undefined?false:_parseInt); | |
var result = []; | |
var labels = document.getElementById(this.name).getElementsByTagName('label'); | |
for(var i=0; i<labels.length; i++) { | |
if(labels[i].getElementsByTagName('input')[0].checked === true) { | |
result.push(labels[i].getElementsByTagName('input')[0].value); | |
} | |
} | |
if(_parseInt) { | |
result = result.map(function (x) { | |
return parseInt(x, 10); | |
}); | |
} | |
return result; | |
} | |
set(arr) { | |
var labels = document.getElementById(this.name).getElementsByTagName('label'); | |
for(var i=0; i<labels.length; i++) { | |
for(var j=0; j<arr.length; j++) { | |
if(labels[i].getElementsByTagName('input')[0].value === arr[j].toString()) { | |
labels[i].getElementsByTagName('input')[0].checked = true; | |
} | |
} | |
} | |
// refresh | |
var selector = this.name+'_select'; | |
if(document.getElementById(selector).getAttribute('data-replace') === 'true') { | |
var result = []; | |
for(var i=0; i<labels.length; i++) { | |
if(labels[i].getElementsByTagName('input')[0].checked === true) { | |
result.push(labels[i].getElementsByTagName('span')[0].textContent.substring(0, 34)); | |
} | |
} | |
if(result.length > 0) { | |
result = result.join(', '); | |
} else { | |
result = document.getElementById(selector).getAttribute('data-placeholder'); | |
} | |
document.getElementById(selector).innerHTML = result; | |
} | |
} | |
clear() { | |
var labels = document.getElementById(this.name).getElementsByTagName('label'); | |
for(var i=0; i<labels.length; i++) { | |
labels[i].getElementsByTagName('input')[0].checked = false; | |
} | |
// refresh | |
var selector = this.name+'_select'; | |
if(document.getElementById(selector).getAttribute('data-replace') === 'true') { | |
var result = document.getElementById(selector).getAttribute('data-placeholder'); | |
document.getElementById(selector).innerHTML = result; | |
} | |
} | |
_clickHandler(event) { | |
if (event.target.parentNode.parentNode && event.target.parentNode.parentNode.children[1]) { | |
var name = event.target.parentNode.parentNode.children[1].id; | |
if(name) { | |
var checkboxes = document.getElementById(name); | |
if(this._show === undefined) { | |
this._show = true; | |
} | |
if(checkboxes) { | |
if (this._show) { | |
checkboxes.style.display = "block"; | |
this._show = false; | |
} else { | |
checkboxes.style.display = "none"; | |
this._show = true; | |
} | |
} | |
} | |
var itemCheck = event.target.parentNode.getAttribute('class'); | |
if(itemCheck && itemCheck.indexOf('_label') !== -1) { | |
var selector = itemCheck.split('_')[0]+'_select'; | |
if(event.target.value) { | |
var result = []; | |
var data = []; | |
var labels = document.getElementById(itemCheck.split('_')[0]).getElementsByTagName('label'); | |
for(var i=0; i<labels.length; i++) { | |
if(labels[i].getElementsByTagName('input')[0].checked === true) { | |
result.push(labels[i].getElementsByTagName('span')[0].textContent.substring(0, 34)); | |
data.push(labels[i].getElementsByTagName('input')[0].value); | |
} | |
} | |
const eventAwesome = new CustomEvent('gmselectbox:change', { | |
bubbles: true, | |
detail: { | |
name: itemCheck.split('_')[0], | |
data: data | |
} | |
}); | |
event.target.dispatchEvent(eventAwesome); | |
if(document.getElementById(selector).getAttribute('data-replace') === 'true') { | |
if(result.length > 0) { | |
result = result.join(', '); | |
} else { | |
result = document.getElementById(selector).getAttribute('data-placeholder'); | |
} | |
document.getElementById(selector).innerHTML = result; | |
} | |
} | |
} | |
} | |
} | |
} | |
document.head.innerHTML += `<style> | |
.gm-multipleSelection { | |
min-width: 150px; | |
max-width: 300px; | |
background-color: #FFF; | |
} | |
.gm-selectBox { | |
position: relative; | |
} | |
.gm-selectBox select { | |
width: 100%; | |
font-weight: bold; | |
} | |
.gm-overSelect { | |
position: absolute; | |
left: 0; | |
right: 0; | |
top: 0; | |
bottom: 0; | |
border: 1px #C0C8D7 solid; | |
border-radius: 5px 5px 5px 5px; | |
} | |
.gm-checkBoxes { | |
display: none; | |
border: 1px #C0C8D7 solid; | |
max-height: 200px; | |
overflow-y: auto; | |
background-color: white; | |
min-width: 150px; | |
max-width: 300px; | |
width: 100%; | |
position: relative; | |
z-index: 3; | |
} | |
.gm-checkBoxes label { | |
display: flex; | |
justify-content: flex-start; | |
align-items: center; | |
} | |
.gm-checkBoxes label:hover { | |
background-color: #EEFCFA; | |
} | |
.gm-checkBoxes label input[type="checkbox"]:checked { | |
background: #24B59D; | |
color: black; | |
} | |
.gm-checkBoxes label input[type="checkbox"] { | |
cursor: pointer; | |
-webkit-appearance: none; | |
-moz-appearance: none; | |
appearance: none; | |
outline: 0; | |
background: white; | |
height: 16px; | |
width: 16px; | |
border: 1px solid #C0C8D7; | |
color: white; | |
} | |
.gm-checkBoxes label input[type="checkbox"]:after { | |
content: ' '; | |
position: relative; | |
left: 40%; | |
top: 20%; | |
width: 15%; | |
height: 40%; | |
border: solid #fff; | |
border-width: 0 2px 2px 0; | |
transform: rotate(50deg); | |
display: none; | |
} | |
.gm-checkBoxes label input[type="checkbox"]:checked:after { | |
display: block; | |
} | |
.gm-textBoxes { | |
position: relative; | |
font-family: 'Nunito Sans'; | |
font-size: 14px; | |
font-weight: 400; | |
height: 100%; | |
display: block; | |
width: 100%; | |
padding: 10px 0px 10px 10px; | |
} | |
</style>`; | |
// ===================== | |
// EXAMPLE HOW TO USE | |
// ===================== | |
var gmselect = new GMSelectBox({ | |
element: 'filter_test', | |
name: 'checkBoxes1', | |
placeholder: '-- Choose --', | |
replaceholder: true, | |
data: [ | |
{ | |
value: 1, | |
text: 'Tester 1' | |
}, | |
{ | |
value: 2, | |
text: 'Tester 2' | |
}, | |
{ | |
value: 3, | |
text: 'Tester 3' | |
}, | |
{ | |
value: 4, | |
text: 'Tester 4', | |
checked: true | |
}, | |
{ | |
value: 5, | |
text: 'Tester 5', | |
checked: true | |
} | |
] | |
}); | |
var gmselect2 = new GMSelectBox({ | |
element: 'filter_without_replaceholder', | |
name: 'checkBoxes2', | |
placeholder: '-- Choose --', | |
data: [ | |
{ | |
value: 7, | |
text: 'Tester 7' | |
}, | |
{ | |
value: 8, | |
text: 'Tester 8' | |
}, | |
{ | |
value: 9, | |
text: 'Tester 9' | |
}, | |
{ | |
value: 10, | |
text: 'Tester 10' | |
} | |
] | |
}); | |
// LISTENER | |
document.addEventListener('gmselectbox:change', function (event) { | |
console.log(event.detail); | |
}); |
Fixed with this CSS
.gm-checkBoxes label {
display: flex;
justify-content: flex-start;
align-items: center;
}
.gm-checkBoxes label input[type="checkbox"] {
cursor: pointer;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
outline: 0;
background: white;
height: 16px;
width: 16px;
border: 1px solid #C0C8D7;
color: white;
}
.gm-textBoxes {
position: relative;
font-family: 'Nunito Sans';
font-size: 14px;
font-weight: 400;
height: 100%;
display: block;
width: 100%;
padding: 10px 0px 10px 10px;
}
Thanks @pae0112
Got it fixed.
Here is the new updated example >> https://jsfiddle.net/aalfiann/ufL1zbst/25/
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Example on https://jsfiddle.net/aalfiann/ufL1zbst/21/