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 Symfony\Component\Form\Extension\Core\Type\SubmitType;
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
{
public function searchAction(Request $request)
public function searchAction(Request $request, $_format)
{
$pattern = $request->query->get('q', '');
if ($pattern === ''){
return $this->render('ChillMainBundle:Search:error.html.twig',
array(
'message' => $this->get('translator')->trans("Your search is empty. "
. "Please provide search terms."),
'pattern' => $pattern
));
switch($_format) {
case 'html':
return $this->render('ChillMainBundle:Search:error.html.twig',
array(
'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);
try {
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
$results = $this->get('chill.main.search_provider')
->getSearchResults(
->getSearchResults(
$pattern,
0,
5,
@ -74,13 +87,18 @@ class SearchController extends Controller
$paginatorFactory = $this->get('chill_main.paginator_factory');
$results = [$this->get('chill.main.search_provider')
->getResultByName(
->getResultByName(
$pattern,
$name,
$paginatorFactory->getCurrentPageFirstItemNumber(),
$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) {
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)
{
$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
->generate('chill_main_postal_code_search');
$view->vars['attr']['data-placeholder'] = $this->translator->trans($options['placeholder']);

View File

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

View File

@ -1,7 +1,7 @@
window.addEventListener('load', function (e) {
var
postalCodes = document.querySelectorAll('[data-postal-code]')
postalCodes = document.querySelectorAll('[data-select-interactive-loading]')
;
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 $limit the number of result (for pagination)
* @param array $option the options, specific for each search
* @param string $format The format for result
* @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,
@ -85,6 +86,6 @@ interface SearchInterface
*
* @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
* results as html string
* results as an array of resultsfrom different SearchInterface
*
* @param string $pattern
* @param number $start
* @param number $limit
* @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
*/
public function getSearchResults($pattern, $start = 0, $limit = 50,
array $options = array())
array $options = array(), $format = 'html')
{
$terms = $this->parse($pattern);
$results = array();
@ -180,7 +181,7 @@ class SearchProvider
if ($terms['_domain'] !== NULL) {
foreach ($sortedSearchServices as $service) {
if ($service->supports($terms['_domain'])) {
if ($service->supports($terms['_domain'], $format)) {
$results[] = $service->renderResult($terms, $start, $limit, $options);
}
}
@ -203,7 +204,7 @@ class SearchProvider
}
public function getResultByName($pattern, $name, $start = 0, $limit = 50,
array $options = array())
array $options = array(), $format)
{
$terms = $this->parse($pattern);
$search = $this->getByName($name);
@ -213,7 +214,7 @@ class SearchProvider
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/select2/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
require('./Resources/public/img/favicon.ico');