Как очистить значение поля с помощью форм Symfony2
Я пишу свой собственный класс CAPTCHA, и когда форма не проверяется, я не хочу предварительно заполнять вкладку captcha с предыдущим ответом по очевидным причинам. Я просто хочу очистить ввод до его отображения.
Я обнаружил, что параметр данных предназначен только для значения по умолчанию, которое перезаписывается тем, что вводит пользователь. Я попробовал следующий код:
$form->get('captcha')->setData(null);
.. После того, как запрос связан с формой, вызывается AlreadyBoundException
. Мне действительно удалось заставить его работать с:
if (isset($formView->children['captcha'])) {
$formView->children['captcha']->vars['value'] = null;
}
Но это просто выглядит неправильно, и определенно не соответствует стандартам Symfony. Я просмотрел другие параметры, которые вы можете предоставить при создании формы, но я не вижу ничего примечательного.
Есть ли у кого-нибудь идеи?
Кстати, я ожидаю, что Symfony2 поставляется в комплекте с решением CAPTCHA, это в основном учебное упражнение, в то время как я привык к структуре.
Ответы
Ответ 1
Я думаю, что вы хотите обработать это поле формы, так как Symfony обрабатывает поле password
: он не будет заполнен. Давайте посмотрим на PasswordType:
namespace Symfony\Component\Form\Extension\Core\Type;
class PasswordType extends AbstractType
{
public function buildView(FormView $view, FormInterface $form, array $options)
{
if ($options['always_empty'] || !$form->isSubmitted()) {
$view->vars['value'] = '';
}
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'always_empty' => true,
'trim' => false,
));
}
//...
}
Итак, это довольно просто: просто добавьте $view->vars['value'] = ''
в метод buildView
вашего FormType (т.е. CaptchaType). Это означает, что данные поля не очищаются, но они не будут переданы шаблону Twig. Разный подход, но результат тот же: поле пароля остается пустым после неудачной проверки.
Если вы действительно ленивы, вы можете использовать PasswordType, но так как ввод этого поля будет замаскирован (*****), это еще хуже сделает раздражающее поле captcha.
Тип вашей формы может выглядеть следующим образом:
class CaptchaType extends AbstractType
{
/**
* {@inheritdoc}
*/
public function buildView(FormView $view, FormInterface $form, array $options)
{
$view->vars['value'] = '';
}
/**
* {@inheritdoc}
*/
public function getParent()
{
return __NAMESPACE__.'\TextType';
}
/**
* {@inheritdoc}
*/
public function getName()
{
return $this->getBlockPrefix();
}
/**
* {@inheritdoc}
*/
public function getBlockPrefix()
{
return 'captcha';
}
}
Изменить:
Просто обнаружил, что CaptchaBundle принял тот же подход.
Ответ 2
Есть забавный способ изменить запрос перед его обработкой. Однако я бы посмотрел на ответ Стефана, поскольку он кажется более чистым.
Что-то вроде этого:
public function indexAction(Request $request)
{
$form = $this->createForm(Form::class);
$subData=$request->request->get('form');
$subData['task']=null;
$request->request->set('form',$subData);
$form->handleRequest($request);
if ($form->isValid()) {
//do stuff
}
return $this->render('default/index.html.twig', array(
'form' => $form->createView()
));
}
Получите представленные данные с именем "form" в виде массива значений, измените указанное значение на null, затем установите значение запроса с новым и обработайте его формой.
И простая форма
class Form extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('task')
->add('save', SubmitType::class);
}
}
Независимо от того, что вы набираете, данные всегда будут пустыми после отправки формы. Конечно, вам нужно проверить капчу, прежде чем устанавливать значение в значение null.
Ответ 3
Вы можете передать неполную сущность в действие, вызванное, когда элемент управления найден неверным.
public function updateAction(Request $request, $id)
{
$entity = $this->EM()->getRepository('Bundle:Entity')->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find Entity entity.');
}
$form = $this->createForm(new RecommendationType()
,$entity
,array(
'attr' => array(
,'entity' => $entity
)
)
);
$form->bind($request);
if ($form->isValid()) {
$this->EM()->persist($entity);
$this->EM()->flush();
return $this->redirect($this->generateUrl('entity_show'
,array('id' => $id)));
} else {
$entity->setCapthca(Null);
}
return $this->render('Bundle:Entity:edit.html.twig'
,array(
'entity' => $entity
,'form' => $form->createView()
)
);
}
Действие create будет иметь аналогичную модификацию.