multiselect component
This commit is contained in:
@@ -0,0 +1,121 @@
|
||||
|
||||
/**
|
||||
* 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
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user