7

I need help on using Symfony2.1 forms with method=GET and a clean URL space.

I am creating a "filter" which I'd like to set in the URL so that people can bookmark their links.

So, very simply the code:

$form = $this->createFormBuilder($defaultData)
    ->add('from', 'date', array('required' => false, 'widget' => 'single_text', 'format' => 'dd.MM.yyyy'))

I render the form widget and all is fine.

However when I submit the form, it produces very ugly GET parameters:

/app_dev.php/de/event?form%5Bfrom%5D=17.11.2012

This is because the input name is of course form[from]

So to clean the URL space, I made myself a theme:

{% block widget_attributes %}
{% spaceless %}
    id="{{ id }}" name="{{ id }}"{% if read_only %} disabled="disabled"{% endif %}{% if required %} required="required"{% endif %}{% if max_length %} maxlength="{{ max_length }}"{% endif %}{% if pattern %} pattern="{{ pattern }}"{% endif %}
    {% for attrname,attrvalue in attr %}{{attrname}}="{{attrvalue}}" {% endfor %}
{% endspaceless %}
{% endblock widget_attributes %}

where I replaced name="{{ full_name }}" with name="{{ id }}".

This works well - my URL space is cleaner:

/app_dev.php/de/event?form_from=17.11.2012

I guess I could live with that - although ideally from=xxx would be better. That is the first and more minor problem.


The second problem is that I can't get the form to bind anymore - this is obvious because the parameter "form" is no longer set - "form_from" has replaced it, but when you do a bind it is still expecting form[].

I tried to fix that like this:

$fromDate = $this->get('request')->query->get('form_from', null);
$request->query->set('form', array('from' => $fromDate);

But that doesn't work. I also suspect that I am digging a huge hole of hacks at the moment.

So, the question is: should I just live with the form%5Bfrom%5D url, or is there a better way to do all of this (without using POST obviously)?

JeanValjean
  • 17,172
  • 23
  • 113
  • 157
mogoman
  • 2,286
  • 24
  • 28

3 Answers3

26

You can set the name of the root form to empty, then your field name will be just form. Do so via

// the first argument to createNamedBuilder() is the name
$form = $this->get('form.factory')->createNamedBuilder(null, 'form', $defaultData)
    ->add('from', 'date', array(
        'required' => false,
        'widget' => 'single_text',
        'format' => 'dd.MM.yyyy'
    ));
Flo Schild
  • 5,104
  • 4
  • 40
  • 55
Bernhard Schussek
  • 4,823
  • 26
  • 33
  • 1
    Is it possible to do something like this when using FormTypes as services? I don't think you can access createNamedBuilder in that context and using FormType::getName() { return ''; } causes problems referencing the FormType as a service. – caponica Aug 29 '13 at 13:32
  • 1
    Of course you can access createNamedBuilder(), you just need to get access to the form factory :) – Bernhard Schussek Aug 29 '13 at 20:46
  • 2
    `$builder->getFormFactory()`... who knew? Thanks! – caponica Aug 29 '13 at 23:10
  • 1
    FormFactory -> `createNamed` could be used to get a `Form` instance instead of a builder – Leto Aug 11 '14 at 13:54
  • @caponica have you found a solution when using form as service ? I am stuck on this! – Sergio Costa Jan 22 '15 at 19:03
  • With the current version of form component, this will create a `form` tag with empty name attribute which doesn't validate as HTML5. – Karolis Mar 17 '18 at 23:34
7

old thread, but worth mentioning that symfony 3 ignores getName entirely.

However, you can do the same with getBlockPrefix if you need the form name to be blank.

public function getBlockPrefix() {
    return null;
}

this will result in form fields being named without a prefix.

DevDonkey
  • 4,835
  • 2
  • 27
  • 41
2

using return null; in your implementation of AbstractType::getName seems to have the same effect these days.

  • But if formtype returns null, is not possible to generate formType with dependency injection – mmoreram Sep 25 '13 at 16:07
  • 1
    Cannot use this approach with DI in general. Returning null is equivalent to the accepted answer, see for yourself. –  Feb 05 '14 at 14:05