Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Some refactoring and updation to get multiple data from multiple inputs #2

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion css/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@
border-left: .3em solid transparent;
}
.multi__inner {
width: 180px;
overflow: hidden;
}
.multi__dropdown {
Expand Down
261 changes: 134 additions & 127 deletions js/multiselect.js
Original file line number Diff line number Diff line change
@@ -1,152 +1,159 @@
let multi = [];
let input = [];
const updateContainer = (container, inner, selected, opt) => {
if (selected.length > 0) {
container.value = selected.join(',');
inner.innerText = selected.join(', ');
} else {
container.value = '';
inner.innerText = opt[0].innerText;
}
container.dispatchEvent(new window.Event('change', { bubbles: true }));
if (selected.length > 0) {
container.value = selected.join(',');
inner.innerText = selected.join(', ');
} else {
container.value = '';
inner.innerText = opt[0].innerText;
}
container.dispatchEvent(new window.Event('change', {bubbles: true}));
};
const buttonToggle = (display, dropdown) => {
display.classList.toggle('multi__dropdown--toggle');
dropdown.classList.toggle('multi--hidden');
display.classList.toggle('multi__dropdown--toggle');
dropdown.classList.toggle('multi--hidden');
};
const map = {};
const value = {};
let multi_idx = 0;
const multiSelect = () => {
Array.from(document.querySelectorAll('.multi'))
.filter((multi) => {
return multi.getAttribute('data-multiselect-initialized') === null;
})
.forEach((el) => {
// stores values of dropdown
map[multi_idx] = [];
// array of options
const { options: opt } = el;
// create container
const container = document.createElement('div');
// carry over classes
el.classList.forEach((className) => {
container.classList.add(className);
});
Array.from(document.querySelectorAll('.multi'))
.filter((multi) => {
return multi.getAttribute('data-multiselect-initialized') === null;
})
.forEach((el) => {
if ($(el).attr('multiple') != undefined) {
multi[multi_idx] = true;
} else {
multi[multi_idx] = false;
}
// stores values of dropdown
map[multi_idx] = [];
value[multi_idx] = [];
// array of options
const {options: opt} = el;
// create container
const container = document.createElement('div');
// carry over classes
el.classList.forEach((className) => {
container.classList.add(className);
});

// Add data-multiselect-initialized attribute
container.setAttribute('data-multiselect-initialized', true);
container.setAttribute('key', multi_idx);
const key = multi_idx;
// carry over ids if exist
// container.id = el.id;
el.id ? (container.id = el.id) : '';
// carry over names
el.getAttribute('name')
? container.setAttribute('name', el.getAttribute('name'))
: '';
el.getAttribute('onchange')
? container.setAttribute('onchange', el.getAttribute('onchange'))
: '';
// container.setAttribute('name', el.getAttribute('name') || '');
// container.classList.add('multi')
// Add data-multiselect-initialized attribute
container.setAttribute('data-multiselect-initialized', true);
container.setAttribute('key', multi_idx);
const key = multi_idx;
// carry over ids if exist
// container.id = el.id;
el.id ? (container.id = el.id) : '';
// carry over names
el.getAttribute('name')
? container.setAttribute('name', el.getAttribute('name'))
: '';
el.getAttribute('onchange')
? container.setAttribute('onchange', el.getAttribute('onchange'))
: '';

// create display
const display = document.createElement('button');
display.classList.add('multi__display');
// create display
const display = document.createElement('button');
display.classList.add('multi__display');
display.type = 'button';

// create inner (displays the values)
const inner = document.createElement('div');
inner.classList.add('multi__inner');
// create inner (displays the values)
const inner = document.createElement('div');
inner.classList.add('multi__inner');

// set innerText to default value
// display.innerText = opt[0].innerText
inner.innerText = opt[0].innerText;
display.value = '';
// append display to container
container.appendChild(display);
display.appendChild(inner);
// set innerText to default value
inner.innerText = opt[0].innerText;
display.value = '';
// append display to container
container.appendChild(display);
display.appendChild(inner);

// replace new select element with new container
el.parentNode.replaceChild(container, el);

// create dropdown
const dropdown = document.createElement('div');
dropdown.classList.add('multi__dropdown');
// create ul
const list = document.createElement('ul');
dropdown.classList.add('multi--hidden');
// iterate over options, skip first (placeholder)
for (let i = 1; i < opt.length; i++) {
const li = document.createElement('li');
li.classList.add('multi__li-item');
// ACCESSIBILITY
// const a = document.createElement('a');
// a.classList.add('item-anchor');
// a.setAttribute('role','option');
// a.setAttribute('tabindex','0');
// a.innerText=opt[i].innerText
li.innerText = opt[i].innerText;
li.addEventListener('click', (e) => {
e.stopPropagation();
if (map[key].includes(e.target.innerText)) {
map[key].splice(map[key].indexOf(e.target.innerText), 1);
e.target.classList.remove('multi__li-item--selected');
} else {
map[key].push(e.target.innerText);
e.target.classList.add('multi__li-item--selected');
}
// e.target.parentElement.removeChild(e.target);
updateContainer(container, inner, map[key], opt);
// replace new select element with new container
el.parentNode.replaceChild(container, el);
// Update 1.0.1 input field
input[key] = document.createElement('input');
input[key].type = "hidden";
input[key].name = $(el).attr('name');
// create dropdown
const dropdown = document.createElement('div');
dropdown.classList.add('multi__dropdown');
// create ul
const list = document.createElement('ul');
dropdown.classList.add('multi--hidden');
// iterate over options, skip first (placeholder)
for (let i = 1; i < opt.length; i++) {
const li = document.createElement('li');
li.classList.add('multi__li-item');
// ACCESSIBILITY
li.innerText = opt[i].innerText;
// Edit by DonatasP
li.setAttribute('data-id', opt[i].value);
if (opt[i].selected) {
$(li).addClass('multi__li-item--selected');
}
$(li).on('click', function(e) {
e.stopPropagation();
$(li).trigger('selected-'+key);
// Edited here
let id = $(this).attr('data-id');
if ($(this).hasClass('multi__li-item--selected')) {
map[key].splice(map[key].indexOf(e.target.innerText), 1);
value[key].splice(value[key].indexOf(id), 1);
$(this).removeClass('multi__li-item--selected');
} else {
if (multi[key] == false) {
map[key] = [];
value[key] = [];
$('.multi__li-item--selected').removeClass('multi__li-item--selected');
}
map[key].push(e.target.innerText);
value[key].push(id);
$(this).addClass('multi__li-item--selected');
if (multi[key] == false) {
container.click();
}
}
input[key].value = value[key];
updateContainer(container, inner, map[key], opt);
});
// li.appendChild(a);
list.appendChild(li);
container.appendChild(input[key]);
}
// add event listener to container to show / hide dropdown
container.addEventListener('click', (e) => {
e.stopPropagation();
buttonToggle(display, dropdown);
});
// append dropdown to container
container.appendChild(dropdown);
// append ul to dropdown
dropdown.appendChild(list);
multi_idx++;
});
// li.appendChild(a);
list.appendChild(li);
}
// add event listener to container to show / hide dropdown
container.addEventListener('click', (e) => {
e.stopPropagation();
buttonToggle(display, dropdown);
// display.classList.toggle('multi__dropdown--toggle');
// dropdown.classList.toggle('multi--hidden');
});
// append dropdown to container
container.appendChild(dropdown);
// append ul to dropdown
dropdown.appendChild(list);
});
// }
multi_idx++;
};
// add event listener to window
document.addEventListener('click', (e) => {
document.querySelectorAll('.multi__display').forEach((display) => {
display.classList.remove('multi__dropdown--toggle');
});
document.querySelectorAll('.multi__display').forEach((display) => {
display.classList.remove('multi__dropdown--toggle');
});

document.querySelectorAll('.multi__dropdown').forEach((dropdown) => {
dropdown.classList.add('multi--hidden');
});
document.querySelectorAll('.multi__dropdown').forEach((dropdown) => {
dropdown.classList.add('multi--hidden');
});
});
// // https://stackoverflow.com/questions/799981/document-ready-equivalent-without-jquery
document.addEventListener('DOMContentLoaded', function (event) {
//do work
multiSelect();
//do work
multiSelect();
});

// Refresh Method
window.multiSelect = {
refresh() {
multiSelect();
},
// addMulti() {
// const root = document.querySelector('#root');
// const select = document.createElement('select');
// select.classList.add('multi');
// const option = document.createElement('option');
// option.selected = true;
// option.disabled = true;
// option.innerHTML="Default"
// select.appendChild(option);
// const option_two = document.createElement('option');
// option_two.innerHTML="Banana";
// select.appendChild(option_two);
// root.appendChild(select);
// }
refresh() {
multiSelect();
},
};