Added a method to container that allows for removing items dynamically

Change-Id: Ibcc5eee453a65943a80141ada4cebe0aed0112f6
diff --git a/dev/demo/containermenudemo.js b/dev/demo/containermenudemo.js
index 9c81bf0..e3b0f99 100644
--- a/dev/demo/containermenudemo.js
+++ b/dev/demo/containermenudemo.js
@@ -92,9 +92,15 @@
   var ExampleItemList = new Array;
   ExampleItemList.push(OwnContainerItemClass.create());
   ExampleItemList.push(OwnContainerItemClass.create());
+  ExampleItemList.push(OwnContainerItemClass.create());
   ExampleItemList[0].value = "Example Item 1";
   ExampleItemList[0]._i = 3;
   ExampleItemList[1]._i = 4;
+  ExampleItemList[2].value = "Remove the Prefix Test";
+  ExampleItemList[2]._i=5;
+  ExampleItemList[2].onclick = function (e) {
+    this._menu.container().removeItemByIndex(3);
+  };
 
   //Own container class.
   var OwnContainerClass = {
diff --git a/dev/js/spec/containerMenuSpec.js b/dev/js/spec/containerMenuSpec.js
index 61f919f..40d72e0 100644
--- a/dev/js/spec/containerMenuSpec.js
+++ b/dev/js/spec/containerMenuSpec.js
@@ -96,7 +96,7 @@
       }
     };
 
