日々のあれこれ

日々見たもの聞いたもの思ったこと書いてます。

Symfony3 PUGX/PUGXAutoCompleterBundle

Symfony3 で PUGX/PUGXAutoCompleterBundleを実装し、Item.php Entityの内容をAutocompleteする方法です。

github.com

PUGX/PUGXAutoCompleterBundle は EntityType::class と同じような動きをします。FormTypeではAutocompleteType::classをFormTypeとして指定することを忘れないでください。

Controllerではjsonを返します。DoctrineでLIKE文でAutocompleteの検索を行います。

Controller Class

class DefaultController extends Controller
{

    /**
     * @Route("/search/list", name="search_list")
     * @Method("GET")
     */
    public function searchListAction(Request $request)
    {
        
        $term = $request->query->get('term');
        $em = $this->getDoctrine()->getManager();
        
        $places = $em->getRepository("AppBundle:Item")->createQueryBuilder('p')
            ->where('p.title LIKE :title')
            ->andWhere('p.title LIKE :title')
            ->setParameter('title', '%'.$term.'%')
            ->getQuery()
            ->getResult();
        
        return $this->render('@AppBundle/Resources/views/Item/search.json.twig', 
            ['places' => $places]
        );
        
    }
}

Twig for Json (search.json.twig)

jsonでは item.title = string, item.id=uniq integer(Uniq index ID) です。このvalueの値がフォームの実態の数字です。EntityFormをAutocompleteとして投げるときにはvalue = idとして指定することで実現が可能です。

[{% for place in places -%}
    {{ {id: item.id, label: item.title, value: item.id}|json_encode|raw }}
    {%- if not loop.last %},{% endif -%}
{%- endfor %}]

FormType (Form/ItemType.php)

use PUGX\AutocompleterBundle\Form\Type\AutocompleteType;

 class ItemType extends AbstractType
 
     public function buildForm(FormBuilderInterface $builder, array $options)
     {
         $builder->add('place', AutocompleteFilterType::class, array(
            'class' => Item::class
         ));
     }
 }

Twig for HTML

autocompleter-jqueryui.js の関数を実行するわけですが autocompleter() と autocomplete() がありややこしいです。autocompleter()はAutoCompleterBundleで定義している関数です。url_listで指定したURLからjsonを取得します。ドキュメントにはurl_getが利用可能と書いてありますが、実際にはどのような環境でも動かなかったです。改善が必要ですね。autocompleter-jqueryui.js の 30行目 if ($this.val() !== '') が認識しないようです。url_getを指定しなくとも動作はします。

<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="{{ asset('js/jquery.js') }}"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<script src="{{ asset('js/autocompleter-jqueryui.js') }}"></script>> <script>

$(document).ready(function() {
    
    var options = {
        url_list: '{{ path('place_search_list') }}',
        otherOptions: {
            minimumInputLength: 3
        }
    };
         // Target form ID
    $('#appbundle_item_item').autocompleter(options);

});
</script>

config.yml

config.ymlはjsの読み込みのためにassetsの設定を行います。

assetic:
    assets:
        jquery_js:
            inputs:
                - %kernel.root_dir%/../vendor/components/jquery/jquery.min.js
            output: "js/jquery.js"
        autocompleter:
            inputs:
                - %kernel.root_dir%/../vendor/pugx/autocompleter-bundle/Resources/public/js/autocompleter-jqueryui.js
            output: "js/autocompleter-jqueryui.js"

Symfony3 の環境での PUGX/PUGXAutoCompleterBundle の実装例は日本語では皆無だったのでこちらに掲載しておきます。