-
Notifications
You must be signed in to change notification settings - Fork 173
9.2. Auto complete
This is a sample implementation of auto-complete, using RESTful on the back end, and Angular on the client side, shared by @adam-s.
The complete server code is at https://github.com/adam-s/954live/tree/master/livesource/src/Plugin/resource/livesearch and the complete client side code is at https://github.com/adam-s/954live/tree/master/livesearch.
My solution was to use a filter on the 'name' public field with an operator 'CONTAINS' and to make sure things didn't get crazy, added a 'range' of 10.
var url = '/api/v1.6/artists?filter[name][value]='
+ encodeURIComponent(queryString)
+ '&filter[name][operator]=CONTAINS&range=10'
+ '&filter[bundle]='
+ encodeURIComponent(bundle);
Where things get fun is there are two different bundles that a user can search for, in this case, artists or venues. So a bundle property is defined on public fields. Using the ability to define a wrapper_method, getBundle is used to return a bundle name to filter on.
<?php
/**
* Maps to ArtistStyle
*/
namespace Drupal\livesource\Plugin\resource\entity\node\artists;
use Drupal\restful\Plugin\resource\ResourceNode;
/**
* Class Artist__1_6
* @package Drupal\livesource\Plugin\resource\entity\node\artists
*
* @Resource(
* name = "artists:1.6",
* resource = "artists",
* label = "Artists",
* description = "Export the artists with all authentication providers.",
* authenticationTypes = TRUE,
* authenticationOptional = TRUE,
* dataProvider = {
* "entityType": "node",
* "bundles": {
* "artists",
* "venues"
* },
* },
* majorVersion = 1,
* minorVersion = 6
* )
*/
class Artists__1_6 extends ResourceNode {
/**
* {@inheritdoc
*/
protected function publicFields() {
$public_fields = parent::publicFields();
$public_fields['name'] = $public_fields['label'];
unset($public_fields['label']);
$public_fields['bundle'] = array(
'wrapper_method' => 'getBundle',
'wrapper_method_on_entity' => TRUE,
);
return $public_fields;
}
}
Here is what it looks like on the client side. I'm surprised how easy this is.
(function() {
angular.module('livesearch')
.factory('LivesearchApi', LivesearchApi);
LivesearchApi.$inject = ['$http', '$q'];
function LivesearchApi($http, $q) {
var service = {
list: list,
getItem: getItem
};
return service;
function list(queryString, timeoutPromise, bundle) {
var deferred = $q.defer();
var url = '/api/v1.6/artists?filter[name][value]='
+ encodeURIComponent(queryString)
+ '&filter[name][operator]=CONTAINS&range=10'
+ '&filter[bundle]='
+ encodeURIComponent(bundle);
$http({
'method': 'GET',
'url': url,
'timeout': timeoutPromise
}).then(function(results) {
console.log(results);
deferred.resolve(results.data);
});
return deferred.promise;
}
}
})();