allow json in search response and abstract interactive loading from select2

This commit is contained in:
Julien Fastré 2018-08-27 13:14:15 +02:00
parent 45946082ea
commit 1826c63251
7 changed files with 46 additions and 23 deletions

View File

@ -30,6 +30,7 @@ use Chill\MainBundle\Search\ParsingException;
use Chill\MainBundle\Search\SearchInterface; use Chill\MainBundle\Search\SearchInterface;
use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\FormType; use Symfony\Component\Form\Extension\Core\Type\FormType;
use Symfony\Component\HttpFoundation\JsonResponse;
/** /**
* *
@ -40,27 +41,39 @@ use Symfony\Component\Form\Extension\Core\Type\FormType;
class SearchController extends Controller class SearchController extends Controller
{ {
public function searchAction(Request $request) public function searchAction(Request $request, $_format)
{ {
$pattern = $request->query->get('q', ''); $pattern = $request->query->get('q', '');
if ($pattern === ''){ if ($pattern === ''){
return $this->render('ChillMainBundle:Search:error.html.twig', switch($_format) {
array( case 'html':
'message' => $this->get('translator')->trans("Your search is empty. " return $this->render('ChillMainBundle:Search:error.html.twig',
. "Please provide search terms."), array(
'pattern' => $pattern 'message' => $this->get('translator')->trans("Your search is empty. "
)); . "Please provide search terms."),
'pattern' => $pattern
));
case 'json':
return new JsonResponse([
'results' => [],
'pagination' => [ 'more' => false ]
]);
}
} }
$name = $request->query->get('name', NULL); $name = $request->query->get('name', NULL);
try { try {
if ($name === NULL) { if ($name === NULL) {
if ($_format === 'json') {
return new JsonResponse('Currently, we still do not aggregate results '
. 'from different providers', JsonResponse::HTTP_BAD_REQUEST);
}
// no specific search selected. Rendering result in "preview" mode // no specific search selected. Rendering result in "preview" mode
$results = $this->get('chill.main.search_provider') $results = $this->get('chill.main.search_provider')
->getSearchResults( ->getSearchResults(
$pattern, $pattern,
0, 0,
5, 5,
@ -74,13 +87,18 @@ class SearchController extends Controller
$paginatorFactory = $this->get('chill_main.paginator_factory'); $paginatorFactory = $this->get('chill_main.paginator_factory');
$results = [$this->get('chill.main.search_provider') $results = [$this->get('chill.main.search_provider')
->getResultByName( ->getResultByName(
$pattern, $pattern,
$name, $name,
$paginatorFactory->getCurrentPageFirstItemNumber(), $paginatorFactory->getCurrentPageFirstItemNumber(),
$paginatorFactory->getCurrentItemsPerPage(), $paginatorFactory->getCurrentItemsPerPage(),
array(SearchInterface::SEARCH_PREVIEW_OPTION => false) array(SearchInterface::SEARCH_PREVIEW_OPTION => false),
$_format
)]; )];
if ($_format === 'json') {
return new JsonResponse(\reset($results));
}
} }
} catch (UnknowSearchDomainException $ex) { } catch (UnknowSearchDomainException $ex) {
return $this->render('ChillMainBundle:Search:error.html.twig', return $this->render('ChillMainBundle:Search:error.html.twig',

View File

@ -98,6 +98,7 @@ class PostalCodeType extends AbstractType
public function buildView(FormView $view, FormInterface $form, array $options) public function buildView(FormView $view, FormInterface $form, array $options)
{ {
$view->vars['attr']['data-postal-code'] = 'data-postal-code'; $view->vars['attr']['data-postal-code'] = 'data-postal-code';
$view->vars['attr']['data-select-interactive-loading'] = true;
$view->vars['attr']['data-search-url'] = $this->urlGenerator $view->vars['attr']['data-search-url'] = $this->urlGenerator
->generate('chill_main_postal_code_search'); ->generate('chill_main_postal_code_search');
$view->vars['attr']['data-placeholder'] = $this->translator->trans($options['placeholder']); $view->vars['attr']['data-placeholder'] = $this->translator->trans($options['placeholder']);

View File

@ -66,8 +66,10 @@ chill_main_admin_permissions:
icons: [key] icons: [key]
chill_main_search: chill_main_search:
path: /{_locale}/search path: /{_locale}/search.{_format}
defaults: { _controller: ChillMainBundle:Search:search } defaults: { _controller: ChillMainBundle:Search:search, _format: 'html' }
requirements:
_format: html|json
chill_main_advanced_search: chill_main_advanced_search:
path: /{_locale}/search/advanced/{name} path: /{_locale}/search/advanced/{name}

View File

@ -1,7 +1,7 @@
window.addEventListener('load', function (e) { window.addEventListener('load', function (e) {
var var
postalCodes = document.querySelectorAll('[data-postal-code]') postalCodes = document.querySelectorAll('[data-select-interactive-loading]')
; ;
for (let i = 0; i < postalCodes.length; i++) { for (let i = 0; i < postalCodes.length; i++) {

View File

@ -57,9 +57,10 @@ interface SearchInterface
* @param int $start the first result (for pagination) * @param int $start the first result (for pagination)
* @param int $limit the number of result (for pagination) * @param int $limit the number of result (for pagination)
* @param array $option the options, specific for each search * @param array $option the options, specific for each search
* @param string $format The format for result
* @return string, an HTML string * @return string, an HTML string
*/ */
public function renderResult(array $terms, $start=0, $limit=50, array $options = array()); public function renderResult(array $terms, $start=0, $limit=50, array $options = array(), $format = 'html');
/** /**
* we may desactive the search interface by default. in this case, * we may desactive the search interface by default. in this case,
@ -85,6 +86,6 @@ interface SearchInterface
* *
* @return boolean * @return boolean
*/ */
public function supports($domain); public function supports($domain, $format);
} }

