From 6fa779e4a3440bd9bf842838ef8b4588c487a9d8 Mon Sep 17 00:00:00 2001
From: Piotr Gawron <piotr.gawron@uni.lu>
Date: Wed, 4 Apr 2018 17:11:24 +0200
Subject: [PATCH] annotators and annotation types selected via tickboxes

---
 frontend-js/package-lock.json                 |  15 +-
 frontend-js/package.json                      |   5 +-
 .../js/gui/admin/ChooseAnnotatorsDialog.js    | 209 +++++++++---------
 .../js/gui/admin/ChooseValidatorsDialog.js    | 167 +++++++-------
 4 files changed, 195 insertions(+), 201 deletions(-)

diff --git a/frontend-js/package-lock.json b/frontend-js/package-lock.json
index 29898ad842..693e8cf2b7 100644
--- a/frontend-js/package-lock.json
+++ b/frontend-js/package-lock.json
@@ -11,9 +11,9 @@
       "dev": true
     },
     "@types/react": {
-      "version": "15.6.14",
-      "resolved": "https://registry.npmjs.org/@types/react/-/react-15.6.14.tgz",
-      "integrity": "sha512-k6YJBmHfzkCtk3iT6aN2hclkPYL2fxlSc3dW//G2kENlmMJ/V+pKhqsHdJJeVluIi1bA296cCLLGATLm7WXToQ==",
+      "version": "15.6.15",
+      "resolved": "https://registry.npmjs.org/@types/react/-/react-15.6.15.tgz",
+      "integrity": "sha512-LOHbyeKRNYLEotniN3DlRGrpXorXupvFSbKrNzc9dZ87uL+IJDbGYVerxKaG1jbnhuc7RhEWxlNmUVtYm3mtNg==",
       "dev": true
     },
     "@types/react-dom": {
@@ -22,7 +22,7 @@
       "integrity": "sha512-XGLjgNtPnBuO1cITYWZAk4KbH0UEDqMg2kuG3xx0UgnrcSd6ijO57Fp9rimmrDKcBnx3b2vFQuEYRXu2GihRYQ==",
       "dev": true,
       "requires": {
-        "@types/react": "15.6.14"
+        "@types/react": "15.6.15"
       }
     },
     "JSONStream": {
@@ -2054,7 +2054,7 @@
       "version": "github:dsehnal/LiteMol#a5419c696faa84530dd93acd55b747cf8136902b",
       "dev": true,
       "requires": {
-        "@types/react": "15.6.14",
+        "@types/react": "15.6.15",
         "@types/react-dom": "15.5.7"
       }
     },
@@ -2389,6 +2389,11 @@
       "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
       "dev": true
     },
