Skip to content

Commit

Permalink
Livesearch result renders to content, remove typeahead
Browse files Browse the repository at this point in the history
  • Loading branch information
rnixx committed May 29, 2024
1 parent 0702999 commit c17760b
Show file tree
Hide file tree
Showing 11 changed files with 121 additions and 2,742 deletions.
3 changes: 2 additions & 1 deletion TODO.rst
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
TODO
====

- Live search.
- Main menu display children.
- Custom root node in example.
- Referencebrowser widget.
- Treibstoff styles.
- Yafowil bootstrap 5 styles.
Expand Down
3 changes: 2 additions & 1 deletion examples/cone.example/src/cone/example/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,7 @@ def search(self, request, query):
result.append({
'value': md.title,
'target': make_url(request, node=child),
'icon': md.icon
'icon': md.icon,
'description': md.description,
})
return result
96 changes: 51 additions & 45 deletions js/src/livesearch.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,8 @@ export class LiveSearch {
constructor(elem) {
this.elem = elem;
this.target = `${elem.data('search-target')}/livesearch`;
this.result = $('<ul />')
.attr('id', 'livesearch-result')
.attr('class', 'dropdown-menu')
.insertAfter(elem.parents('.input-group'));
this.content = $('#content');
this.result = null;

this._term = '';
this._minlen = 3;
Expand All @@ -31,30 +29,9 @@ export class LiveSearch {
this.on_keydown = this.on_keydown.bind(this);
this.on_change = this.on_change.bind(this);
this.on_result = this.on_result.bind(this);
this.on_select = this.on_select.bind(this);

elem.on('keydown', this.on_keydown);
elem.on('change', this.on_change);

// let source = new Bloodhound({
// datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'),
// queryTokenizer: Bloodhound.tokenizers.whitespace,
// remote: 'livesearch?term=%QUERY'
// });
// source.initialize();
// this.render_suggestion = this.render_suggestion.bind(this);
// elem.typeahead(null, {
// name: 'livesearch',
// displayKey: 'value',
// source: source.ttAdapter(),
// templates: {
// suggestion: this.render_suggestion,
// empty: '<div class="empty-message">No search results</div>'
// }
// });
// this.on_select = this.on_select.bind(this);
// let event = 'typeahead:selected';
// elem.off(event).on(event, this.on_select);
}

search() {
Expand All @@ -68,6 +45,55 @@ export class LiveSearch {
this._in_progress = false;
}

render_no_results() {
ts.compile_template(this, `
<h5 class="card-title">No search results</h5>
`, this.result);
}

render_suggestion(item) {
ts.compile_template(this, `
<div class="mb-4">
<h5 class="card-title">
<a href="${item.target}"
ajax:bind="click"
ajax:event="contextchanged:#layout"
ajax:target="${item.target}">
<i class="${item.icon}"></i>
${item.value}
</a>
</h5>
<p class="card-text">
${item.description === undefined ? '' : item.description}
</p>
</div>
`, this.result);
}

on_result(data, status, request) {
this.content.empty();
ts.compile_template(this, `
<div class="card mt-2">
<div class="card-body" t-elem="result">
<h3 class="card-title mb-3">Search results for "${this._term}"</h3>
</div>
</div>
`, this.content);
if (!data.length) {
this.render_no_results();
} else {
ts.compile_template(this, `
<p class="card-text mb-3">
<span>${data.length} Results</span>
</p>
`, this.result);
for (const item of data) {
this.render_suggestion(item);
}
}
this.result.tsajax();
}

on_keydown(evt) {
if (evt.keyCode === 13) {
return;
Expand Down Expand Up @@ -99,24 +125,4 @@ export class LiveSearch {
this.search();
}, this._delay);
}

on_result(data, status, request) {
console.log(data);
}

on_select(evt, suggestion, dataset) {
if (!suggestion.target) {
console.log('No suggestion target defined.');
return;
}
ts.ajax.trigger(
'contextchanged',
'#layout',
suggestion.target
);
}

render_suggestion(suggestion) {
return `<span class="${suggestion.icon}"></span>${suggestion.value}`;
}
}
9 changes: 0 additions & 9 deletions src/cone/app/browser/ajax.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from cone.app.browser.actions import ActionContext
from cone.app.browser.utils import bdajax_warning
from cone.app.browser.utils import format_traceback
from cone.app.interfaces import ILiveSearch
from cone.tile import render_tile
from node.utils import safe_encode
from pyramid.exceptions import Forbidden
Expand Down Expand Up @@ -363,11 +362,3 @@ def render_ajax_form(model, request, name):
error='true'
)
return Response(rendered)


@view_config(name='livesearch', accept='application/json', renderer='json')
def livesearch(model, request):
adapter = request.registry.queryAdapter(model, ILiveSearch)
if not adapter:
return list()
return adapter.search(request, request.params['term'])
6 changes: 0 additions & 6 deletions src/cone/app/browser/layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,6 @@ class LogoTile(Tile):
"""


@tile(name='livesearch', path='templates/livesearch.pt', permission='login')
class LivesearchTile(Tile):
"""Tile rendering the live search.
"""


@tile(name='colortoggler', path='templates/colortoggler.pt', permission='login')
class ColorTogglerTile(Tile):
"""Tile rendering the color mode toggler.
Expand Down
17 changes: 0 additions & 17 deletions src/cone/app/browser/resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,22 +59,6 @@
compressed='bootstrap-icons.min.css'
))

