Skip to content

Commit f7966bc

Browse files
committed
better entity loading with predefined controller and callback
1 parent 06426de commit f7966bc

File tree

5 files changed

+87
-2
lines changed

5 files changed

+87
-2
lines changed

Form/Type/Select2EntityType.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,8 @@ public function configureOptions(OptionsResolver $resolver)
167167
'autostart' => true,
168168
'width' => isset($this->config['width']) ? $this->config['width'] : null,
169169
'req_params' => array(),
170+
'property' => null,
171+
'callback' => null,
170172
)
171173
);
172174
}

Resources/config/services.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
<argument type="service" id="router" />
1212
<argument>%tetranz_select2_entity.config%</argument>
1313
</service>
14+
<service id="tetranz_select2entity.autocomplete_service" class="Tetranz\Select2EntityBundle\Service\AutocompleteService">
15+
<argument type="service" id="service_container" />
16+
</service>
1417
</services>
1518

1619
</container>

Resources/public/js/select2entity.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@
5555
},
5656
data: function (params) {
5757
var ret = {
58-
'q': params.term
58+
'q': params.term,
59+
'field_name': $s2.data('name')
5960
};
6061

6162
var reqParams = $s2.data('req_params');

Resources/views/Form/fields.html.twig

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
'data-page-limit':page_limit,
1212
'data-scroll':scroll ? 'true' : 'false',
1313
'data-autostart':autostart ? 'true' : 'false',
14-
'class' : (attr.class|default('') ~ ' select2entity form-control')|trim
14+
'class' : (attr.class|default('') ~ ' select2entity form-control')|trim,
15+
'data-name' : name|e('html_attr')
1516
}) %}
1617

1718
{% if allow_add.enabled %}

Service/AutocompleteService.php

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
<?php
2+
3+
namespace Tetranz\Select2EntityBundle\Service;
4+
5+
use Doctrine\ORM\EntityRepository;
6+
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
7+
use Symfony\Component\DependencyInjection\ContainerAwareTrait;
8+
use Symfony\Component\DependencyInjection\ContainerInterface;
9+
use Symfony\Component\Form\FormTypeInterface;
10+
use Symfony\Component\HttpFoundation\Request;
11+
use Symfony\Component\PropertyAccess\PropertyAccess;
12+
13+
class AutocompleteService implements ContainerAwareInterface
14+
{
15+
use ContainerAwareTrait;
16+
17+
18+
public function __construct(ContainerInterface $container)
19+
{
20+
$this->setContainer($container);
21+
}
22+
23+
/**
24+
* @param Request $request
25+
* @param string|FormTypeInterface $type
26+
*
27+
* @return array
28+
*/
29+
public function getAutocompleteResults(Request $request, $type)
30+
{
31+
$form = $this->container->get('form.factory')->create($type);
32+
$fieldOptions = $form->get($request->get('field_name'))->getConfig()->getOptions();
33+
34+
/** @var EntityRepository $repo */
35+
$repo = $this->container->get('doctrine')->getRepository($fieldOptions['class']);
36+
37+
$term = $request->get('q');
38+
39+
$countQB = $repo->createQueryBuilder('e');
40+
$countQB
41+
->select($countQB->expr()->count('e'))
42+
->where('e.'.$fieldOptions['property'].' LIKE :term')
43+
->setParameter('term', '%' . $term . '%')
44+
;
45+
46+
$maxResults = $fieldOptions['page_limit'];
47+
$offset = ($request->get('page', 1) - 1) * $maxResults;
48+
49+
$resultQb = $repo->createQueryBuilder('e');
50+
$resultQb
51+
->where('e.'.$fieldOptions['property'].' LIKE :term')
52+
->setParameter('term', '%' . $term . '%')
53+
->setMaxResults($maxResults)
54+
->setFirstResult($offset)
55+
;
56+
57+
58+
if (array_key_exists('callback', $fieldOptions)) {
59+
$cb = $fieldOptions['callback'];
60+
61+
$cb($countQB, $request);
62+
$cb($resultQb, $request);
63+
}
64+
65+
$count = $countQB->getQuery()->getSingleScalarResult();
66+
$paginationResults = $resultQb->getQuery()->getResult();
67+
68+
$result = ['results' => null, 'more' => $count > ($offset + $maxResults)];
69+
70+
$accessor = PropertyAccess::createPropertyAccessor();
71+
72+
$result['results'] = array_map(function ($item) use ($accessor, $fieldOptions) {
73+
return ['id' => $accessor->getValue($item, $fieldOptions['primary_key']), 'text' => $accessor->getValue($item, $fieldOptions['property'])];
74+
}, $paginationResults);
75+
76+
return $result;
77+
}
78+
}

0 commit comments

Comments
 (0)