View File

@ -157,17 +157,18 @@ class SearchProvider
/** /**
* search through services which supports domain and give * search through services which supports domain and give
* results as html string * results as an array of resultsfrom different SearchInterface
* *
* @param string $pattern * @param string $pattern
* @param number $start * @param number $start
* @param number $limit * @param number $limit
* @param array $options * @param array $options
* @return array of html results * @param string $format
* @return array of results from different SearchInterface
* @throws UnknowSearchDomainException if the domain is unknow * @throws UnknowSearchDomainException if the domain is unknow
*/ */
public function getSearchResults($pattern, $start = 0, $limit = 50, public function getSearchResults($pattern, $start = 0, $limit = 50,
array $options = array()) array $options = array(), $format = 'html')
{ {
$terms = $this->parse($pattern); $terms = $this->parse($pattern);
$results = array(); $results = array();
@ -180,7 +181,7 @@ class SearchProvider
if ($terms['_domain'] !== NULL) { if ($terms['_domain'] !== NULL) {
foreach ($sortedSearchServices as $service) { foreach ($sortedSearchServices as $service) {
if ($service->supports($terms['_domain'])) { if ($service->supports($terms['_domain'], $format)) {
$results[] = $service->renderResult($terms, $start, $limit, $options); $results[] = $service->renderResult($terms, $start, $limit, $options);
} }
} }
@ -203,7 +204,7 @@ class SearchProvider
} }
public function getResultByName($pattern, $name, $start = 0, $limit = 50, public function getResultByName($pattern, $name, $start = 0, $limit = 50,
array $options = array()) array $options = array(), $format)
{ {
$terms = $this->parse($pattern); $terms = $this->parse($pattern);
$search = $this->getByName($name); $search = $this->getByName($name);
@ -213,7 +214,7 @@ class SearchProvider
throw new ParsingException("The domain is not supported for the search name"); throw new ParsingException("The domain is not supported for the search name");
} }
return $search->renderResult($terms, $start, $limit, $options); return $search->renderResult($terms, $start, $limit, $options, $format);
} }
/** /**

View File

@ -27,7 +27,7 @@ require('./Resources/public/modules/download-report/index.js');
//require('./Resources/public/css/scratch.css'); //require('./Resources/public/css/scratch.css');
//require('./Resources/public/css/select2/select2.css'); //require('./Resources/public/css/select2/select2.css');
require('select2/dist/css/select2.css'); require('select2/dist/css/select2.css');
require('./Resources/public/modules/postal-code/index.js'); require('./Resources/public/modules/select_interactive_loading/index.js');
// img // img
require('./Resources/public/img/favicon.ico'); require('./Resources/public/img/favicon.ico');