# typeahead
typeahead_resources = wr.ResourceGroup(
name='cone.app-typeahead',
directory=os.path.join(resources_dir, 'typeahead'),
path='typeahead'
)
# typeahead_resources.add(wr.ScriptResource(
# name='typeahead-js',
# depends='jquery-js',
# resource='typeahead.bundle.js'
# ))
# typeahead_resources.add(wr.StyleResource(
# name='typeahead-css',
# resource='typeahead.css'
# ))

# cone
cone_resources = wr.ResourceGroup(
name='cone.app-cone',
Expand Down Expand Up @@ -151,7 +135,6 @@ def initialize(cls, config, settings):
# register default resources
config.register_resource(jquery_resources)
config.register_resource(bootstrap_resources)
config.register_resource(typeahead_resources)
config.register_resource(cone_resources)

def register_resource(self, config, resource):
Expand Down
17 changes: 17 additions & 0 deletions src/cone/app/browser/search.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from cone.app.interfaces import ILiveSearch
from cone.tile import tile
from cone.tile import Tile
from pyramid.view import view_config


@tile(name='livesearch', path='templates/livesearch.pt', permission='login')
class LivesearchTile(Tile):
"""Tile rendering the live search."""


@view_config(name='livesearch', accept='application/json', renderer='json')
def livesearch(model, request):
adapter = request.registry.queryAdapter(model, ILiveSearch)
if not adapter:
return list()
return adapter.search(request, request.params['term'])
70 changes: 48 additions & 22 deletions src/cone/app/browser/static/cone/cone.app.js
Original file line number Diff line number Diff line change
Expand Up @@ -319,10 +319,8 @@ var cone = (function (exports, $, ts) {
constructor(elem) {
this.elem = elem;
this.target = `${elem.data('search-target')}/livesearch`;
this.result = $('<ul />')
.attr('id', 'livesearch-result')
.attr('class', 'dropdown-menu')
.insertAfter(elem.parents('.input-group'));
this.content = $('#content');
this.result = null;
this._term = '';
this._minlen = 3;
this._delay = 250;
Expand All @@ -331,7 +329,6 @@ var cone = (function (exports, $, ts) {
this.on_keydown = this.on_keydown.bind(this);
this.on_change = this.on_change.bind(this);
this.on_result = this.on_result.bind(this);
this.on_select = this.on_select.bind(this);
elem.on('keydown', this.on_keydown);
elem.on('change', this.on_change);
}
Expand All @@ -345,6 +342,52 @@ var cone = (function (exports, $, ts) {
});
this._in_progress = false;
}
render_no_results() {
ts.compile_template(this, `
<h5 class="card-title">No search results</h5>
`, this.result);
}
render_suggestion(item) {
ts.compile_template(this, `
<div class="mb-4">
<h5 class="card-title">
<a href="${item.target}"
ajax:bind="click"
ajax:event="contextchanged:#layout"
ajax:target="${item.target}">
<i class="${item.icon}"></i>
${item.value}
</a>
</h5>
<p class="card-text">
${item.description === undefined ? '' : item.description}
</p>
</div>
`, this.result);
}
on_result(data, status, request) {
this.content.empty();
ts.compile_template(this, `
<div class="card mt-2">
<div class="card-body" t-elem="result">
<h3 class="card-title mb-3">Search results for "${this._term}"</h3>
</div>
</div>
`, this.content);
if (!data.length) {
this.render_no_results();
} else {
ts.compile_template(this, `
<p class="card-text mb-3">
<span>${data.length} Results</span>
</p>
`, this.result);
for (const item of data) {
this.render_suggestion(item);
}
}
this.result.tsajax();
}
on_keydown(evt) {
if (evt.keyCode === 13) {
return;
Expand Down Expand Up @@ -375,23 +418,6 @@ var cone = (function (exports, $, ts) {
this.search();
}, this._delay);
}
on_result(data, status, request) {
console.log(data);
}
on_select(evt, suggestion, dataset) {
if (!suggestion.target) {
console.log('No suggestion target defined.');
return;
}
ts.ajax.trigger(
'contextchanged',
'#layout',
suggestion.target
);
}
render_suggestion(suggestion) {
return `<span class="${suggestion.icon}"></span>${suggestion.value}`;
}
}

class GlobalEvents extends ts.Events {
Expand Down
2 changes: 1 addition & 1 deletion src/cone/app/browser/static/cone/cone.app.min.js

Large diffs are not rendered by default.

Loading

0 comments on commit c17760b

Please sign in to comment.