Implemented search. * Closes #16;
h3rald h3rald@h3rald.com
Sat, 21 Mar 2015 21:59:29 +0100
9 files changed,
194 insertions(+),
14 deletions(-)
M
app/index.html
→
app/index.html
@@ -38,6 +38,7 @@ <script src="js/modules/info.js"> </script>
<script src="js/modules/tags.js"> </script> <script src="js/modules/guide.js"> </script> <script src="js/modules/document.js"> </script> + <script src="js/modules/search.js"> </script> <script src="js/app.js"> </script> </body> </html>
M
app/js/app.js
→
app/js/app.js
@@ -11,6 +11,7 @@ '/info': app.info,
"/tags/:id": app.tags, "/document/:action/:id...": app.document, "/guide/:id": app.guide, - "/new": app.create + "/new": app.create, + "/search": app.search }); }());
M
app/js/models.js
→
app/js/models.js
@@ -29,6 +29,16 @@ url: "/v1/docs?contents=false&tags="+tag
}).then(docs); }; + Doc.search = function(search, offset, limit){ + offset = offset || 0; + limit = limit || 10; + var docs = m.prop(""); + return m.request({ + method: "GET", + url: "/v1/docs?contents=false&search="+search+"&limit="+limit+"&offset="+offset, + }).then(docs); + }; + Doc.get = function(id) { var doc = m.prop(""); return m.request({
A
app/js/modules/search.js
@@ -0,0 +1,50 @@
+(function(){ + 'use strict'; + var app = window.LS || (window.LS = {}); + var u = LS.utils; + + // Search Module + app.search = {vm: {}}; + app.search.vm.init = function(){ + var vm = this; + vm.query = m.route.param("q"); + vm.offset = m.route.param("offset") || 0; + vm.limit = m.route.param("limit") || 10; + vm.result = m.prop({total: 0, results: []}); + vm.total = 0; + Doc.search(vm.query, vm.offset, vm.limit).then(function(result){ + vm.result(result); + vm.total = result.total; + }, vm.flashError); + }; + app.search.main = function(){ + var vm = app.search.vm; + var result = vm.result(); + var title = m("h2.col-md-12", ["You searched for: ", m("em", vm.query)]); + var total = m("p.col-md-12", [m("strong", result.total), " hits"]); + var resultPanel = function(res){ + var obj = {}; + obj.title = res.id; + obj.content = m("div", [ + m("p", ["Created on: ", u.date(res.created)]), + m("p", res.tags.map(function(tag){ + return u.taglink(tag); + })) + ] + ); + return m(".row.search-result", m(".col-md-12", [u.panel(obj)])); + }; + var results = m(".row", [m(".col-md-12", result.results.map(resultPanel))]); + + return m("section", [ + m(".row", title), + m(".row", total), + m(".row.text-center", [u.paginator(vm)]), + results, + m(".row.text-center", [u.paginator(vm)]) + ]); + }; + + u.layout(app.search); + +}());
M
app/js/utils.js
→
app/js/utils.js
@@ -39,15 +39,79 @@ };
}; u.panel = function(obj){ + var title = ""; + var footer = ""; + if (obj.title){ + title = m(".panel-heading", [ + m("h2.panel-title", [obj.title]) + ]); + } + if (obj.footer){ + footer = m(".panel-footer", obj.footer); + } return m(".panel.panel-default", [ - m(".panel-heading", [ - m("h2.panel-title", [obj.title]) - ]), + title, m(".panel-body", [ obj.content - ]) + ]), + footer ]); }; + + /** + * - total + * - limit + * - offset + * - query + */ + u.paginator = function(obj) { + var max_page = Math.ceil(obj.total/obj.limit)-1; + var c_page = Math.ceil(obj.offset/obj.limit); + var page = function(n, sign, disabled){ + var klass; + if (disabled) { + klass = "disabled"; + } else { + klass = (n === c_page) ? "active" : "inactive"; + } + var first = (n === 0); + var last = (n == max_page); + var offset = obj.limit * n; + sign = sign || n+1; + return m("li", {class: klass}, + [m("a", { + href: "/search?q="+obj.query+"&offset="+offset+"&limit="+obj.limit, + config: m.route + }, [m.trust(sign)] + )] + ); + }; + var pages = []; + var prev; + var next; + for (var i=0; i<=max_page; i++){ + var p; + switch(i){ + case c_page-1: + prev = page(i, "«"); + break; + case c_page+1: + next = page(i, "»"); + break; + } + if (c_page === 0){ + prev = page(0, "«", true); + } + if (c_page === max_page){ + next = page(max_page, "»", true); + } + pages.push(page(i)); + } + pages.unshift(prev); + pages.push(next); + return m("nav", [m("ul.pagination", pages)]); + }; + u.dropdown = function(obj) { var el = "li.dropdown"; var icon = (obj.icon) ? m("i.fa."+obj.icon) : "";@@ -113,4 +177,5 @@ return function(xhr) {
xhr.setRequestHeader("Content-Type", contentType); }; }; +}());}; }());
M
app/styles/elements.less
→
app/styles/elements.less
@@ -141,5 +141,8 @@ }
} .toolbar { - margin: 4px 0; + margin: 5px 0; } +.search-result { + margin: 5px 0; +}
M
app/styles/litestore.css
→
app/styles/litestore.css
@@ -1882,7 +1882,10 @@ color: #fff;
text-decoration: none; } .toolbar { - margin: 4px 0; + margin: 5px 0; +} +.search-result { + margin: 5px 0; } .note { -moz-background-clip: padding;@@ -2682,4 +2685,4 @@ font-weight: normal;
font-size: 100%; color: #00cc33; content: "\f058" " "; -} +}