Skip to content

Commit 4dd93aa

Browse files
committed
feature #239 add a custom form field type example (yceruto)
This PR was merged into the master branch. Discussion ---------- add a custom form field type example **The first purpose** of this PR is to provide a practical example of how to create a custom form field type. **The second purpose** is to improve the user interface to the field "Published At" on edit a Post, using a JavaScript date library like bootstrap-datetimepicker for parsing, validating, manipulating, and formatting dates. http://eonasdan.github.io/bootstrap-datetimepicker. >**Important:** Is not the purpose of this PR create a custom form field type to support all options and features of the datetimepicker plugin. References: * http://symfony.com/doc/current/cookbook/create_custom_field_type.html * http://symfony.com/doc/current/best_practices/forms.html#custom-form-field-types Main Topics: * Defining the custom form Field Type. * Creating your form Field Type as a Service. * Creating a Template for the custom form field Type * Configuring the custom form template. * Initializing datetime picker JavaScript plugin. * Using the form Field Type into PostType form. Others Topics (refactor): * Moving the initialization of the highligth JavaScript plugin for `main.js` file. **Preview:** ![datetimepicker](https://cloud.githubusercontent.com/assets/2028198/10723013/d1930664-7b8c-11e5-9409-ec8b369a1c2f.png) Commits ------- d8376ea add a custom form field type example
2 parents b4f82a7 + d8376ea commit 4dd93aa

File tree

13 files changed

+283
-13
lines changed

13 files changed

+283
-13
lines changed

app/Resources/assets/css/bootstrap-datetimepicker.min.css

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/Resources/assets/js/bootstrap-datetimepicker.min.js

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/Resources/assets/js/main.js

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,28 @@
77
* file that was distributed with this source code.
88
*/
99

