diff --git a/public/custom/multiselectcomponent/multiselectcomponent.html b/public/custom/multiselectcomponent/multiselectcomponent.html
new file mode 100644
index 00000000..c49e3bff
--- /dev/null
+++ b/public/custom/multiselectcomponent/multiselectcomponent.html
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/public/custom/multiselectcomponent/multiselectcomponent.js b/public/custom/multiselectcomponent/multiselectcomponent.js
new file mode 100644
index 00000000..65bdd36b
--- /dev/null
+++ b/public/custom/multiselectcomponent/multiselectcomponent.js
@@ -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 = '';
+ }
+
+ /**
+ * This method creates an item list item that works as visual representation of selected values.
+ */
+ function createItemListItem (value) {
+ return html = ''+itemString(getDataItem(value))+
+ ' x'+
+ ''+
+ '';
+ }
+
+ /**
+ * Returns a requested data item that matches (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
+ };
+}
\ No newline at end of file