Specify the form theme of a specified entity in Symfony 2 - forms

I am working on a form quite complicated.
This form is based on an OngletFichier Entity with its form Builder :
$builder
->add('traitement')
->add('ligneEntetes');
$builder->add('colonnesOnglet', 'collection', array('type' => new ColonneOngletType()
));
As you can see, in this Entity Form, I got a list of ColonneOnglet which is an other entity.
It looks like something like that :
Entity Form
SimpleAttribute of OngletFichier (text input)
SimpleAttribute of OngletFichier (text input)
ColonneOnglet (which have its own attributes, its own input)
ColonneOnglet (which have its own attributes, its own input)
ColonneOnglet (which have its own attributes, its own input)
I need to define a special form theme for each ColonneOnglet to organize its inputs, and to put it in red or not depending on one of its attribute.
I am quite lost with form theming.
I found an example but I don't know if it can answer my problem : http://symfony2-document.readthedocs.org/en/latest/cookbook/form/create_custom_field_type.html
Thanks in advance for helping me !
EDIT :
http://symfony.com/doc/current/cookbook/form/form_customization.html#how-to-customize-an-individual-field
This works easily !

The article you've found is good, but I think this section of the manual fits better: http://symfony.com/doc/2.0/cookbook/form/form_customization.html#how-to-customize-an-individual-field
So the easiest way is to create separate file with form theme and import it into template using
form_theme form 'Path:To:theme.html.twig'. You can also define your styling inside the template itself and import using this directive: form_theme form _self, but be aware that in order for this to work the template must extend another one.

Related

redux-form Wizard form with linked fields

