Skip to content

Instantly share code, notes, and snippets.

@aalfiann
Last active January 29, 2024 05:40
Show Gist options
  • Save aalfiann/c03284330015ec7f3b5336a2c224a7a7 to your computer and use it in GitHub Desktop.
Save aalfiann/c03284330015ec7f3b5336a2c224a7a7 to your computer and use it in GitHub Desktop.
Select with checkbox pure javascript
"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);
});
@aalfiann
Copy link
Author

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