Pierre de LESPINAY
Pierre de LESPINAY

Reputation: 46158

Render a choice field without form

I often need to render very simple imputs in some of my templates.

I'd like to take advantage of the twig macros & form blocks to render certain HTML inputs without involving the whole Symfony forms machinery.

For example from the controller:

$templateContext = array(
    'my_input' = new FormField('my_input', 'choice', array(
        'choices' => array('value1', 'value2', 'my_value'),
        'value' => 'my_value',
    ));
);

In the template:

<div>{{ form_widget(my_input) }}</div>

would render:

<div>
    <select name="my_input">
        <option>value1</option>
        <option>value2</option>
        <option selected="selected">my_value</option>
    </select>
</div>

Is there a simple way to do that ?


Eventually I would also like to be able to reuse these fields elsewhere (like we can reuse form types)

Upvotes: 0

Views: 2753

Answers (3)

Volmarg Reiso
Volmarg Reiso

Reputation: 483

I found my own solution for it since i need to create subforms from existing forms.

  • create totally empty twig template,
  • add in it only {{form(form)}}
  • render this template render()->getContent()
  • do a preg replace on the result (i do it in js) formView = formView.replace(/<(.*?)form(.*?)>/, '');

Yes yes - i know that regex is not perfect so before someone says it - i say it on my own, change it for youself as it catches "form-group" classes etc as well.

This is just a showcase of my solution

Upvotes: 0

Pierre de LESPINAY
Pierre de LESPINAY

Reputation: 46158

Here is what I finally ended up with:

Class MyInput {
    public static values = array(
        'value1',
        'value2',
        'my_value',
    );
}

class MyInputType extends AbstractType
{
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'choices' => MyInput::$value,
        ));
    }

    public function getParent() { return 'choice'; }
    public function getName() { return 'my_input_type'; }
}

Field type used from the controller (after having registered it as a service)

public function MyAction(Request $request)
{
    $form = $this->createForm('my_input_type');
    $form->handleRequest($request);
    $templateContext['myForm'] = $form->createView();
    // ...
}

Input rendered into the template

<div>{{ form(myForm) }}</div>

To conclude: I've not been able to render an input without the form machinery, but the actual form remains rather simple.

Upvotes: 0

Ben Hillier
Ben Hillier

Reputation: 2104

There are many ways to go about this. The easiest would be to write the plain HTML into your twig template.

<form method="post">
<div>
    <select name="my_input">
        <option>value1</option>
        <option>value2</option>
        <option selected="selected">my_value</option>
    </select>
</div>
</form>

And then in your controller read the values back.

    $request = $this->getRequest();
    if($request->getMethod() == 'POST'){
        $data = $request->get('my_input')

        //Do whatever you want with $data
    }

If you want you re-use the html, you can build it somewhere in your PHP and pass it into Twig whenever you need it; or you can place it in a separate twig template and read that with the {include ''} command in twig.

Upvotes: 1

Related Questions