Creating a 'Ajaxified' Form Field Type

て烟熏妆下的殇ゞ 提交于 2019-11-29 11:03:43

I wrote a bundle (Alsatian/FormBundle), which does what you want on the server side.

  • How to avoid loading each entities by each form rendering :

    abstract class AbstractExtensibleChoicesType extends AbstractRoutableType
    {
        public function configureOptions(OptionsResolver $resolver)
        {  
            $resolver->setDefault('choices',array());
        }
    }
    
  • How to populate the form field with cached content :

That's your own logic, I would suggest : create a controller which only returns (as HTML) :

<option value="1">Option 1</option>
<option value="2">Option 2</option>

In the controller set Maxage :

/*
* @Route(...)
* @Cache(maxage=64000)
*/
public function getOptionsAction(Request $request) // Home
{
    $choices = $this->getDoctrine()->getManager()->getRepository //....

    return $this->render(/*...*/);
}

Use javascript to load this url and to put the html result in your select field.

If you are using something like Select2 : Your Controller can also return the options as a JSONReponse(), then you can load this JSON directly from the select2 ajax option (see bundle documentation, that's how I use it).

Get the sumitted choices in a Form::PRE_SUBMIT event (also PRE_SET_DATA if you use your form to edit), and reinject these choices to the field.

Autocomplete with an Ajax controller option looks nice to me, but heres' another( maybe quicker?) option: render your form through hinclude.

hinclude is a JS library used to "defer" load of parts of a page, thought Ajax. Symfony comes with integrated support (official documentation).

How yo use it:

  • move your form render to another controller action, let's call it formAction
  • include hinclude.js on your page (cf official Github)
  • use this code to render your form:

    {{ render_hinclude(controller('...::form'), {'default': 'Loading...'}) }}

  • you will probably want to keep your form handling in your original controller action, so modify the "action" of the generated form like this:

    $form = $this->createForm(new FormType(), $obj, array( 'action' => $this->generateUrl('original_form_action')));

Considering your usecase, The best way would be to use an Autocomplete. Here is a Symfony bundle I have been using and its awesome. I did some overwrite its javascript (autocompleter) to enhance few functionality as per my case.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!