Skip to content

Commit fdbf1fa

Browse files
committed
bug symfony#16351 [WIP] [Form] [TwigBridge] Bootstrap horizontal theme missing tests (pieter2627)
This PR was submitted for the 2.8 branch but it was merged into the 2.7 branch instead (closes symfony#16351). Discussion ---------- [WIP] [Form] [TwigBridge] Bootstrap horizontal theme missing tests | Q | A | ------------------ | --- | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | | License | MIT | Doc PR | The current bootstrap horizontal theme has a limitation where the inputs will always have `col-sm-2` class applied to them and the developer has no way on changing this when he wants larger/smaller labels or wants to target another screen size only. The same applies for the `div` around the `input`. PR checks if a label's class has a `col-*` class set and then uses it rather than the default so that the developer can change them as is needed. Again the same for the `div` by checking the `group_attr.class` This is my first contribution to Symfony and from the contribution docs I see that the following is still needed. ### ToDo - [ ] Create Doc and its PR - [ ] Edit `CHANGELOG???` For the Doc it seems best to edit `cookbook/form/form_customization.rst` and add another 'admonition' below the "built-in form themes" section that highlights this capability? I'm not sure what will go into the CHANGELOG? Commits ------- a35d3d4 [WIP] [Form] [TwigBridge] Bootstrap horizontal theme missing tests
2 parents 83f9ae0 + a35d3d4 commit fdbf1fa

File tree

3 files changed

+279
-6
lines changed

3 files changed

+279
-6
lines changed

src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_3_horizontal_layout.html.twig

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,13 @@ col-sm-2
2525
{# Rows #}
2626

2727
{% block form_row -%}
28-
{% spaceless %}
2928
<div class="form-group{% if (not compound or force_error|default(false)) and not valid %} has-error{% endif %}">
30-
{{ form_label(form) }}
29+
{{- form_label(form) -}}
3130
<div class="{{ block('form_group_class') }}">
32-
{{ form_widget(form) }}
33-
{{ form_errors(form) }}
31+
{{- form_widget(form) -}}
32+
{{- form_errors(form) -}}
3433
</div>
35-
</div>
36-
{% endspaceless %}
34+
{##}</div>
3735
{%- endblock form_row %}
3836

3937
{% block checkbox_row -%}
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bridge\Twig\Tests\Extension;
13+
14+
use Symfony\Bridge\Twig\Extension\FormExtension;
15+
use Symfony\Bridge\Twig\Form\TwigRenderer;
16+
use Symfony\Bridge\Twig\Form\TwigRendererEngine;
17+
use Symfony\Bridge\Twig\Extension\TranslationExtension;
18+
use Symfony\Bridge\Twig\Tests\Extension\Fixtures\StubTranslator;
19+
use Symfony\Bridge\Twig\Tests\Extension\Fixtures\StubFilesystemLoader;
20+
use Symfony\Component\Form\FormView;
21+
use Symfony\Component\Form\Tests\AbstractBootstrap3HorizontalLayoutTest;
22+
23+
class FormExtensionBootstrap3HorizontalLayoutTest extends AbstractBootstrap3HorizontalLayoutTest
24+
{
25+
/**
26+
* @var FormExtension
27+
*/
28+
protected $extension;
29+
30+
protected $testableFeatures = array(
31+
'choice_attr',
32+
);
33+
34+
protected function setUp()
35+
{
36+
parent::setUp();
37+
38+
$rendererEngine = new TwigRendererEngine(array(
39+
'bootstrap_3_horizontal_layout.html.twig',
40+
'custom_widgets.html.twig',
41+
));
42+
$renderer = new TwigRenderer($rendererEngine, $this->getMock('Symfony\Component\Security\Csrf\CsrfTokenManagerInterface'));
43+
44+
$this->extension = new FormExtension($renderer);
45+
46+
$loader = new StubFilesystemLoader(array(
47+
__DIR__.'/../../Resources/views/Form',
48+
__DIR__.'/Fixtures/templates/form',
49+
));
50+
51+
$environment = new \Twig_Environment($loader, array('strict_variables' => true));
52+
$environment->addExtension(new TranslationExtension(new StubTranslator()));
53+
$environment->addExtension($this->extension);
54+
55+
$this->extension->initRuntime($environment);
56+
}
57+
58+
protected function tearDown()
59+
{
60+
parent::tearDown();
61+
62+
$this->extension = null;
63+
}
64+
65+
protected function renderForm(FormView $view, array $vars = array())
66+
{
67+
return (string) $this->extension->renderer->renderBlock($view, 'form', $vars);
68+
}
69+
70+
protected function renderEnctype(FormView $view)
71+
{
72+
return (string) $this->extension->renderer->searchAndRenderBlock($view, 'enctype');
73+
}
74+
75+
protected function renderLabel(FormView $view, $label = null, array $vars = array())
76+
{
77+
if ($label !== null) {
78+
$vars += array('label' => $label);
79+
}
80+
81+
return (string) $this->extension->renderer->searchAndRenderBlock($view, 'label', $vars);
82+
}
83+
84+
protected function renderErrors(FormView $view)
85+
{
86+
return (string) $this->extension->renderer->searchAndRenderBlock($view, 'errors');
87+
}
88+
89+
protected function renderWidget(FormView $view, array $vars = array())
90+
{
91+
return (string) $this->extension->renderer->searchAndRenderBlock($view, 'widget', $vars);
92+
}
93+
94+
protected function renderRow(FormView $view, array $vars = array())
95+
{
96+
return (string) $this->extension->renderer->searchAndRenderBlock($view, 'row', $vars);
97+
}
98+
99+
protected function renderRest(FormView $view, array $vars = array())
100+
{
101+
return (string) $this->extension->renderer->searchAndRenderBlock($view, 'rest', $vars);
102+
}
103+
104+
protected function renderStart(FormView $view, array $vars = array())
105+
{
106+
return (string) $this->extension->renderer->renderBlock($view, 'form_start', $vars);
107+
}
108+
109+
protected function renderEnd(FormView $view, array $vars = array())
110+
{
111+
return (string) $this->extension->renderer->renderBlock($view, 'form_end', $vars);
112+
}
113+
114+
protected function setTheme(FormView $view, array $themes)
115+
{
116+
$this->extension->renderer->setTheme($view, $themes);
117+
}
118+
}
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Form\Tests;
13+
14+
abstract class AbstractBootstrap3HorizontalLayoutTest extends AbstractBootstrap3LayoutTest
15+
{
16+
public function testLabelOnForm()
17+
{
18+
$form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\DateType');
19+
$view = $form->createView();
20+
$this->renderWidget($view, array('label' => 'foo'));
21+
$html = $this->renderLabel($view);
22+
23+
$this->assertMatchesXpath($html,
24+
'/label
25+
[@class="col-sm-2 control-label required"]
26+
[.="[trans]Name[/trans]"]
27+
'
28+
);
29+
}
30+
31+
public function testLabelDoesNotRenderFieldAttributes()
32+
{
33+
$form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\TextType');
34+
$html = $this->renderLabel($form->createView(), null, array(
35+
'attr' => array(
36+
'class' => 'my&class',
37+
),
38+
));
39+
40+
$this->assertMatchesXpath($html,
41+
'/label
42+
[@for="name"]
43+
[@class="col-sm-2 control-label required"]
44+
'
45+
);
46+
}
47+
48+
public function testLabelWithCustomAttributesPassedDirectly()
49+
{
50+
$form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\TextType');
51+
$html = $this->renderLabel($form->createView(), null, array(
52+
'label_attr' => array(
53+
'class' => 'my&class',
54+
),
55+
));
56+
57+
$this->assertMatchesXpath($html,
58+
'/label
59+
[@for="name"]
60+
[@class="my&class col-sm-2 control-label required"]
61+
'
62+
);
63+
}
64+
65+
public function testLabelWithCustomTextAndCustomAttributesPassedDirectly()
66+
{
67+
$form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\TextType');
68+
$html = $this->renderLabel($form->createView(), 'Custom label', array(
69+
'label_attr' => array(
70+
'class' => 'my&class',
71+
),
72+
));
73+
74+
$this->assertMatchesXpath($html,
75+
'/label
76+
[@for="name"]
77+
[@class="my&class col-sm-2 control-label required"]
78+
[.="[trans]Custom label[/trans]"]
79+
'
80+
);
81+
}
82+
83+
public function testLabelWithCustomTextAsOptionAndCustomAttributesPassedDirectly()
84+
{
85+
$form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\TextType', null, array(
86+
'label' => 'Custom label',
87+
));
88+
$html = $this->renderLabel($form->createView(), null, array(
89+
'label_attr' => array(
90+
'class' => 'my&class',
91+
),
92+
));
93+
94+
$this->assertMatchesXpath($html,
95+
'/label
96+
[@for="name"]
97+
[@class="my&class col-sm-2 control-label required"]
98+
[.="[trans]Custom label[/trans]"]
99+
'
100+
);
101+
}
102+
103+
public function testStartTag()
104+
{
105+
$form = $this->factory->create('Symfony\Component\Form\Extension\Core\Type\FormType', null, array(
106+
'method' => 'get',
107+
'action' => 'http://example.com/directory',
108+
));
109+
110+
$html = $this->renderStart($form->createView());
111+
112+
$this->assertSame('<form name="form" method="get" action="http://example.com/directory" class="form-horizontal">', $html);
113+
}
114+
115+
public function testStartTagWithOverriddenVars()
116+
{
117+
$form = $this->factory->create('Symfony\Component\Form\Extension\Core\Type\FormType', null, array(
118+
'method' => 'put',
119+
'action' => 'http://example.com/directory',
120+
));
121+
122+
$html = $this->renderStart($form->createView(), array(
123+
'method' => 'post',
124+
'action' => 'http://foo.com/directory',
125+
));
126+
127+
$this->assertSame('<form name="form" method="post" action="http://foo.com/directory" class="form-horizontal">', $html);
128+
}
129+
130+
public function testStartTagForMultipartForm()
131+
{
132+
$form = $this->factory->createBuilder('Symfony\Component\Form\Extension\Core\Type\FormType', null, array(
133+
'method' => 'get',
134+
'action' => 'http://example.com/directory',
135+
))
136+
->add('file', 'Symfony\Component\Form\Extension\Core\Type\FileType')
137+
->getForm();
138+
139+
$html = $this->renderStart($form->createView());
140+
141+
$this->assertSame('<form name="form" method="get" action="http://example.com/directory" class="form-horizontal" enctype="multipart/form-data">', $html);
142+
}
143+
144+
public function testStartTagWithExtraAttributes()
145+
{
146+
$form = $this->factory->create('Symfony\Component\Form\Extension\Core\Type\FormType', null, array(
147+
'method' => 'get',
148+
'action' => 'http://example.com/directory',
149+
));
150+
151+
$html = $this->renderStart($form->createView(), array(
152+
'attr' => array('class' => 'foobar'),
153+
));
154+
155+
$this->assertSame('<form name="form" method="get" action="http://example.com/directory" class="foobar form-horizontal">', $html);
156+
}
157+
}

0 commit comments

Comments
 (0)