summaryrefslogtreecommitdiff
path: root/html/search-v2.html
diff options
context:
space:
mode:
Diffstat (limited to 'html/search-v2.html')
-rw-r--r--html/search-v2.html336
1 files changed, 0 insertions, 336 deletions
diff --git a/html/search-v2.html b/html/search-v2.html
deleted file mode 100644
index 100565b..0000000
--- a/html/search-v2.html
+++ /dev/null
@@ -1,336 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
- <head>
- <meta charset="utf-8">
-
- <style>
-body { font-family: 'Cantarell', Helvetica, Arial, sans-serif; }
-
-.twitter-typeahead { width: 87% ;}
-.typeahead, .tt-query, .tt-hint {
- width: 100%; height: 30px;
- padding: 8px 12px; outline: none;
- font-size: 20px; line-height: 30px;
- border: 2px solid #ccc; border-radius: 8px;
- -webkit-border-radius: 8px;
- -moz-border-radius: 8px;
-}
-.tt-menu {
- width: 100%; margin: 12px 0; padding: 8px 0;
- background-color: #fff;
- border: 1px solid #ccc; border-radius: 8px;
- -webkit-border-radius: 8px;
- -moz-border-radius: 8px;
- -webkit-box-shadow: 0 5px 10px rgba(0,0,0,.2);
- -moz-box-shadow: 0 5px 10px rgba(0,0,0,.2);
- box-shadow: 0 5px 10px rgba(0,0,0,.2);
-}
-.tt-suggestion { padding: 3px 20px; line-height: 24px; font-size: 18px; }
-.tt-suggestion span { padding-left: 16px; font-size: 14px; color: #777; float: right; }
-.tt-cursor { background: #ddd; }
-.tt-highlight { font-weight: normal; color: #777; }
-
-#selections { width: 87%; padding-top: 40px; }
-#selections div { padding: 4px 40px; line-height: 24px; font-size: 18px; color: #666; }
-#selections div span { padding-left: 16px; font-size: 14px; color: #999; float: right; }
- </style>
-
- <!-- js labraries -->
- <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
- <script src="https://cdnjs.cloudflare.com/ajax/libs/corejs-typeahead/1.2.1/bloodhound.min.js"></script>
- <script src="https://cdnjs.cloudflare.com/ajax/libs/corejs-typeahead/1.2.1/typeahead.jquery.min.js"></script>
- </head>
- <body>
-
- <div id="the-basics">
- <input class="typeahead" id="tagsInput" type="text" placeholder="try me!">
- </div>
-
- <div id="selections">
- </div>
-
- </body>
- <script>
-
-// arrays for kb-format (utf/EL-Gr to ascii translation)
-var ORiGiN = 'ςερτυθιοπασδφγηξκλζχψωβνμΕΡΤΥΘΙΟΠΑΣΔΦΓΗΞΚΛΖΧΨΩΒΝΜάέήίόύώϊϋΆΈΉΊΌΎΏΪΫQWERTYUIOPASDFGHJKLZXCVBNM'.split('');
-var kbKeyZ = 'sertyuiopasdfghjklzxcvbnmertyuiopasdfghjklzxcvbnmaehioyviyaehioyviyqwertyuiopasdfghjklzxcvbnm'.split('');
-
-// convert string to kb-format
-function kb_trans(s) {
- var charArr = s.split('')
- var i
- var out = ''
- charArr.forEach( el => {
- i = 0
- exist = -1
- ORiGiN.forEach( ori => {
- if (ori == el) {
- exist = i;
- }
- i++;
- })
- out += (exist == -1) ? el : kbKeyZ[exist];
- });
- return out;
-}
-
-// public data objects
-var products;
-var everyProduct;
-
-function loadData() {
- const xhttp = new XMLHttpRequest();
- xhttp.onload = function() {
- products = JSON.parse(this.responseText);
- }
- xhttp.open("GET", "results/keywords-v3.json");
- xhttp.send();
-}
-loadData();
-
-function loadData2() {
- const xhttp = new XMLHttpRequest();
- xhttp.onload = function() {
- everyProduct = JSON.parse(this.responseText);
- }
- xhttp.open("GET", "results/products.json");
- xhttp.send();
-}
-loadData2();
-
-// bigram fuzzy match
-// --- credit: https://dirask.com/posts/JavaScript-check-words-similarity-fuzzy-compare-with-bigrams-paola1
-const createBigram = word => {
- const input = word.toLowerCase();
- const vector = [];
- for (let i = 0; i < input.length; ++i) {
- vector.push(input.slice(i, i + 2));
- }
- return vector;
-};
-const checkSimilarity = (a, b) => {
- if (a.length > 0 && b.length > 0) {
- const aBigram = createBigram(a);
- const bBigram = createBigram(b);
- let hits = 0;
- for (let x = 0; x < aBigram.length; ++x) {
- for (let y = 0; y < bBigram.length; ++y) {
- if (aBigram[x] === bBigram[y]) {
- hits += 1;
- }
- }
- }
- if (hits > 0) {
- const union = aBigram.length + bBigram.length;
- return (2.0 * hits) / union;
- }
- }
- return 0;
-};
-var bi_1st = .6; // bigram minimum match score for 1st word
-var bi_2nd = .8; // bigram minimum match score for 2nd word
-
-// on document ready code /////////////////////////////////////////////////////
-$(document).ready(function() {
-
- // suggestions engine ////////////////////////////////////////////////////
- // ---
- function suggestions_engine(qOrig) {
- var results = []; // suggestions to respond
- var proList = []; // list of products (for all suggestions)
- var commonL = []; // list of common products (for multiple suggestions)
- var possibleNext = []; // list of possible next suggestions
-
- var root, last;
-
- // clean q(uery) string from symbols and multiple spaces
- var q = qOrig.replace('+',' ').replace('.',' ')
- .replace(' ',' ')
- .replace(' ',' ');
-
- var qAr = q.split(' '); // split to words
-
- if (qAr.length == 1) { // suggest 1st word ////////////////////////
- var kbq = kb_trans(q)
- // regex match all possible suggestions; (in kb-format)
- substrRegex = new RegExp( kbq, 'i'); // match q anywhere
- products.forEach( it => {
- if ( (substrRegex.test(it.kb))
- || (checkSimilarity(it.kb, kbq) > bi_1st) ) {
- results.push(it);
- }
- });
- }
-
- if (qAr.length == 2) { // suggest 2nd word ///////////////////////////
- root = qAr[0].trim();
- kbroot = kb_trans(root);
-
- substrRegex = new RegExp( kb_trans(qAr[1]), 'i');
-
- products.forEach( it => { // loop through suggestions
- if (it.kb == kbroot ) { // match 1st suggestion
- it.c.forEach ( wo => { // regex match linked words
- if ( (substrRegex.test(wo.kb))
- || (checkSimilarity(wo.kb, kbroot) > bi_2nd) ) {
- results.push({
- w: root +' '+ wo.w,
- f: 100
- });
- proList = proList.concat(wo.p)
- }
- });
- }
- });
- }
-
- if (qAr.length > 2) {
- root = qAr.shift(); // get out the first item of qAr
- last = qAr.pop(); // get out the lase item of qAr
- // now qAr includes only the items after root and before last;
- // so qAr includes all already selected suggestions (but root)
-
- var kbqAr = []; // array of selected suggestions in kb-format
- qAr.forEach( w => { kbqAr.push(kb_trans(w)); })
-
- // kb-translate the root/last keys
- kbroot = kb_trans(root);
- kblast = kb_trans(last);
-
- substrRegex = new RegExp( kblast, 'i'); // construct regex for mathing
-
- products.forEach( it => {
- if (it.kb == kbroot ) { // find root
-
- // calculate list of common items/products (commonL)
- // for selected suggestions
- // ---
- is1stOcc = true; // 1st occurance flag
- it.c.forEach ( swo => {
- if (kbqAr.includes( swo.kb )) {
- // swo is one of the already selected suggestions
- // so...
- // update the commonL(ist)
- if (is1stOcc) {
- commonL = swo.p;
- is1stOcc = false;
- }
- else {
- // list ot common products
- // = intersection of (so-far) commonL and swo.p
- commonL = commonL.filter(value => swo.p.includes(value));
- }
- }
- else { // if swo is not already selected
- // then it is a possible next suggestion
- possibleNext.push(swo);
- }
- });
- // console.log('commonL:', commonL)
-
- possibleNext.forEach( poss => { // for tthe possible next suggestions
- // if word matches regex
- // and list of word's products has commons with commonL
- // then it is a valid next suggestion
- if (substrRegex.test(poss.kb)) {
- // check intersection of commonL and suggestion's product-lists
- tempL = commonL.filter(value => poss.p.includes(value));
- if (tempL.length) {
- results.push({
- w: root +' '+ qAr.join(' ') +' '+ poss.w,
- f: 100
- });
- // update proList too
- proList = proList.concat(tempL)
- }
- }
- });
- }
-
- });
- }
-
-
- if ((qAr.length != 1) && (proList.length < 13)) {
- // get unique product ids
- let unique = proList.filter((item, i, ar) => ar.indexOf(item) === i);
- // credit: https://stackoverflow.com/questions/11246758/
-
- results = [];
- unique.forEach( pr => {
- everyProduct.forEach( pi => {
- if (pi.id == pr)
- results.push(pi);
- })
- });
- }
- return results;
- }
-
- var isuggest = function(qOrig, list) {
- var results = suggestions_engine(qOrig);
- if (results.length == 0) {
- var qAr = qOrig.trim().split(' ');
- qAr.pop(); // remove last word
- results = suggestions_engine(qAr.join(' '));
- }
- list(results);
- }
-
- // setup suggestions search/input control
- // ---
- const $tagsInput = $('#tagsInput')
- $tagsInput.typeahead(
- {
- hint: true,
- highlight: true,
- minLength: 1
- },
- {
- limit: 12,
- name: 'products',
- displayKey: 'w',
- source: isuggest,
- templates: {
- suggestion: function(data) {
- // console.log(data.w);
- if (data.id)
- return '<div>'+ data.w + '<span>' + data.id + '</span></div>';
- return '<div>'+ data.w +'</div>';
- }
- }
- }
- )
- .bind("typeahead:selected", function(obj, datum, name) {
- console.log(datum);
- if (datum.hasOwnProperty('id')) {
- // final product selected; do whatever ...
- // ex. add to selection list
- $('#selections').append('<div>'+ datum.w + '<span>' + datum.id + '</span></div>');
-
- // then reset search control
- $('.typeahead').typeahead('val','').trigger('blur')
- .trigger("query");
- setTimeout(() => { $('.typeahead').focus(); }, 100);
- }
- else {
- $('.typeahead').typeahead('val','').trigger('blur');
- $('.typeahead').typeahead('val', datum.w +' ')
- .trigger("query");
- // give some time to the engine to calculate results
- // then fire focus again...
- setTimeout(() => { $('.typeahead').focus(); }, 100);
- }
- })
- .bind("typeahead:cursorchange", function(obj, data) {
- // console.log(obj, data);
- // var dt = new Date();
- // console.log('triggered cursorchange /'+dt);
- });
-
-
-
-});
- </script>
-</html>