Add corpusByMatch fragment to VC builder (Issue #27)

Change-Id: I3c7ecb434572412203bb6055b4ce8f2947975306
diff --git a/dev/js/src/init.js b/dev/js/src/init.js
index e2d89b9..34a838a 100644
--- a/dev/js/src/init.js
+++ b/dev/js/src/init.js
@@ -263,19 +263,19 @@
 
       vc.onOpen = function () {
         vcname.classList.add('active');
+
+        var view = d.getElementById('vc-view');
+        if (!view.firstChild)
+          view.appendChild(this.element());
+        
         show['collection'] = true;
       };
       
       var vcclick = function () {
-
         if (vc.isOpen()) {
           vc.minimize()
         }
         else {
-          var view = d.getElementById('vc-view');
-          if (!view.firstChild)
-            view.appendChild(vc.element());
-
           vc.open();
         };
       };
diff --git a/dev/js/src/match/corpusByMatch.js b/dev/js/src/match/corpusByMatch.js
index 050ecb7..a9bcf58 100644
--- a/dev/js/src/match/corpusByMatch.js
+++ b/dev/js/src/match/corpusByMatch.js
@@ -30,11 +30,45 @@
         "click", this.clickOnMeta.bind(this), false
       );
 
-      this._fragment = vcFragmentClass.create();
+      this._fragment = vcFragmentClass.create();      
+
+      this._fragment.element().addEventListener(
+        "click", this.toVcBuilder.bind(this), true
+      );
 
       return this;
     },
 
+    /**
+     * Join fragment with VC
+     */
+    toVcBuilder : function (e) {
+      if (e)
+        e.stopPropagation();
+
+      if (this._fragment.isEmpty())
+        return;
+
+      let vc = KorAP.vc;
+      if (!vc) {
+        console.log("Global VC not established");
+        return;
+      };
+
+      for (let doc of this._fragment.documents()) {
+        vc.addRequired(doc);
+        console.log("Add " + doc.toQuery());
+      };
+
+      if (!vc.isOpen()) {
+        vc.open();
+      };
+
+      // Scroll to top
+      window.scrollTo(0, 0);
+    },
+
+    // Event handler for meta constraint creation
     clickOnMeta : function (e) {
       e.stopPropagation();
       if (e.target === e.currentTarget) {
@@ -65,16 +99,16 @@
         return;
 
       type = type || "type:string";
-      
+
       // Add or remove the constraint to the fragment
       if (key && value) {
         if (target.classList.contains("chosen")) {
           target.classList.remove("chosen");
-          this._fragment.remove(key, value);
+          this.remove(key, value);
         }
         else {
           target.classList.add("chosen");
-          this._fragment.add(key, value);
+          this.add(key, value, type);
         };
 
         // Check if the fragment is empty
@@ -95,6 +129,17 @@
       }
     },
 
+    // Add constraint
+    add : function (key, value, type) {
+      type = type.replace(/^type:/, '');
+      this._fragment.add(key, value, type);
+    },
+
+    // Remove constraint
+    remove : function (key, value) {
+      this._fragment.remove(key, value);
+    },
+    
     // Stringify annotation
     toQuery : function () {
       return this._fragment.toQuery();
diff --git a/dev/js/src/vc/fragment.js b/dev/js/src/vc/fragment.js
index a03e845..2d2504d 100644
--- a/dev/js/src/vc/fragment.js
+++ b/dev/js/src/vc/fragment.js
@@ -6,7 +6,7 @@
  * @author Nils Diewald
  */
 
-define(['util'], function () {
+define(['vc/doc', 'util'], function (docClass) {
   "use strict";
 
   const loc = KorAP.Locale;
@@ -72,6 +72,7 @@
       return;
     },
 
+
     /**
      * Check, if the fragment contains any constraints
      */
@@ -79,12 +80,6 @@
       return this._operands.length > 0 ? false : true;
     },
     
-    /**
-     * Add fragment constraints to VC.
-     */
-    mergeWithVC : function () {
-    },
-
 
     /**
      * Get the element associated with the virtual corpus
@@ -107,6 +102,27 @@
 
 
     /**
+     * Return operands as document objects
+     */
+    documents : function () {
+      return this._operands.map(
+        function (item) {
+          let doc = docClass.create();
+          doc.key(item[0]);
+          doc.matchop("eq");
+          doc.value(item[1]);
+          if (item[2] === "date") {
+            doc.type("date");
+          }
+          else {
+            doc.type("string");
+          };
+          return doc;
+        }
+      );
+    },
+
+    /**
      * Update the whole object based on the underlying data structure
      */
     update : function() {
@@ -147,17 +163,22 @@
       return this;
     },
 
+    
+    /**
+     * Stringification
+     */
     toQuery : function () {
       if (this._operands.length === 0)
         return '';
 
-      let str = '(' + this._operands.map(
+      return this._operands.map(
         function (item) {
+          if (item[2] === "date") {
+            return item[0] + ' in ' + item[1];
+          };
           return item[0] + ' = "' + new String(item[1]).quote() + '"';
         }
       ).join(" & ");
-      
-      return str + ')';
     }
   }
 });