I am building a multi-step application form with React. Having first built it with pure internal state I am now in the process of refactoring to Redux using redux-form.
Having used the example here as a basis: http://redux-form.com/5.2.5/#/examples/wizard?_k=oftw7a we have come a good way.
However the problem appears when i have two forms which are supposed to have the same value. During one of the pages i have a name field, that is supposed to be duplicated on the name field of the next page. The opposite should happen if you go back from the last page. Any tips to how this could be achieved?
Using the wizard, you are basically working with the exact same form that's split into multiple pieces. Ultimately it's the same form, because redux-form tracks them by name. It is how the library identifies the pieces of the same form - using the name.
form: 'wizard',
Here you can see that the exact same instance of the form will be shared throughout the pieces. fields work in a similar manner. Each field is defined as part of a form.
As long as you use the same field constants inside the fields object that you pass into the reduxForm function and as long as the value for form is the same, so that they use the same underlying form object, it should work for you just fine.
On one page you should pass in
export default reduxForm({
form: 'wizard',
fields : {
'fieldIWantOnBothPartsOfTheForm',
'someOtherFieldThatShouldOnlyBeHere',
},
...
And then on the other page:
export default reduxForm({
form: 'wizard',
fields : {
'fieldIWantOnBothPartsOfTheForm',
'thirdFieldHere',
},
...
Also, make sure you keep destroyOnUnmount equal to false if you want to navigate back-and-forth.
Hope that helps.

How can I get the Zend_Form object via the Zend_Form_Element child

I've built a Zend_Form_Decorator_Input class which extends Zend_Form_Decorator_Abstract, so that I could customize my form inputs -- works great. I ran into a problem in the decorate class, in trying to get the form name of the element, so as to built a unique id for each field (in case there are multiple forms with identical field names).
There is no method like this: Zend_Form_Element::getForm(); It seems Zend_Form_Decorator_Abstract doesn't have this ability either. Any ideas?
I don't think changing the id from the decorator is the right approach. At the time the decorator is called the element already has been rendered. Thus changing the id would have no effect to the source code. Additionally, as you already have pointed out, the relation between a form and its elements is unidirectional, i.e. (to my best knowledge) there is no direct way to access the form from the element.
So far the bad news.
The good news is, that there actually is a pretty easy solution to your problem: The Zend_Form option elementsBelongTo. It prevents that the same ID is assigned to two form elements that have the same name but belong to different forms:
$form1 = new Zend_Form(array('elementsBelongTo' => 'form1'));
$form1->addElement('Text', 'text1');
$form2 = new Zend_Form(array('elementsBelongTo' => 'form2'));
$form2->addElement('Text', 'text1');
Although both forms have a text field named 'text1', they have different ids: 'form1-text1' and 'form2-text1'. However, there is a major drawback to this: This also changes the name elements in such a way that they are in the format formname[elementname]. Therefore $this->getRequest()->getParam('formname') will return an associative array containing the form elements.

How to set a my own form representation for my own type

I have created my own form type in my Symfony 2 project whose a child of the date type. I call it in the controller :
$form = $this->createFormBuilder($customer)
->add('my_own_field_name', 'my_own_date_type', array())
->getForm();
In the twig template :
{{form_row(form.my_own-field_name)}}
Is it possible to say to Symfony2 to call my own twig for a representation of this field through the 'form_row' function instead of having the date type representation
Thank you
Consider having a look at this part of the official SF2 documentation.
As told in the doc, the getName method of your custom type helps SF2 find a custom form renderer. As your type name is my_date_type, SF2 will try to look for a my_date_type_widget block in a configured form templates list (as shown at the end of this post and in the official doc).
You just have to create a template fields.html.twig in your bundle resources/views/Form/ folder that specifies this block as shown in the doc and add your own logic in it.
Don't forget to add the config lines
# app/config/config.yml
twig:
form:
resources:
- 'YourOwnBundle:Form:fields.html.twig'
to tell symfony to always use this to render this form type.

symfony2 twig render form 'choice' as list

How can I (in symfony2 twig) render the form control 'choice' (expanded, checkboxes) as list ('li's, or just with a 'br' inbetwwen each option) and not have all options appear on one line?
I guess I could bach a jQuery together, but isn't there a more native way?
You can override the appropriate theme block. There is a great description in the docs how to do that.

How to remove a validator from a Select?

I have a form where I need to add/remove validators dynamically. Based on a dropdown selection, other form fields may have different validation rules.
For other kinds of inputs, I've used replace(methodThatCreatesTheInput()) to get rid of a previously added validator. (Not knowing of a better way. Specifically, there doesn't seem to be any way to directly remove a validator from a component...)
With Select, from wicket-extensions, this approach fails with something like:
WicketMessage: submitted http post value [[Ljava.lang.String;#5b4bf56d]
for SelectOption component [8:myForm:targetInput] contains an
illegal relative path element [targetConsortiums:1:option] which does not
point to an SelectOption component. Due to this the Select component cannot
resolve the selected SelectOption component pointed to by the illegal value.
A possible reason is that component hierarchy changed between rendering and
form submission.
The method that creates the Select:
private FormComponent<?> targetSelection() {
Map<Class<? extends Target>, List<Target>> targets = targetService.getAllAsMap();
SelectOptions<Target> propertyOptions = new SelectOptions<Target>("targetConsortiums",
targets.get(Consortium.class), new TargetRenderer());
SelectOptions<Target> consortiumOptions = new SelectOptions<Target>("targetProperties",
targets.get(Property.class), new TargetRenderer());
Select select = new Select(ID_TARGET, new PropertyModel<Target>(model, "target"));
select.add(propertyOptions);
select.add(consortiumOptions);
select.setRequired(true);
select.setMarkupId(ID_TARGET);
return select;
}
(Why use a Select instead of normal DropDownChoice? We want the two types of choices to be clearly separated, as documented in this question.)
Any ideas how to solve this? What I'm trying to achieve is, of course, very simple. Unfortunately Wicket disagrees, or I'm using it wrong.
Wicket 1.4.
I don't know how to do this on Wicket 1.4, but on Wicket 1.5 there is a remove method for validators on FormComponent (see javadoc)