10-
/**
11-
* Handling the modal confirmation message.
12-
*/
1310
(function ($) {
11+
$(document).ready(function () {
12+
hljs.initHighlightingOnLoad();
13+
14+
// Datetime picker initialization.
15+
// See http://eonasdan.github.io/bootstrap-datetimepicker/
16+
$('[data-toggle="datetimepicker"]').datetimepicker({
17+
icons: {
18+
time: 'fa fa-clock-o',
19+
date: 'fa fa-calendar',
20+
up: 'fa fa-chevron-up',
21+
down: 'fa fa-chevron-down',
22+
previous: 'fa fa-chevron-left',
23+
next: 'fa fa-chevron-right',
24+
today: 'fa fa-check-circle-o',
25+
clear: 'fa fa-trash',
26+
close: 'fa fa-remove'
27+
}
28+
});
29+
});
30+
31+
// Handling the modal confirmation message.
1432
$(document).on('submit', 'form[data-confirmation]', function (event) {
1533
var $form = $(this),
1634
$confirm = $('#confirmationModal');

app/Resources/assets/js/moment.min.js

Lines changed: 80 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/Resources/views/base.html.twig

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -143,21 +143,16 @@
143143
{# uncomment the following lines to combine and minimize JavaScript assets with Assetic
144144
{% javascripts filter="?jsqueeze" output="js/app.js"
145145
"%kernel.root_dir%/Resources/assets/js/jquery-2.1.4.js"
146+
"%kernel.root_dir%/Resources/assets/js/moment.min.js"
146147
"%kernel.root_dir%/Resources/assets/js/bootstrap-3.3.4.js"
147148
"%kernel.root_dir%/Resources/assets/js/highlight.pack.js"
149+
"%kernel.root_dir%/Resources/assets/js/bootstrap-datetimepicker.min.js"
148150
"%kernel.root_dir%/Resources/assets/js/main.js" %}
149151
<script src="{{ asset_url }}"></script>
150152
{% endjavascripts %}
151153
#}
152154

153155
<script src="{{ asset('js/app.js') }}"></script>
154-
155-
<script>
156-
$(document).ready(function() {
157-
hljs.initHighlightingOnLoad();
158-
});
159-
</script>
160156
{% endblock %}
161-
162157
</body>
163158
</html>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{#
2+
Each field type is rendered by a template fragment, which is determined
3+
by the value of your getName() method and the suffix _widget.
4+
5+
See http://symfony.com/doc/current/cookbook/form/create_custom_field_type.html#creating-a-template-for-the-field
6+
#}
7+
8+
{% block app_datetimepicker_widget %}
9+
{% spaceless %}
10+
<div class="input-group date" data-toggle="datetimepicker">
11+
{{ block('datetime_widget') }}
12+
<span class="input-group-addon">
13+
<span class="fa fa-calendar"></span>
14+
</span>
15+
</div>
16+
{% endspaceless %}
17+
{% endblock %}

app/config/config.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ twig:
5252
strict_variables: "%kernel.debug%"
5353
form_themes:
5454
- "bootstrap_3_layout.html.twig"
55+
- "form/fields.html.twig"
5556

5657
# Assetic Configuration (used for managing web assets: CSS, JavaScript, Sass, etc.)
5758
assetic:

app/config/services.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ services:
2828
tags:
2929
- { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }
3030

31+
app.form.type.datetimepicker:
32+
class: AppBundle\Form\Type\DateTimePickerType
33+
tags:
34+
- { name: form.type, alias: app_datetimepicker }
35+
3136
# Uncomment the following lines to define a service for the Post Doctrine repository.
3237
# It's not mandatory to create these services, but if you use repositories a lot,
3338
# these services simplify your code:

src/AppBundle/Form/PostType.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,7 @@ public function buildForm(FormBuilderInterface $builder, array $options)
4949
'label' => 'label.content',
5050
))
5151
->add('authorEmail', 'email', array('label' => 'label.author_email'))
52-
->add('publishedAt', 'datetime', array(
53-
'widget' => 'single_text',
52+
->add('publishedAt', 'app_datetimepicker', array(
5453
'label' => 'label.published_at',
5554
))
5655
;
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
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 AppBundle\Form\Type;
13+
14+
use AppBundle\Utils\MomentFormatConverter;
15+
use Symfony\Component\Form\AbstractType;
16+
use Symfony\Component\Form\FormInterface;
17+
use Symfony\Component\Form\FormView;
18+
use Symfony\Component\OptionsResolver\OptionsResolver;
19+
20+
/**
21+
* Defines the custom form field type used to manipulate datetime values across
22+
* Bootstrap Date\Time Picker javascript plugin.
23+
* See http://symfony.com/doc/current/cookbook/create_custom_field_type.html
24+
*
25+
* @author Yonel Ceruto <yonelceruto@gmail.com>
26+
*/
27+
class DateTimePickerType extends AbstractType
28+
{
29+
/**
30+
* @var MomentFormatConverter
31+
*/
32+
private $formatConverter;
33+
34+
public function __construct()
35+
{
36+
$this->formatConverter = new MomentFormatConverter();
37+
}
38+
39+
/**
40+
* {@inheritdoc}
41+
*/
42+
public function buildView(FormView $view, FormInterface $form, array $options)
43+
{
44+
$view->vars['attr']['data-date-format'] = $this->formatConverter->convert($options['format']);;
45+
$view->vars['attr']['data-date-locale'] = \Locale::getDefault();
46+
}
47+
48+
/**
49+
* {@inheritdoc}
50+
*/
51+
public function configureOptions(OptionsResolver $resolver)
52+
{
53+
$resolver->setDefaults(array(
54+
'widget' => 'single_text',
55+
));
56+
}
57+
58+
/**
59+
* {@inheritdoc}
60+
*/
61+
public function getParent()
62+
{
63+
return 'datetime';
64+
}
65+
66+
/**
67+
* {@inheritdoc}
68+
*/
69+
public function getName()
70+
{
71+
return 'app_datetimepicker';
72+
}
73+
}

0 commit comments

Comments
 (0)