changeset 16:8d6c2a5ed08d

Added instant search results preview.
author Ludovic Chabant <ludovic@chabant.com>
date Mon, 31 Dec 2012 22:02:39 -0800
parents 238299b93f4c
children 8a4e0fe2c689
files wikked/static/css/wikked.less wikked/static/js/wikked/models.js wikked/static/js/wikked/views.js wikked/static/tpl/search-results.html
diffstat 4 files changed, 79 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/wikked/static/css/wikked.less	Sun Dec 30 23:15:32 2012 -0800
+++ b/wikked/static/css/wikked.less	Mon Dec 31 22:02:39 2012 -0800
@@ -80,6 +80,10 @@
     margin-top: @baseLineHeight;
     margin-bottom: 0;
 }
+pre {
+    margin-top: @baseLineHeight;
+    margin-bottom: @baseLineHeight;
+}
 sup, sub {
     line-height: 0;
 }
@@ -145,6 +149,10 @@
     display: inline-block;
     margin: 0;
 }
+ul.search-results {
+    list-style: none;
+}
+
 form.page-edit {
     textarea {
         height: 10em;
@@ -202,3 +210,8 @@
     margin-top: 1em;
     margin-bottom: 1em;
 }
+
+b.match {
+    padding: 0 0.2em;
+    background: #ffeb84;
+}
--- a/wikked/static/js/wikked/models.js	Sun Dec 30 23:15:32 2012 -0800
+++ b/wikked/static/js/wikked/models.js	Mon Dec 31 22:02:39 2012 -0800
@@ -30,6 +30,21 @@
             this._onChangeAuth(this.get('auth'));
             return this;
         },
+        doPreviewSearch: function(query, callback) {
+            if (this._isSearching) {
+                return;
+            }
+            this._isSearching = true;
+            var $model = this;
+            $.getJSON('/api/search', { q: query })
+                .success(function (data) {
+                    $model._isSearching = false;
+                    callback(data);
+                })
+                .error(function() {
+                    $model._isSearching = false;
+                });
+        },
         doSearch: function(form) {
             this.app.navigate('/search/' + $(form.q).val(), { trigger: true });
         },
@@ -40,6 +55,7 @@
             this.set('url_hist', '/#/changes/' + path);
             this.set('url_search', '/search');
         },
+        _isSearching: false,
         _onChangeAuth: function(auth) {
             if (auth) {
                 this.set('url_login', false);
--- a/wikked/static/js/wikked/views.js	Sun Dec 30 23:15:32 2012 -0800
+++ b/wikked/static/js/wikked/views.js	Mon Dec 31 22:02:39 2012 -0800
@@ -64,6 +64,45 @@
                 model.doSearch(this);
                 return false;
             });
+            var $view = this;
+            Util.TemplateLoader.get('search-results', function(src) {
+                var template = Handlebars.compile(src);
+                var origPageEl = $('#app .page');
+
+                $view.$('#search .search-query')
+                    .on('input', function() {
+                        var curPreviewEl = $('#app .page[class~="preview-search-results"]');
+
+                        // Restore the original content if the query is now
+                        // empty. Otherwise, run a search and render only the
+                        // `.page` portion of the results page.
+                        var query = $(this).val();
+                        if (query && query.length > 0) {
+                            model.doPreviewSearch(query, function(data) {
+                                data.is_instant = true;
+                                var resultList = $(template(data));
+                                var inner = $('.page', resultList)
+                                    .addClass('preview-search-results')
+                                    .detach();
+                                if (origPageEl.is(':visible')) {
+                                    inner.insertAfter(origPageEl);
+                                    origPageEl.hide();
+                                } else {
+                                    curPreviewEl.replaceWith(inner);
+                                }
+                            });
+                        } else {
+                            curPreviewEl.remove();
+                            origPageEl.show();
+                        }
+                    })
+                    .keyup(function(e) {
+                        if (e.keyCode == 27) {
+                            // Clear search on `Esc`.
+                            $(this).val('').trigger('input');
+                        }
+                    });
+            });
         }
     });
 
--- a/wikked/static/tpl/search-results.html	Sun Dec 30 23:15:32 2012 -0800
+++ b/wikked/static/tpl/search-results.html	Mon Dec 31 22:02:39 2012 -0800
@@ -1,10 +1,20 @@
 <article class="row">
     <div class="page span12">
         <h1>Search Results</h1>
+        {{#if is_instant}}
+        <p><small>Press <code>Escape</code> to cancel.</small></p>
+        {{/if}}
+        {{#if hits}}
         <ul class="search-results">
             {{#each hits}}
-            <li><a href="/#/read/{{url}}">{{title}}</a></li>
+            <li>
+            <h3><a href="/#/read/{{url}}">{{title}}</a></h3>
+            <div class="highlighted"><pre><code>{{{content_highlights}}}</code></pre></div>
+            </li>
             {{/each}}
         </ul>
+        {{else}}
+        <p>No matches found.</p>
+        {{/if}}
     </div>
 </article>