I've implement a custom dropdown, that help to find users from data. Each item have a userpic, first name and last name. And my task is create a dropdown with settings like use picture or not. I coded it in create
function, in a loop with if
-statement: if (is_use_picture) { /* ... */ }
. It would be great if I could get some feedback on this code.
function Dropdown(dropdown, data, is_use_picture, is_multiselect) {
/**
* Reformat a data and create a dropdown.
*/
var formatted_data;
this.init = function() {
formatted_data = reformat(data);
var DROPDOWN_ITEMS_LENGTH = 10;
var result = new Array(DROPDOWN_ITEMS_LENGTH);
for (var i = 0; i < DROPDOWN_ITEMS_LENGTH; ++i) {
result[i] = data[i];
}
create(result, is_use_picture, is_multiselect);
};
/**
* @param {Array.<Object>} data.
* @return {Array.<Object>} result.
*/
var reformat = function(data) {
var len = response.items.length;
var result = new Array(len);
var first_name;
var last_name;
var domain;
for (var i = 0; i < len; ++i) {
first_name = response.items[i].first_name.toLowerCase();
last_name = response.items[i].last_name.toLowerCase();
domain = response.items[i].domain.toLowerCase();
result[i] = {
'item_info': response.items[i],
'first_name': first_name,
'last_name': last_name,
'domain': domain
};
}
return result;
};
/**
* Create and insert dropdown items.
* @param {Array.<Object>} data.
* @param {bool} is_use_picture.
*/
var dropdown_items;
var dropdown_items_length;
var create = function(data, is_use_picture) {
var item_node = document.createElement('div');
item_node.className = 'dropdown-item cf';
var text_node = document.createElement('span');
if (is_use_picture) {
var picture_node = document.createElement('span');
picture_node.className = 'dropdown-item-picture';
}
var len = data.length;
var docfrag = document.createDocumentFragment();
var i = 0;
while (i < len) {
var item = item_node.cloneNode(true);
item.setAttribute('data-index', i);
item.setAttribute('data-id', data[i].id);
item.addEventListener('click', select);
if (is_use_picture) {
var picture = picture_node.cloneNode(true);
picture.style.backgroundImage = 'url(' + data[i].photo_50 + ')';
item.appendChild(picture);
}
var text = text_node.cloneNode(true);
text.className = 'dropdown-item-text';
text.textContent = data[i].first_name + ' ' + data[i].last_name;
item.appendChild(text);
docfrag.appendChild(item);
i++;
}
dropdown_items_length = i;
clean();
dropdown_content.appendChild(docfrag);
dropdown_items = dropdown.querySelectorAll('.dropdown-item');
};
/**
* Open/close a dropdown.
*/
var dropdown_content = dropdown.querySelector('.dropdown-content');
var is_open;
var open = function() {
dropdown_content.classList.remove('hidden');
is_open = true;
};
var close = function() {
dropdown_content.className += ' hidden';
is_open = false;
};
document.addEventListener('keydown', function(event) {
event = event || window.event;
if (is_open && event.keyCode === 27) {
close();
}
}, false);
document.addEventListener('click', function(event) {
event = event || window.event;
if (is_open && event.keyCode == 0) {
var element = event.target;
while (element !== document) {
if (element.className === 'dropdown') {
return;
}
element = element.parentNode;
}
close();
}
}, false);
/**
*
*/
var clean = function() {
while (dropdown_content.hasChildNodes()) {
dropdown_content.removeChild(dropdown_content.firstChild);
}
};
/**
* Navigation by dropdown.
*/
var UP_KEY_CODE = 38;
var DOWN_KEY_CODE = 40;
var SCROLL_STEP = 66;
var keydown_count = -1;
var hover = function(event) {
event = event || window.event;
if (event.keyCode === UP_KEY_CODE || event.keyCode === DOWN_KEY_CODE) {
if (event.keyCode === UP_KEY_CODE) {
keydown_count--;
if (keydown_count < 0) {
keydown_count = dropdown_items_length - 1;
dropdown_content.scrollTop = SCROLL_STEP * dropdown_items_length;
}
if (keydown_count < (dropdown_items_length - 3)) {
dropdown_content.scrollTop -= SCROLL_STEP;
}
} else if (event.keyCode === DOWN_KEY_CODE) {
keydown_count++;
if (keydown_count >= dropdown_items_length) {
keydown_count = 0;
dropdown_content.scrollTop = 0;
}
if (keydown_count > 2) {
dropdown_content.scrollTop += SCROLL_STEP;
}
}
for (var i = 0; i < dropdown_items_length; ++i) {
dropdown_items[i].classList.remove('dropdown-item--hover');
}
dropdown_items[keydown_count].className += ' dropdown-item--hover';
}
};
/**
*
*/
var select = function() {
if (!is_multiselect) {
close();
}
dropdown_input.value = '';
return this.getAttribute('data-id');
};
/**
*
*/
var dropdown_input = dropdown.querySelector('.dropdown-input');
dropdown_input.addEventListener('keydown', hover, false);
var dropdown_input_wrap = dropdown.querySelector('.dropdown-input-wrap');
dropdown_input_wrap.addEventListener('click', open, false);
}
I use this code to init dropdown:
var dropdown = new Dropdown(document.getElementById('dropdown'), response.items, true, false);
dropdown.init();
init()
function. I updated my question. \$\endgroup\$