isnowfy / simple

A static blog generator with a single static page
http://isnowfy.github.io/simple/
MIT License
911 stars 661 forks source link

Contribution: Searching function #21

Open ghost opened 8 years ago

ghost commented 8 years ago

Hello,

Saw that you wanted to add searching function to your project and decided to contribute a code that I use in my blog.

Test page (index.html), online demo here or just type something in my blog search form.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
    <title>Zearch</title>

    <!-- Bootstrap -->
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet">

    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
    <!--[if lt IE 9]>
      <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
      <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
  </head>
  <body>

    <div class="container">
      <div id="content">
        <div class="row">
          <div class="page-content col-md-6 col-sm-8">

            <h1>Type L</h1>
            <form>
              <div class="input-group custom-search-form">
                <input type="text" id="uzer-infut" class="form-control" placeholder="Ask me anything">
              </div>
            </form>

            <div id="queryMe"></div>

          </div><!--/.page-content-->
        </div><!--/.row-->
      </div><!--/.content-->
    </div><!--/.container-->

  <script defer src="search.js"></script>
  <script defer src="tmpl.min.js"></script>

  </body>
</html>

You must have https://github.com/blueimp/JavaScript-Templates installed (npm install; npm run build)

search.js

(function() {
    'use strict';

    var nothingFoundTemplate = [
        "<hr>",
            "<div class='alert alert-info'>Nothing found.</div>",
        "<hr>"
    ].join(''),
    searchTemplate = [
        "{% for (var x=0; x < o.length; x++) { %}",
            "<div class='page-header'>",
                "<h4>",
                    "<a href='{%=o[x][1]%}' class='text-muted'>",
                        "{%=o[x][0]%}",
                    "</a>",
                "</h4>",
            "</div>",
        "{% } %}"
    ].join(''),
    entries = [
            //  title     url
            ['Lorem', 'http://ex0.com'],
            ['Little Joe', 'http://ex1.com'],
            ['ipsum', 'http://ex2.com'],
            ['next', 'http://ex3.com'],
            ['generation', 'http://ex4.com'],
            ['old', 'http://ex5.com'],
            ['school', 'http://ex6.com']
    ];

    var innerData = function(partialTemplate, data, id) {
        var template = document.createElement('div'),
            container = document.querySelector('#' + id);
        while (container.firstChild) {
            container.removeChild(container.firstChild);
        }
        template.innerHTML = tmpl(partialTemplate, data);
        container.appendChild(template);
    };
    var invokeSearch = function() {
        var x,
            arr = [],
            foundPosts = false,
            uzerQuery = document.getElementById('uzer-infut').value.toLowerCase();

        if (uzerQuery === '') {
            innerData(nothingFoundTemplate, arr, 'queryMe');
            return false;
        }

        entries.forEach(function(entry) {
            if (entry[0].toLowerCase().match(uzerQuery)) {
                arr.push(entry);
                foundPosts = true;
            }
        });
        innerData(foundPosts ? searchTemplate :
                nothingFoundTemplate, arr, 'queryMe');
    };
    document.getElementById('uzer-infut').addEventListener('input', invokeSearch, false);
}());

Every key stroke will trigger the search function, thus making it interactive without the need from the user to click any submit buttons (especially useful on mobile devices).

3 days later: replaced the entries objects with arrays instead.

isnowfy commented 8 years ago

That's pretty cool, and I will add the search function later Thanks.

ghost commented 8 years ago

I'm glad that you liked it. If you want to detect the visitor operating system, here's the code and working demo - https://jsfiddle.net/3mqtuy0r/

Add the following span in any html page.

<span id='detect-os'></span>

The script:

(function() {
    'use strict';
    var detect =
    {
        mobile:  ['Android', 'iPhone', 'iPod', 'iPad', 'Symbian', 'Windows Phone', 'BlackBerry'],

        shorter: ['Linux', 'Free', 'Open', 'NetBSD', 'BSD', 'Mac',
                  'Win', 'Sun', 'HP', 'Play', 'Web', 'QNX', 'BeOS', 'X11', 'OS/2'],

        longer:  ['Linux', 'FreeBSD', 'OpenBSD', 'NetBSD', 'BSD', 'Macintosh',
                  'Windows', 'SunOS', 'Hewlett-Packard', 'PlayStation',
                  'WebTV OS', 'QNX', 'BeOS', 'UNIX', 'OS/2'],

        foundOS: 'unknown',
        itsmobile: navigator.userAgent.match(/(Android)|(iPod)|(iPad)|(Symbian)|(Phone)|(BlackBerry)/i),

        findOS: function(arr, os, mobile_bool) {
            var x = arr.length;
            while (x--) {
                if (os.indexOf(arr[x]) !== -1)
                {
                    detect.foundOS = (mobile_bool ? arr[x] : detect.longer[x]);
                    break;
                }
            }
        }
    };

    if (detect.itsmobile) {
        detect.findOS(detect.mobile, navigator.userAgent, true);
    } else {
        detect.findOS(detect.shorter, navigator.platform, false);
    }

    document.getElementById('detect-os').textContent = detect.foundOS;
}());

You can combine both javascripts in one file instead. Copy search.js and add it above/below this example.