Mercurial > wikked
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>