+    "multi-checkbox-list": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/multi-checkbox-list/-/multi-checkbox-list-0.2.0.tgz",
+      "integrity": "sha512-b1HVb8XqCNtC2OAu2AVgs/eaNnMS9Zudv61Nsi3OR9527P5c5IfwGbCzgLyBHiT0pHeL7Kpk6V+6bQYM8sYaTg=="
+    },
     "nave": {
       "version": "0.5.3",
       "resolved": "https://registry.npmjs.org/nave/-/nave-0.5.3.tgz",
diff --git a/frontend-js/package.json b/frontend-js/package.json
index feff0ba36e..a6345728a8 100644
--- a/frontend-js/package.json
+++ b/frontend-js/package.json
@@ -4,7 +4,7 @@
   "description": "frontentd for minerva google maps interface",
   "main": "minerva.js",
   "scripts": {
-    "build:css": "cleancss --skip-rebase -o dist/minerva.css node_modules/dual-listbox/dist/*.css src/main/css/*.css",
+    "build:css": "cleancss --skip-rebase -o dist/minerva.css node_modules/dual-listbox/dist/*.css node_modules/multi-checkbox-list/dist/*.css src/main/css/*.css",
     "build:js": "browserify --debug --standalone minerva src/main/js/minerva.js | exorcist dist/minerva.js.map > dist/minerva.js ",
     "//": "rm -rf dist & rmdir /q /s dist & mkdir dist & browserify --debug --standalone minerva src/main/js/minerva.js | exorcist dist/minerva.js.map > dist/minerva.js & uglifyjs --compress --mangle --in-source-map dist/minerva.js.map --source-map-include-sources --source-map dist/minerva.min.js.map -o dist/minerva.min.js dist/minerva.js",
     "build-deploy": "npm run build && npm run deploy",
@@ -17,6 +17,7 @@
   },
   "author": "Piotr Gawron",
   "devDependencies": {
+    "MolStar": "git://github.com/davidhoksza/MolStar.git",
     "assert": "1.4.1",
     "bluebird": "^3.4.6",
     "bootstrap": "^3.3.7",
@@ -36,7 +37,6 @@
     "log4js-memory-appender": "1.0.5",
     "mkdirp": "^0.5.1",
     "mocha": "^3.5.3",
-    "MolStar": "git://github.com/davidhoksza/MolStar.git",
     "uglifyjs": "^2.4.10"
   },
   "dependencies": {
@@ -49,6 +49,7 @@
     "jstree": "^3.3.4",
     "jszip": "^3.1.4",
     "log4js": "0.6.38",
+    "multi-checkbox-list": "^0.2.0",
     "pileup": "^0.6.8",
     "request": "^2.82.0",
     "spectrum-colorpicker": "^1.8.0",
diff --git a/frontend-js/src/main/js/gui/admin/ChooseAnnotatorsDialog.js b/frontend-js/src/main/js/gui/admin/ChooseAnnotatorsDialog.js
index 9b06fb9151..87d2c6ae79 100644
--- a/frontend-js/src/main/js/gui/admin/ChooseAnnotatorsDialog.js
+++ b/frontend-js/src/main/js/gui/admin/ChooseAnnotatorsDialog.js
@@ -3,11 +3,11 @@
 /* exported logger */
 
 var AbstractGuiElement = require('../AbstractGuiElement');
-var DualListbox = require('dual-listbox').DualListbox;
 var GuiConnector = require("../../GuiConnector");
+var MultiCheckboxList = require("multi-checkbox-list");
 var UserPreferences = require("../../map/data/UserPreferences");
 
-var InvalidArgumentError = require ('../../InvalidArgumentError');
+var InvalidArgumentError = require('../../InvalidArgumentError');
 
 var Functions = require('../../Functions');
 var logger = require('../../logger');
@@ -38,29 +38,29 @@ ChooseAnnotatorsDialog.prototype.createGui = function () {
 
   var annotatorsDiv = Functions.createElement({
     type: "div",
-    style: "display:table-cell",
-    xss: false
+    style: "display:table-cell;width:100%"
   });
 
   annotatorsDiv.appendChild(Functions.createElement({
-    type: "div",    
-    name: "annotatorListBox"
+    type: "div",
+    name: "annotatorListBox",
+    style: "width:100%;height:250px"
   }));
 
   annotatorsDiv.appendChild(Functions.createElement({
-    type: "div",    
+    type: "div",
     className: "minerva-annotators-params"
   }));
 
-  content.appendChild(annotatorsDiv);  
+  content.appendChild(annotatorsDiv);
 
   self.getElement().appendChild(content);
 };
 
-function onChangeParameterValue(element, user){  
+function onChangeParameterValue(element, user) {
   var name = $(element).siblings(".minerva-annotator-param-name")[0].childNodes[0].nodeValue;
   var annotatorClassName = $(element).parent().parent().attr('name');
-     
+
   var data = new UserPreferences();
 
   var annotatorsParams = {};
@@ -69,7 +69,7 @@ function onChangeParameterValue(element, user){
   else annotatorsParams[annotatorClassName][name] = element.value;
   data.setAnnotatorsParameters(annotatorsParams);
 
-  return ServerConnector.updateUserPreferences({user: user, preferences: data}).then(null, GuiConnector.alert);  
+  return ServerConnector.updateUserPreferences({user: user, preferences: data}).then(null, GuiConnector.alert);
 }
 
 ChooseAnnotatorsDialog.prototype.setElementType = function (elementType) {
@@ -84,32 +84,78 @@ ChooseAnnotatorsDialog.prototype.setElementType = function (elementType) {
     var element = $("[name='annotatorListBox']", self.getElement())[0];
     var annotatorsParams = $(".minerva-annotators-params", self.getElement())[0];
     Functions.removeChildren(element);
-    
+
     var selectElement = Functions.createElement({
-      type: "select",
-      className: "minerva-multi-select"
+      type: "div",
+      style: "width:50%; height:200px;float:left; OVERFLOW-Y:scroll"
     });
 
-    var annotators = configuration.getElementAnnotators(elementType);    
+    element.appendChild(selectElement);
+
+    var annotators = configuration.getElementAnnotators(elementType);
 
     var selectedAnnotators = user.getPreferences().getElementAnnotators(elementType.className);
 
+    var selectedValues = [];
+
+    var entries = [];
+
     for (var i = 0; i < annotators.length; i++) {
       var annotator = annotators[i];
-      var selected = false;
+      var entry = {name: annotator.getName(), value: annotator.getClassName(), selected: false};
       for (var j = 0; j < selectedAnnotators.length; j++) {
         if (annotator.getName() === selectedAnnotators[j]) {
-          selected = true;
-        }      
+          entry.selected = true;
+        }
       }
-      var option = new Option();
-      option.value = annotator.getClassName();
-      option.attributes.selected = selected;
-      option.innerHTML = "<div>" + annotator.getName() + "</div>";
-      selectElement.appendChild(option);
+      entries.push(entry);
     }
+    var checkboxList = new MultiCheckboxList(selectElement, {
+      entries: entries,
+      listTitle: "Available annotators",
+      selectedTitle: "Selected annotators",
+      selectedList: true
+    });
+    var changeSelection = function (elementId, selected) {
+
+      var annotators = configuration.getElementAnnotators();
+      var annotator;
+      for (var i = 0; i < annotators.length; i++) {
+        if (elementId === annotators[i].getClassName()) {
+          annotator = annotators[i];
+        }
+      }
+      var data = new UserPreferences();
+
+      var elementAnnotators = {};
+      if (selected) {
+        selectedAnnotators.push(annotator.getName());
+      } else {
+        var index = selectedAnnotators.indexOf(annotator.getName());
+        if (index > -1) {
+          selectedAnnotators.splice(index, 1);
+        }
+      }
+      createAnnotatorsParams();
+
+      elementAnnotators[elementType.className] = selectedAnnotators;
+      data.setElementAnnotators(elementAnnotators);
+      return ServerConnector.updateUserPreferences({
+        user: user,
+        preferences: data
+      }).then(null, GuiConnector.alert);
+    };
+
+    checkboxList.addListener("select", function (element) {
+      return changeSelection(element.value, true);
+    });
+    checkboxList.addListener("deselect", function (element) {
+      return changeSelection(element.value, false);
+    });
+
+
+    function createAnnotatorsParams() {
 
-    function createAnnotatorsParams(){
       var existingAnnotatorsParameters = user.getPreferences().getAnnotatorsParameters();
 
       Functions.removeChildren(annotatorsParams);
@@ -117,35 +163,34 @@ ChooseAnnotatorsDialog.prototype.setElementType = function (elementType) {
         var annotator = annotators[i];
         for (var j = 0; j < selectedAnnotators.length; j++) {
           if (annotator.getName() === selectedAnnotators[j]) {
-            
             var paramsDefs = annotator.getParametersDefinitions();
             if (paramsDefs.length > 0) {
-              
+
               annotatorsParams.appendChild(Functions.createElement({
-                type: "div",    
+                type: "div",
                 className: "minerva-annotators-params-header",
                 content: '<div>Available parameters</div>'
-              }))
-  
+              }));
+
               var annotatorParams = Functions.createElement({
-                type: "div",    
+                type: "div",
                 className: "minerva-annotator-params",
                 name: annotator.getClassName()
               });
-    
+
               annotatorParams.appendChild(Functions.createElement({
-                type: "div",    
+                type: "div",
                 className: "minerva-annotator-params-header",
                 content: annotator.getName()
               }));
-  
+
               for (var k = 0; k < paramsDefs.length; k++) {
-                var param = paramsDefs[k];              
+                var param = paramsDefs[k];
                 var paramElement = Functions.createElement({
-                  type: "div",    
+                  type: "div",
                   className: "minerva-annotator-param"
                 });
-  
+
                 var paramName = Functions.createElement({
                   type: "div",
                   className: "minerva-annotator-param-name",
@@ -153,10 +198,10 @@ ChooseAnnotatorsDialog.prototype.setElementType = function (elementType) {
                 });
 
                 var tooltipContainer = Functions.createElement({
-                  type: "span"            
+                  type: "span"
                 });
                 tooltipContainer.appendChild(Functions.createElement({
-                  type: "span",    
+                  type: "span",
                   className: "glyphicon glyphicon-question-sign tooltip-icon"
                 }));
                 tooltipContainer.appendChild(Functions.createElement({
@@ -164,104 +209,60 @@ ChooseAnnotatorsDialog.prototype.setElementType = function (elementType) {
                   className: "annotator-tooltip",
                   content: param.description
                 }));
-  
-                paramName.appendChild(tooltipContainer)
-                paramElement.appendChild(paramName);    
-  
+
+                paramName.appendChild(tooltipContainer);
+                paramElement.appendChild(paramName);
+
                 var paramValue;
-  
+
                 var existingParamValue;
                 if (existingAnnotatorsParameters[annotator.getClassName()]) {
                   existingParamValue = existingAnnotatorsParameters[annotator.getClassName()][param.name]
                 }
-  
+
                 if (param.type.indexOf("String") >= 0) {
                   paramValue = Functions.createElement({
                     type: "textarea",
-                    onchange: function(){return onChangeParameterValue(this, user);}
+                    onchange: function () {
+                      return onChangeParameterValue(this, user);
+                    }
                   });
                   if (existingParamValue) paramValue.value = existingParamValue;
                 } else if (param.type.indexOf("Integer") >= 0) {
                   paramValue = Functions.createElement({
                     type: "input",
                     inputType: "number",
-                    onchange: function(){return onChangeParameterValue(this, user);}
+                    onchange: function () {
+                      return onChangeParameterValue(this, user);
+                    }
                   });
                   if (existingParamValue) paramValue.value = existingParamValue;
                 } else if (param.type.indexOf("Boolean") >= 0) {
                   paramValue = Functions.createElement({
                     type: "input",
                     inputType: "checkbox",
-                    onchange: function(){return onChangeParameterValue(this, user);}
+                    onchange: function () {
+                      return onChangeParameterValue(this, user);
+                    }
                   });
                   paramValue.checked = (existingParamValue && existingParamValue === 'true');
                 } else {
                   throw new InvalidAlgorithmError("Unknown annotator parameter type");
-                }    
-                
+                }
+
                 paramElement.appendChild(paramValue);
-                annotatorParams.appendChild(paramElement);              
+                annotatorParams.appendChild(paramElement);
               }
-  
+
               annotatorsParams.appendChild(annotatorParams);
             }
-          }      
-        }
-      };
-
-    }
-    createAnnotatorsParams();
-
-    element.appendChild(selectElement);
-    new DualListbox(selectElement, {
-      addEvent: function (value) {
-        var annotators = configuration.getElementAnnotators();
-        var annotator;
-        for (var i = 0; i < annotators.length; i++) {
-          if (value === annotators[i].getClassName()) {
-            annotator = annotators[i];
           }
         }
-        selectedAnnotators.push(annotator.getName());
+      }
+    }
 
-        createAnnotatorsParams();
-
-        var data = new UserPreferences();
-
-        var elementAnnotators = {};
-        elementAnnotators[elementType.className] = selectedAnnotators;
-        data.setElementAnnotators(elementAnnotators);
-        return ServerConnector.updateUserPreferences({user: user, preferences: data}).then(null, GuiConnector.alert);
-      },
-      removeEvent: function (value) {
-        var annotators = configuration.getElementAnnotators();
-        var annotator;
-        for (var i = 0; i < annotators.length; i++) {
-          if (value === annotators[i].getClassName()) {
-            annotator = annotators[i];
-          }
-        }
-        var index = selectedAnnotators.indexOf(annotator.getName());
-        if (index > -1) {
-          selectedAnnotators.splice(index, 1);
-        }
+    createAnnotatorsParams();
 
-        createAnnotatorsParams();
-        
-        var data = new UserPreferences();
-
-        var elementAnnotators = {};
-        elementAnnotators[elementType.className] = selectedAnnotators;
-        data.setElementAnnotators(elementAnnotators);
-        return ServerConnector.updateUserPreferences({user: user, preferences: data}).then(null, GuiConnector.alert);
-      },
-      availableTitle: 'Available',
-      selectedTitle: 'Used',
-      addButtonText: '>',
-      removeButtonText: '<',
-      addAllButtonText: '>>',
-      removeAllButtonText: '<<'
-    });
   });
 
 };