-    describe('OwnContainerMenu', function () {
+    describe('KorAP.ContainerMenu', function () {
 
       var list = [
         ["Constituency"],
@@ -327,6 +327,50 @@
 
       });
 
+      it('should allow removing an item from the container list', function () {/**var list = [
+        ["Constituency"],
+        ["Lemma"],
+        ["Morphology"],
+        ["Part-of-Speech"],
+        ["Syntax"]
+      ];
+      */
+        var menu = OwnContainerMenu.create(list,ExampleItemList);
+        menu._firstActive = true;
+        menu.limit(3);
+        expect(menu.show()).toBe(true);
+        menu.next();
+        menu.next();
+        menu.next();
+        menu.next();
+        expect(menu.shownItem(2).active()).toBe(true);
+        expect(menu.container().item(0).active()).toBe(false);
+        expect(menu.container().item(1).active()).toBe(false);
+        expect(menu.container().item(2).active()).toBe(false); //prefix
+        expect(menu.container().item(2)).toEqual(menu._prefix);
+        expect(menu.container().length()).toBe(3);
+        menu.container().removeItemByIndex(0);
+        expect(menu.shownItem(2).active()).toBe(true);
+        expect(menu.container().item(0).active()).toBe(false);
+        expect(menu.container().item(1).active()).toBe(false); //prefix
+        expect(menu.container().item(1)).toEqual(menu._prefix);
+        expect(menu.container().length()).toBe(2);
+        menu.next();
+        expect(menu.shownItem(2).active()).toBe(false);
+        expect(menu.container().item(0).active()).toBe(true);
+        expect(menu.container().item(1).active()).toBe(false); //prefix
+        expect(menu.container().item(1)).toEqual(menu._prefix);
+        expect(menu.container().length()).toBe(2);
+        menu.container().removeItemByIndex(0);
+        expect(menu.shownItem(2).active()).toBe(false);
+        expect(menu.shownItem(0).active()).toBe(true);
+        expect(menu.container().item(0).active()).toBe(false); //prefix //would be selected, if it were not ""
+        expect(menu.container().item(0)).toEqual(menu._prefix);
+        expect(menu.container().length()).toBe(1);
+
+        
+
+      });
       it('should be nextable', function () {
         var menu = OwnContainerMenu.create(list);
         menu._firstActive = true;
@@ -2055,7 +2099,8 @@
         expect(menu.slider().length()).toEqual(4);
       });
     });
-    describe('Container', function () {
+
+    describe('KorAP.ContainerMenu.Container', function () {
       it("should be initializable with no additional container items", function () {
         var list = [
           ["Constituency"],
@@ -2085,8 +2130,6 @@
         expect(container.liveLength()).toEqual(1);
         menu.prev();
         expect(container.active()).toBeTruthy();
-
-        
       });
 
     });
diff --git a/dev/js/src/container/container.js b/dev/js/src/container/container.js
index 9cf5205..02d6fba 100644
--- a/dev/js/src/container/container.js
+++ b/dev/js/src/container/container.js
@@ -14,11 +14,11 @@
 
   return {
     /**
-     * 
-     * @param {Array<object>} listOfContainerItems List of items that will be placed within the container and that realise some of the functions supplied in containeritem.js
-     * @param {object} params May contain attribute containerItemClass for a base class all containerItems build upon
-     * @returns The container object
-     */
+    * 
+    * @param {Array<object>} listOfContainerItems List of items that will be placed within the container and that realise some of the functions supplied in containeritem.js
+    * @param {object} params May contain attribute containerItemClass for a base class all containerItems build upon
+    * @returns The container object
+    */
     create : function (listOfContainerItems, params) {
       var obj = Object.create(this);
       obj._init(listOfContainerItems, params);
@@ -58,8 +58,7 @@
       
       //t._el.classList.add('visible'); //Done by containermenu
 
-
-    },
+  },
 
     addItem : function (item) {
       var cItem = this._containerItemClass.create().upgradeTo(item);
@@ -90,12 +89,49 @@
         this._menu._prefix=prefItem;
       }
     },
+    
+    /**
+    * Remove a containeritem from the container by identity. Should not be used with prefix.
+    * If the active item is removed, this calls menu.next().
+    * @param {containerItemClass} item The item to be removed.
+    */
+    removeItem : function (item) {
+      if (this.items.indexOf(item) === -1){ // This is returned if indexOf cannot find the item.
+        KorAP.log(0,"Invalid item in containers removeItemByIndex: This containerItem is not contained", "container.js");
+        return;
+      };
+      if (item === this._prefix) {//CHANGE TO _cItemPrefix later!!!
+        KorAP.log(0,"Tried to remove the prefix item by calling removeItem. Please cut all connections from the menu to prefix and then\
+ the connection container._prefix before calling this function if you really want to remove the prefix.","container.js");
+        return;
+      };
+      if (item.active()) {
+        this._menu.next();
+      };
+      item._menu=undefined;
+      this._el.removeChild(item.element());
+      this.items.splice(this.items.indexOf(item) , 1);
+    },
 
     /**
-     * Exit the container unconditionally. Required so that active returns the
-     * correct result. Called when the prefix or similar resets the currently visual
-     * field.
+     * Remove a containeritem from the container by its index. Should not be used with prefix.
+     * CAUTION liveIndex, so what you see, is not the actual index within the containerItem list.
+     * This can be accessed with container.items . If the active item is removed, this calls menu.next().
+     * @param {Int} index The index of the item to be removed.
      */
+    removeItemByIndex : function (index) {
+      if (index < 0 || index >= this.length()){
+        KorAP.log(0,"Invalid index in containers removeItemByIndex: "+index, "container.js");
+        return;
+      };
+      this.removeItem(this.items[index]); //CAUTION liveIndex (what you see) != index within the list!
+    },
+
+    /**
+    * Exit the container unconditionally. Required so that active returns the
+    * correct result. Called when the prefix or similar resets the currently visual
+    * field.
+    */
     exit : function () {
       if (this.position !== undefined) {
         this.item().active(false);
@@ -114,17 +150,17 @@
     },
 
     /**
-     * @returns whether an item within the container is active (by checking this.position)
-     */
+    * @returns whether an item within the container is active (by checking this.position)
+    */
     active : function () {
       return this.position !== undefined;
     },
 
     /**
-     * Getter for items
-     * @param {Integer} index [optional] Index of to select item. If left blank this.position.
-     * @returns item at location index
-     */
+    * Getter for items
+    * @param {Integer} index [optional] Index of to select item. If left blank this.position.
+    * @returns item at location index
+    */
     item : function (index) {
       if (index === undefined) return this.items[this.position];
       return this.items[index];
@@ -149,10 +185,11 @@
         }
       }
     },
-
+    
     /**
-     * Move on to the next item in container. Returns true if we then leave the container, false otherwise.
-     */
+     * 
+    * Move on to the next item in container. Returns true if we then leave the container, false otherwise.
+    */
     next : function() {
       if (this.position !== undefined){
         this.item().active(false);
@@ -176,8 +213,8 @@
     },
 
     /**
-     * Move on to the previous item in container. Returns true if we then leave the container, false otherwise.
-     */
+    * Move on to the previous item in container. Returns true if we then leave the container, false otherwise.
+    */
     prev : function() {
       if (this.position !== undefined){
         this.item().active(false);
@@ -228,9 +265,9 @@
     },
 
     /**
-     * 
-     * @returns The number of items that are selectable. Is the actual length of the list.
-     */
+    * 
+    * @returns The number of items that are selectable. Is the actual length of the list.
+    */
     liveLength : function () {
       var ll = 0;
       for (let item of this.items){