Add new criterions using menus
diff --git a/dev/js/src/vc.js b/dev/js/src/vc.js
index 4598275..2587d1c 100644
--- a/dev/js/src/vc.js
+++ b/dev/js/src/vc.js
@@ -4,14 +4,13 @@
  * @author Nils Diewald
  */
 /*
- * Replaces a previous version written by Mengfei Zhou
+ * This replaces a previous version written by Mengfei Zhou
  */
 
 /*
-  TODO: Implement a working localization solution!
   TODO: Disable "and" or "or" in case it's followed
         by an unspecified document
-  TODO: Implement "persistance"-Option,
+  TODO: Implement "persistence"-Option,
         injecting the current creation date stamp
 
   Error codes:
@@ -28,14 +27,23 @@
   813: "Collection type is not supported" (like 713)
   814: "Unknown rewrite operation"
   815: "Rewrite expects source"
+
+  Localization strings:
+  KorAP.Locale = {
+    EMPTY : '...',
+    AND : 'and',
+    OR : 'or',
+    DELETE : 'x'
+  }
 */
 
 define([
   'vc/unspecified',
   'vc/doc',
   'vc/docgroup',
+  'vc/menu',
   'util'
-], function (unspecDocClass, docClass, docGroupClass) {
+], function (unspecDocClass, docClass, docGroupClass, menuClass) {
   "use strict";
 
   // ???
@@ -46,15 +54,24 @@
 
   var loc = KorAP.Locale;
 
+  KorAP._vcKeyMenu = undefined;
+
   /**
    * Virtual Collection
    */
   return {
+
+    /**
+     * The JSON-LD type of the virtual collection
+     */
     ldType : function () {
       return null;
     },
 
-    _init : function () {
+    // Initialize virtual collection
+    _init : function (keyList) {
+
+      // Inject localized css styles
       if (!KorAP._overrideStyles) {
 	var sheet = KorAP.newStyleSheet();
 
@@ -74,16 +91,21 @@
 	  1
 	);
 
-	console.log(sheet);
-
 	KorAP._overrideStyles = true;
+
+	// Create key menu
+	KorAP._vcKeyMenu = menuClass.create(keyList);
+	KorAP._vcKeyMenu.limit(5);
       };
 
       return this;
     },
 
-    create : function () {
-      return Object.create(this)._init();
+    /**
+     * Create a new virtual collection.
+     */
+    create : function (keyList) {
+      return Object.create(this)._init(keyList);
     },
 
     clean : function () {
@@ -94,17 +116,23 @@
       return this;
     },
 
-    render : function (json) {
-      var obj = Object.create(this)._init();
+    /**
+     * Create and render a new virtual collection
+     * based on a KoralQuery collection document 
+     */
+    render : function (json, keyList) {
+      var obj = Object.create(this)._init(keyList);
 
       if (json !== undefined) {
-	// Root object
+	// Parse root document
 	if (json['@type'] == 'koral:doc') {
 	  obj._root = docClass.create(obj, json);
 	}
+	// parse root group
 	else if (json['@type'] == 'koral:docGroup') {
 	  obj._root = docGroupClass.create(obj, json);
 	}
+	// Unknown collection type
 	else {
 	  KorAP.log(813, "Collection type is not supported");
 	  return;
@@ -122,6 +150,10 @@
       return obj;
     },
 
+    /**
+     * Get or set the root object of the
+     * virtual collection.
+     */
     root : function (obj) {
       if (arguments.length === 1) {
 	var e = this.element();
@@ -145,6 +177,9 @@
       return this._root;
     },
 
+    /**
+     * Get the element associated with the virtual collection
+     */
     element : function () {
       if (this._element !== undefined)
 	return this._element;
@@ -158,15 +193,28 @@
       return this._element;
     },
 
+
+    /**
+     * Update the whole object based on the underlying
+     * data structure
+     */
     update : function () {
       this._root.update();
       return this;
     },
 
+
+    /**
+     * Get the generated json string
+     */
     toJson : function () {
       return this._root.toJson();
     },
 
+
+    /**
+     * Get the generated query string
+     */
     toQuery : function () {
       return this._root.toQuery();
     }
diff --git a/dev/js/src/vc/doc.js b/dev/js/src/vc/doc.js
index 700f410..436f9ef 100644
--- a/dev/js/src/vc/doc.js
+++ b/dev/js/src/vc/doc.js
@@ -2,20 +2,10 @@
  * Document criterion
  */
 
-/**
- * Criterion in a KorAP.Doc
- */
-function _changeKey () {
-  var doc = this.parentNode.refTo;
-  var key = doc.element().firstChild;
-  key.appendChild(fieldMenu.element());
-  fieldMenu.show();
-  fieldMenu.focus();
-  // key, matchop, type, value
-};
-
 define([
-  'vc/jsonld', 'vc/menu', 'vc/rewritelist'], function (jsonldClass, menuClass, rewriteListClass) {
+  'vc/jsonld', 'vc/rewritelist'], function (jsonldClass, rewriteListClass) {
+
+/*
   var fieldMenu = menuClass.create([
     ['Titel', 'title', 'string'],
     ['Untertitel', 'subTitle', 'string'],
@@ -24,9 +14,22 @@
   ]);
 
   fieldMenu.limit(5);
+*/
 
   _validRegexMatchRE  = new RegExp("^(?:eq|ne)$");
 
+    /**
+     * Criterion in a KorAP.Doc
+     */
+    function _changeKey () {
+      var doc = this.parentNode.refTo;
+      var key = doc.element().firstChild;
+      key.appendChild(fieldMenu.element());
+      fieldMenu.show();
+      fieldMenu.focus();
+      // key, matchop, type, value
+    };
+
   return {
     _ldType : "doc",
     _obj : function () { return '???'; /*KorAP.Doc*/ },
diff --git a/dev/js/src/vc/item.js b/dev/js/src/vc/item.js
index bfefe38..7922bbd 100644
--- a/dev/js/src/vc/item.js
+++ b/dev/js/src/vc/item.js
@@ -20,6 +20,15 @@
       return this;
     },
 
+    onclick : function (e) {
+      this.menu().release(
+	this._name,
+	this._value,
+	this._type
+      );
+      e.halt();
+    },
+
     name : function () {
       return this._name;
     },
@@ -37,6 +46,10 @@
       var li = document.createElement("li");
       li.setAttribute("data-type", this._type);
       li.setAttribute("data-value", this._value);
+
+      // Connect action
+      li["onclick"] = this.onclick.bind(this);
+
       li.appendChild(document.createTextNode(this._name));
       return this._element = li;
     }
diff --git a/dev/js/src/vc/menu.js b/dev/js/src/vc/menu.js
index 6f6d2bd..2cdc0e8 100644
--- a/dev/js/src/vc/menu.js
+++ b/dev/js/src/vc/menu.js
@@ -1,10 +1,17 @@
 // Field menu
-define(['menu', 'menu/item'], function (menuClass, itemClass) {
+define(['menu', 'vc/item'], function (menuClass, itemClass) {
   return {
     create : function (params) {
       return Object.create(menuClass)
 	.upgradeTo(this)
 	._init(itemClass, undefined, params)
+    },
+    released : function (cb) {
+      this._cb = cb;
+    },
+    release : function (name, value, type) {
+      if (this._cb !== undefined)
+	this._cb(name, value, type);
     }
   };
 });
diff --git a/dev/js/src/vc/unspecified.js b/dev/js/src/vc/unspecified.js
index 9efd007..f10dcf7 100644
--- a/dev/js/src/vc/unspecified.js
+++ b/dev/js/src/vc/unspecified.js
@@ -1,13 +1,26 @@
 /**
- * Unspecified criterion
+ * An unspecified criterion in a virtual collection.
+ * Inherits everything from jsonld
  */
-define(['vc/jsonld', 'vc/doc', 'util'], function (jsonldClass, docClass) {
+define([
+  'vc/jsonld',
+  'vc/doc',
+  'util'
+], function (jsonldClass, docClass) {
 
+  // Localize empty string
   var loc = KorAP.Locale;
   loc.EMPTY = loc.EMPTY || '⋯';
 
   return {
+
+    // The ld-type
     _ldType : "non",
+
+    /**
+     * Create new unspecified criterion
+     * with a link to the parent object
+     */
     create : function (parent) {
       var obj = Object.create(jsonldClass).
 	upgradeTo(this);
@@ -18,7 +31,9 @@
       return obj;
     },
 
-    // Set key - replace
+    /**
+     * Set the key; this will spawn a new doc
+     */
     key : function (v) {
 
       // Not replaceable
@@ -46,6 +61,10 @@
       return newDoc;
     },
 
+
+    /**
+     * Update the element
+     */
     update : function () {
 
       if (this._element === undefined)
@@ -56,6 +75,10 @@
 
       var ellipsis = document.createElement('span');
       ellipsis.appendChild(document.createTextNode(loc.EMPTY));
+
+      // Click on empty criterion
+      ellipsis.addEventListener('click', this.onclick.bind(this));
+
       this._element.appendChild(ellipsis);
 
       // Set ref - TODO: Cleanup!
@@ -77,6 +100,10 @@
       return this.element();
     },
 
+
+    /**
+     * Get the associated element
+     */
     element : function () {
       if (this._element !== undefined)
 	return this._element;
@@ -85,5 +112,30 @@
       this.update();
       return this._element;
     },
+
+    /**
+     * Click on the unspecified object
+     */
+    onclick : function () {
+      var menu = KorAP._vcKeyMenu;
+
+      // Add keyelement at the correct position
+      this._element.insertBefore(
+	menu.element(),	
+	this._element.firstChild
+      );
+
+      var that = this;
+
+      // Set released method
+      menu.released(function (name, value, type) {
+	that.key(name);
+	// + ' # ' + type);
+	this.hide();
+      });
+
+      menu.show();
+      menu.focus();
+    }
   };
 });