After doing more research from the documentation, it looks like a custom widget is the best way to try to achieve what I need: an autocomplete drop down that loads article/blog posts by title as the user types (I selected npm jquery-autocomplete, https://www.npmjs.com/package/jquery-autocomplete, as I thought it would be easy to implement for this feature, but perhaps there is an easier way within apos itself).
I followed the instructions in the tutorial on widgets, http://apostrophecms.org/docs/tutorials/getting-started/custom-widgets.html, and think that I almost have this hooked up, but I don't see the search widget (view) rendered, instead the dom shows an empty element div class="apos-area" data-apos-area="" element, which indicates there is a piece missing between linking all the part together, but I can't identify the missing piece based on the documentation sample code.
This is question #1, what is missing in the code below to keep the search.html view from loading?
app.js
modules: {
'search-widget': {}
}
lib\modules\search-widget\index.js
module.exports = {
extend: 'apostrophe-widgets',
label: 'SiteSearch',
addFields: [{
type: 'string',
name: 'title',
label: 'Title'
},
{
type: 'string',
name: 'url',
label: 'Url'
}
],
construct: function(self, options) {
//load third party styles and scripts?
var superPushAssets = self.pushAssets;
self.pushAssets = function() {
superPushAssets();
self.pushAsset('stylesheet', 'autocomplete', { when: 'always' });
self.pushAsset('script', 'autocomplete', { when: 'always' })
};
//get the data
self.pageBeforeSend = function(req, callback) {
var criteria = [
{ "type": "apostrophe-blog" },
{ "published": true }
];
criteria = { $and: criteria };
self.apos.docs.find(req, criteria).sort({ title: 1 }).toArray(function(err, autocomplete) {
if (err) {
return callback(err);
}
//Can I do something like this to load the widget data?
req.data.autocomplete = autocomplete;
return callback(null);
});
}
}
};
lib\modules\search-widget\views\search.html
<div id="custom-search-input">
<div class="input-group col-md-12">
<input type="text" class="form-control input-lg" id="site-search" placeholder="Search" />
<span class="input-group-btn">
<button class="btn btn-info btn-lg" type="button">
<i class="glyphicon glyphicon-search"></i>
</button>
</span>
</div>
</div>
lib\modules\apostrophe-pages\views\pages\home.html
{% extends 'apostrophe-templates:layout.html' %} {% block bodyClass %}{{ super() }} home-page{% endblock %} {% block title %}Help Site: {{ data.page.title | e }}{% endblock %} {% block main %}
<section id="promo" class="promo section offset-header">
<div class="container text-center">
<div class="row">
<div class="col-md-offset-2 col-md-8 col-sm-6 col-xs-12">
<!--search widget-->
{{ apos.singleton(data.page, 'search', 'search-widget') }}
</div>
</div>
</div>
</section>
Question #2 is, in the search-widget\index.js construct function, is this the correct way to load the third party assets that will be needed to render it to the dom and use it?
Question #3 is, in search.html can I simply use data.page to send the data to the jquery-autocomplete object?
<div id="custom-search-input">
<div class="input-group col-md-12">
<input type="text" class="form-control input-lg" id="site-search" placeholder="Search" />
<span class="input-group-btn">
<button class="btn btn-info btn-lg" type="button">
<i class="glyphicon glyphicon-search"></i>
</button>
</span>
</div>
</div>
<script>
$(function() {
$("#site-search").autocomplete({
source: {{ data.autocomplete | json }}
});
});
</script>