diff --git a/frontend-js/src/main/js/gui/admin/ChooseValidatorsDialog.js b/frontend-js/src/main/js/gui/admin/ChooseValidatorsDialog.js
index 91cb0d6d7c..ff901f023b 100644
--- a/frontend-js/src/main/js/gui/admin/ChooseValidatorsDialog.js
+++ b/frontend-js/src/main/js/gui/admin/ChooseValidatorsDialog.js
@@ -6,6 +6,7 @@ var AbstractGuiElement = require('../AbstractGuiElement');
 var DualListbox = require('dual-listbox').DualListbox;
 var GuiConnector = require("../../GuiConnector");
 var UserPreferences = require("../../map/data/UserPreferences");
+var MultiCheckboxList = require("multi-checkbox-list");
 
 var Functions = require('../../Functions');
 var logger = require('../../logger');
@@ -79,66 +80,61 @@ ChooseValidatorsDialog.prototype.createValidAnnotationsDualListBox = function (u
 
   var validAnnotations = user.getPreferences().getElementValidAnnotations(elementType.className);
 
+  var entries = [];
+
+
   for (var i = 0; i < miriamTypes.length; i++) {
     var miriamType = miriamTypes[i];
+    var entry = {name: miriamType.getCommonName(), value: miriamType.getName(), selected: false};
+
     var selected = false;
     for (var j = 0; j < validAnnotations.length; j++) {
       if (miriamType.getName() === validAnnotations[j]) {
-        selected = true;
+        entry.selected = true;
       }
     }
-    var option = new Option();
-    option.value = miriamType.getName();
-    option.attributes.selected = selected;
-    option.innerHTML = "<div>" + miriamType.getCommonName() + "</div>";
-    validAnnotationSelect.appendChild(option);
+    entries.push(entry);
   }
 
-  new DualListbox(validAnnotationSelect, {
-    addEvent: function (value) {
-      var miriamTypes = configuration.getMiriamTypes();
-      var miriamType;
-      for (var i = 0; i < miriamTypes.length; i++) {
-        if (value === miriamTypes[i].getName()) {
-          miriamType = miriamTypes[i];
-        }
-      }
-      validAnnotations.push(miriamType.getName());
-
-      var data = new UserPreferences();
+  var checkboxList = new MultiCheckboxList(validAnnotationSelect, {
+    entries: entries,
+    listTitle: "Available",
+    selectedTitle: "Selected",
+    selectedList: true
+  });
 
-      var elementAnnotators = {};
-      elementAnnotators[elementType.className] = validAnnotations;
-      data.setElementValidAnnotations(elementAnnotators);
-      return ServerConnector.updateUserPreferences({user: user, preferences: data}).then(null, GuiConnector.alert);
-    },
-    removeEvent: function (value) {
-      var miriamTypes = configuration.getMiriamTypes();
-      var miriamType;
-      for (var i = 0; i < miriamTypes.length; i++) {
-        if (value === miriamTypes[i].getName()) {
-          miriamType = miriamTypes[i];
-        }
+  var changeSelection = function (elementId, selected) {
+    var miriamTypes = configuration.getMiriamTypes();
+    var miriamType;
+    for (var i = 0; i < miriamTypes.length; i++) {
+      if (elementId === miriamTypes[i].getName()) {
+        miriamType = miriamTypes[i];
       }
+    }
+    if (selected) {
+      validAnnotations.push(miriamType.getName());
+    } else {
       var index = validAnnotations.indexOf(miriamType.getName());
       if (index > -1) {
         validAnnotations.splice(index, 1);
       }
+    }
 
-      var data = new UserPreferences();
+    var data = new UserPreferences();
 
-      var elementAnnotators = {};
-      elementAnnotators[elementType.className] = validAnnotations;
-      data.setElementValidAnnotations(elementAnnotators);
-      return ServerConnector.updateUserPreferences({user: user, preferences: data}).then(null, GuiConnector.alert);
-    },
-    availableTitle: 'Available',
-    selectedTitle: 'Used',
-    addButtonText: '>',
-    removeButtonText: '<',
-    addAllButtonText: '>>',
-    removeAllButtonText: '<<'
+    var elementAnnotators = {};
+    elementAnnotators[elementType.className] = validAnnotations;
+    data.setElementValidAnnotations(elementAnnotators);
+    return ServerConnector.updateUserPreferences({user: user, preferences: data}).then(null, GuiConnector.alert);
+  };
+
+  checkboxList.addListener("select", function (element) {
+    return changeSelection(element.value, true);
+  });
+  checkboxList.addListener("deselect", function (element) {
+    return changeSelection(element.value, false);
   });
+
 };
 
 ChooseValidatorsDialog.prototype.createVerifyAnnotationsDualListBox = function (user, configuration, elementType, verifyAnnotationSelect) {
@@ -162,6 +158,8 @@ ChooseValidatorsDialog.prototype.createVerifyAnnotationsDualListBox = function (
     }
   });
   checkbox.checked = requiredAnnotationsData.requiredAtLeastOnce;
+  verifyCheckboxDiv.appendChild(Functions.createElement({type: "br"}));
+  verifyCheckboxDiv.appendChild(Functions.createElement({type: "br"}));
   verifyCheckboxDiv.appendChild(checkbox);
   verifyCheckboxDiv.appendChild(Functions.createElement({
     type: "span",
@@ -171,73 +169,62 @@ ChooseValidatorsDialog.prototype.createVerifyAnnotationsDualListBox = function (
 
   var miriamTypes = configuration.getMiriamTypes();
 
+  var entries = [];
 
   for (var i = 0; i < miriamTypes.length; i++) {
     var miriamType = miriamTypes[i];
-    var selected = false;
+    var entry = {name: miriamType.getCommonName(), value: miriamType.getName(), selected: false};
     for (var j = 0; j < requiredAnnotationsData.list.length; j++) {
       if (miriamType.getName() === requiredAnnotationsData.list[j]) {
-        selected = true;
+        entry.selected = true;
       }
     }
-    var option = new Option();
-    option.value = miriamType.getName();
-    option.attributes.selected = selected;
-    option.innerHTML = "<div>" + miriamType.getCommonName() + "</div>";
-    verifyAnnotationSelect.appendChild(option);
+    entries.push(entry);
   }
 
-  new DualListbox(verifyAnnotationSelect, {
-    addEvent: function (value) {
-      var miriamTypes = configuration.getMiriamTypes();
-      var miriamType;
-      for (var i = 0; i < miriamTypes.length; i++) {
-        if (value === miriamTypes[i].getName()) {
-          miriamType = miriamTypes[i];
-        }
-      }
-      requiredAnnotationsData.list.push(miriamType.getName());
+  var checkboxList = new MultiCheckboxList(verifyAnnotationSelect, {
+    entries: entries,
+    listTitle: "Available",
+    selectedTitle: "Selected",
+    selectedList: true
+  });
 
-      var data = new UserPreferences();
+  var changeSelection = function (elementId, selected) {
 
-      var elementRequiredAnnotations = {};
-      elementRequiredAnnotations[elementType.className] = {
-        "require-at-least-one": requiredAnnotationsData.requiredAtLeastOnce,
-        "annotation-list": requiredAnnotationsData.list
-      };
-      data.setElementRequiredAnnotations(elementRequiredAnnotations);
-      return ServerConnector.updateUserPreferences({user: user, preferences: data}).then(null, GuiConnector.alert);
-    },
-    removeEvent: function (value) {
-      var miriamTypes = configuration.getMiriamTypes();
-      var miriamType;
-      for (var i = 0; i < miriamTypes.length; i++) {
-        if (value === miriamTypes[i].getName()) {
-          miriamType = miriamTypes[i];
-        }
+    var miriamTypes = configuration.getMiriamTypes();
+    var miriamType;
+    for (var i = 0; i < miriamTypes.length; i++) {
+      if (elementId === miriamTypes[i].getName()) {
+        miriamType = miriamTypes[i];
       }
+    }
+    if (selected) {
+      requiredAnnotationsData.list.push(miriamType.getName());
+    } else {
       var index = requiredAnnotationsData.list.indexOf(miriamType.getName());
       if (index > -1) {
         requiredAnnotationsData.list.splice(index, 1);
       }
+    }
 
-      var data = new UserPreferences();
+    var data = new UserPreferences();
 
-      var elementRequiredAnnotations = {};
-      elementRequiredAnnotations[elementType.className] = {
-        "require-at-least-one": requiredAnnotationsData.requiredAtLeastOnce,
-        "annotation-list": requiredAnnotationsData.list
-      };
-      data.setElementRequiredAnnotations(elementRequiredAnnotations);
-      return ServerConnector.updateUserPreferences({user: user, preferences: data}).then(null, GuiConnector.alert);
-    },
-    availableTitle: 'Available',
-    selectedTitle: 'Used',
-    addButtonText: '>',
-    removeButtonText: '<',
-    addAllButtonText: '>>',
-    removeAllButtonText: '<<'
+    var elementRequiredAnnotations = {};
+    elementRequiredAnnotations[elementType.className] = {
+      "require-at-least-one": requiredAnnotationsData.requiredAtLeastOnce,
+      "annotation-list": requiredAnnotationsData.list
+    };
+    data.setElementRequiredAnnotations(elementRequiredAnnotations);
+    return ServerConnector.updateUserPreferences({user: user, preferences: data}).then(null, GuiConnector.alert);
+  };
+
+  checkboxList.addListener("select", function (element) {
+    return changeSelection(element.value, true);
   });
+  checkboxList.addListener("deselect", function (element) {
+    return changeSelection(element.value, false);
+  });
+
 };
 
 ChooseValidatorsDialog.prototype.init = function () {
-- 
GitLab