121 lines
4.7 KiB
JavaScript
121 lines
4.7 KiB
JavaScript
|
|
/**
|
|
* Multi-select component
|
|
*
|
|
* @param identifier Identifier parameter that makes each instance unique and is used in DOM datasets used by this component.
|
|
* @param data Data (array of objects)
|
|
* @param field Field parameter that will be send as list with form
|
|
* @param itemString String that should be shown as selector in select and a item label in item list
|
|
*/
|
|
function MultiSelectComponent(identifier, data, field, itemString) {
|
|
|
|
// Private variables
|
|
var selectBox, addButton, itemHolder;
|
|
|
|
/**
|
|
* This is the method that generates template for multiselect component.
|
|
* This method is easily rewriteable into PHP.
|
|
* It is necessary to keep html datasets with prefix data-ms- intact for the javascript component to work.
|
|
* ECMAScript 5 version, does not need any compilers, nor jQuery or other framework.
|
|
* This method is not required to stay inside the MultiSelectComponent and may be rendered in any way;
|
|
*
|
|
* identifier is inherited from the instance creation.
|
|
* data is inherited from the instance creation.
|
|
* field is inherited from the instance creation.
|
|
* itemString is inherited from the instance creation.
|
|
*
|
|
*/
|
|
function createTemplate () {
|
|
var html = '<select data-ms-select="'+identifier+'">';
|
|
|
|
for(var idx in data) {
|
|
if(data.hasOwnProperty(idx)) {
|
|
html += '<option value="'+data[idx][field]+'">'+itemString(data[idx])+'</value>' //createSelectOption(data[idx]);
|
|
}
|
|
}
|
|
|
|
return html += '</select><input type="button" data-ms-add="'+identifier+'" value="add"><div data-ms-list="'+identifier+'"></div>';
|
|
}
|
|
|
|
/**
|
|
* This method creates an item list item that works as visual representation of selected values.
|
|
*/
|
|
function createItemListItem (value) {
|
|
return html = '<span>'+itemString(getDataItem(value))+
|
|
' <span data-ms-remove="'+identifier+'" data-ms-value="'+value+'">x</span>'+
|
|
'<input style="display: none" type="checkbox" value="'+value+'" name="'+identifier+'[]" checked>'+
|
|
'</span>';
|
|
}
|
|
|
|
/**
|
|
* Returns a requested data item that matches <field> (class instance variable field) value of passed value.
|
|
*/
|
|
function getDataItem (value) {
|
|
for(var idx in data) {
|
|
if(data.hasOwnProperty(idx)){
|
|
if(data[idx][field] == value){
|
|
return data[idx];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* By selecting an item, that item is removed from list of available items and is added to list of selected items.
|
|
* If no more items are available for adding, add button and selectbox are disabled and list gets an informative item.
|
|
*/
|
|
function selectItem (value) {
|
|
selectBox.removeChild(selectBox.querySelector('option[value="' + value + '"]'));
|
|
itemHolder.innerHTML += createItemListItem(value);
|
|
|
|
if(selectBox.children.length === 0) {
|
|
selectBox.options.add(new Option('no more items to add', 0));
|
|
addButton.setAttribute('disabled', 'disabled');
|
|
selectBox.setAttribute('disabled', 'disabled');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* By deselecting (removing) an item, that item is removed from selected list and added again into select box of available items;
|
|
* If add button was disabled (mostly because of no selectable items in list) it and the selectbox are now re-enabled and informative item is removed.
|
|
*/
|
|
function deselectItem (element) {
|
|
var id = element.getAttribute('data-ms-value');
|
|
selectBox.options.add(new Option(itemString(getDataItem(id)), id));
|
|
itemHolder.removeChild(element.parentNode);
|
|
|
|
if(addButton.getAttribute('disabled')) {
|
|
selectBox.options.remove(0);
|
|
addButton.removeAttribute('disabled');
|
|
selectBox.removeAttribute('disabled');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Initializes javascript part of the component.
|
|
*/
|
|
function init () {
|
|
// Cached elements only for JS to be a little more optimized.
|
|
selectBox = document.querySelector('[data-ms-select="'+identifier+'"]');
|
|
addButton = document.querySelector('[data-ms-add="'+identifier+'"]');
|
|
itemHolder = document.querySelector('[data-ms-list="'+identifier+'"]');
|
|
|
|
// Add button
|
|
addButton.addEventListener('click', function() {
|
|
selectItem(selectBox.value);
|
|
});
|
|
|
|
// Remove item button
|
|
itemHolder.addEventListener('click', function(e) {
|
|
if(e.target.getAttribute('data-ms-remove')) {
|
|
deselectItem(e.target);
|
|
}
|
|
})
|
|
}
|
|
|
|
// Publicly exposed static methods and variables.
|
|
return {
|
|
init: init,
|
|
createTemplate: createTemplate
|
|
};
|
|
} |