-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[RFC][Form] Add form::getErrorsAsArray #7205
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
+1 for having this functionality inside the form component...I've had to implement this numerous times |
+1 I had to implement the same function in a special controller from which other controller inherit. I was just thinking to create a PR for that. |
Does this really belong to the core ? Would using the JMSSerializerBundle solve your issue ? |
Other variant of extraction errors to array: private function getErrorMessages(\Symfony\Component\Form\Form $form)
{
$errors = array();
foreach ($form->getErrors() as $key => $error) {
$template = $error->getMessageTemplate();
$parameters = $error->getMessageParameters();
$errors[$key] = strtr($template, $parameters);
}
if ($form->hasChildren()) {
foreach ($form->getChildren() as $child) {
if (!$child->isValid()) {
$key = sprintf('%s[%s]', $form->getName(), $child->getName());
$errors[$key] = $this->getErrorMessages($child);
}
}
}
return $errors;
} |
@vicb: we already have |
@fabpot my point is that this would probably be used in the context of a ws (web service) and then you probably want to include jms or fosrestbundle. Anyway I am not opposed to the change. Fabien Potencier notifications@github.com wrote:
|
+1 |
@Koc The result is the same but in your variant, you use deprecated methods (like hasChildren, getChildren). @Vibs For me there is no link between this method and the usage of web services. The goal is simply to have an array representation of errors, which can be serialize to Json or not after. I think it's a common use case to be able to have the complete list of errors. |
In fact, we can think this is usefull, but in this state, this is not so usefull. private function getErrorsAsArray(\Symfony\Component\Form\Form $form)
{
$errors = array();
foreach ($form->getErrors() as $error) {
$errors[] = $error->getMessage();
}
foreach ($form->all() as $child) {
if ($err = $this->getErrorsAsArray($child)) {
$options = $child->getConfig()->getOptions();
$key = $this->get('translator')->trans($options['label'] ?: '', array(), $options['translation_domain'] ?: 'messages');
$errors[$key] = $err;
}
}
return $errors;
} |
@raziel057 oh, haven't noticed that, thank you. Big +1 for this method. We are using it for ajax responses with errors to extjs forms. |
@lyrixx I don't see why the key should be localized. The key must be the fieldName, nothing else. |
Why ? I really depends on your use case. |
@lyrixx Even if the end user doesn't care about the field names, your html elements needs to have a name (and it's a bad idea to set field label as name). If you have the element names in the list of error, you can easily link it to the corresponding fields. With js you can display errors bottom each fields. You can also get the the localized text of corresponding labels for each fields in error. So for me there you shoudn't rely on localized text and the getErrorsAsArray must return a list of error which field name as key. If you really need a localized label, I suggest to iterate on the array to add the label from you controller. |
It would be nice have same method for form values: $group = GuardGroupPeer::retrieveByPK($id);
$form = $this->createForm(new GuardGroupType(), $group);
$values = $form->getValuesAsArray(); // array('guardgroup[title]' => 'title', guardgroup[active_from] => DateTime) |
Do you want the array representing the view data or the model data ? |
yes, for bind it to extjs form for example. I can create separate ticket for this. |
I'm wondering how the answer to my question can be "yes"... |
View data, sorry bro. |
Now we are using smth like this: private function getFormValues(\Symfony\Component\Form\FormView $formView)
{
$values = array();
foreach ($formView->vars['form']->children as $subView)
{
if (count($subView->children))
{
$values = array_merge($values, $this->getFormValues($subView));
}
else
{
$values[$subView->vars['full_name']] = $subView->vars['value'];
}
}
return $values;
} |
@Koc |
Well, not the same formatting than the one you use here (it will be a nested array, not a flat array with |
$childForm = $this->get('form.factory')->createNamedBuilder('subform', 'form', array('subtitle' => 'st1'))
->add('subtitle')
;
$form = $this->createFormBuilder(array('title' => 't1'))
->add('title')
->add($childForm)
->getForm();
// getFormValues:
// array (size=3)
// 'form[title]' => string 't1' (length=2)
// 'form[subform][subtitle]' => string 'st1' (length=3)
// 'form[_token]' => string 'e04b43b8c0a6fd9d6095783f9e9f41613209329f' (length=40)
// getViewData:
// array (size=1)
// 'title' => string 't1' (length=2) Maybe it should be method in |
+1 for the feature |
Wouldn't it be useful to use the full form field id (as in |
I think that instead of adding a bunch of
Additionally,
When all this is done, |
A FormErrorCollection seems the best solution as we can then format the result the way we need. +1 |
Like so many others... :) Feel free to work on this, if you want. |
I'm going to work on this one. |
@wouterj Great, thank you! :) |
replaced by #9099 |
My version of solving the problem: services:
form_errors:
class: Intranet\OrgunitBundle\Form\FormErrors /src/Intranet/OrgunitBundle/Form/FormErrors.php <?php
namespace Intranet\OrgunitBundle\Form;
class FormErrors
{
public function getArray(\Symfony\Component\Form\Form $form)
{
return $this->getErrors($form);
}
private function getErrors($form)
{
$errors = array();
if ($form instanceof \Symfony\Component\Form\Form) {
// соберем ошибки элемента
foreach ($form->getErrors() as $error) {
$errors[] = $error->getMessage();
}
// пробежимся под дочерним элементам
foreach ($form->all() as $key => $child) {
/** @var $child \Symfony\Component\Form\Form */
if ($err = $this->getErrors($child)) {
$errors[$key] = $err;
}
}
}
return $errors;
}
} /src/Intranet/OrgunitBundle/Controller/DefaultController.php $form = $this->createFormBuilder($entity)->getForm();
$form_errors = $this->get('form_errors')->getArray($form);
return new JsonResponse($form_errors); |
…and added two optional parameters $deep and $flatten (webmozart) This PR was merged into the 2.5-dev branch. Discussion ---------- [Form] Changed Form::getErrors() to return an iterator and added two optional parameters $deep and $flatten | Q | A | ------------- | --- | Bug fix? | no | New feature? | yes | BC breaks? | yes | Deprecations? | yes | Tests pass? | yes | Fixed tickets | #7205 | License | MIT | Doc PR | - See the changes in the UPGRADE files for more information. Commits ------- 6b3fbb5 [Form] Changed the default value of $flatten in Form::getErrors() to true a9268c4 [Form] Changed Form::getErrors() to return an iterator and added two optional parameters $deep and $flatten
I need in my project
Form::getErrorsAsArray
(likeForm::getErrorsAsString
), to render the error in a json response. It can be useful for a web service.Do it make sens to add it to the form component ?
Here my code:
If it's ok for you, I will create a PR.
The text was updated successfully, but these errors were encountered: