vendredi 27 février 2015

Symfony 2 search form renders an unwanted search field. Can I disable this behaviour?

The require section in my composer.json looks like this:



"require": {
"php": ">=5.3.3",
"symfony/symfony": "2.3.*",
"doctrine/orm": "~2.2,>=2.2.3,<2.5",
"doctrine/dbal": "<2.5",
"doctrine/doctrine-bundle": "~1.2",
"twig/extensions": "1.0.*",
"symfony/assetic-bundle": "~2.3",
"symfony/swiftmailer-bundle": "~2.3",
"symfony/monolog-bundle": "~2.4",
"sensio/distribution-bundle": "~2.3",
"sensio/framework-extra-bundle": "~3.0,>=3.0.2",
"sensio/generator-bundle": "~2.3",
"incenteev/composer-parameter-handler": "~2.0",

"braincrafted/bootstrap-bundle": "~2.0",
"twbs/bootstrap": "3.2.*",
"jquery/jquery": "1.11.*",
"stof/doctrine-extensions-bundle": "~1.1@dev"
},


NOTE: The last four packages are added on top of Symfony2 standard edition.


Following the Symfony 2 Forms docs chapter, I'm trying to create a search form. So, I have created an entity class:



<?php
namespace AppBundle\Entity;

use Symfony\Component\Validator\Constraints as Assert;

class SearchQuery
{
/**
* @Assert\NotBlank()
* @Assert\Type(type="string", message="form.search.query.validation.type")
* @Assert\Length(
* min = 3,
* max = 50,
* minMessage = "form.search.query.validation.min",
* maxMessage = "form.search.query.validation.max"
* )
*/
protected $query;

public function __construct($query = '')
{
$this->setQuery($query);
}

public function getQuery()
{
return $this->query;
}

public function setQuery($query)
{
$this->query = $query;
}
}


And a form type class:



<?php
namespace AppBundle\Form\Type;

use
Symfony\Component\OptionsResolver\OptionsResolverInterface,
Symfony\Component\Form\AbstractType,
Symfony\Component\Form\FormBuilderInterface
;

class SearchType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('query', 'text', array(
'label' => '',
'attr' => array(

),
))
->add('save', 'submit', array(
'label' => '',
));
}

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\SearchQuery',
'attr' => array(
'id' => 'search-form'
)
));
}

public function getName()
{
return 'search';
}
}


The rendered output:



<form name="search" method="post" action="/app_dev.php/search" id="search-form" role="form">

<input type="search" id="search" name="search" required="required" class="form-control" value="">

<div class="form-group">
<label class="control-label required" for="search_query">Query</label>
<input type="text" id="search_query" name="search[query]" required="required" class="form-control">
</div>
<div class="form-group">
<button type="submit" id="search_save" name="search[save]" class="btn btn-primary">Save</button>
</div>
<input type="hidden" id="search__token" name="search[_token]" class="form-control" value="5f0e9c4a9d4e251fc62e25686cf810eaa0ff4331">
</form>


The problem is that something between Symfony 2 Forms, BraincraftedBootstrapBundle and Twig is trying to play smart and adds this unwanted field:



<input type="search" id="search" name="search" required="required" class="form-control" value="">


I've noticed that this happens only if the SearchType::getName() method returns 'search'. If I change this to something like:



class SearchType extends AbstractType
{

[...]

public function getName()
{
return 'search_foo';
}

[...]

}


everything works as expected, the rendered output is:



<form name="search_foo" method="post" action="/app_dev.php/cautare" id="search-form" role="form">
<div id="search_foo">
<div class="form-group">
<label class="control-label required" for="search_foo_query">Query</label>
<input type="text" id="search_foo_query" name="search_foo[query]" required="required" class="form-control">
</div>
<div class="form-group">
<button type="submit" id="search_foo_save" name="search_foo[save]" class="btn btn-primary">Save</button>
</div>
<input type="hidden" id="search_foo__token" name="search_foo[_token]" class="form-control" value="68ee88cb3adef211b993806029ba3fa989322c80">
</div>
</form>


Of course, I can change the name to something else and move on, but it's like a nail being hammered in my head to do so without understanding what's really happening behind the curtains.


I've even tried to set the field type to search instead of text hoping that if it sees that there is a search field would leave me alone and won't try to guess what my intentions are, but no, it still prints the unwanted field.


Aucun commentaire:

Enregistrer un commentaire