-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[2.2] [Form] Enhanced DateType with support for different widgets types per date part (year, month, day) #3825
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
Conversation
Interesting ideas! Scheduled for POST-2.1. |
@ruimarinho The |
@fabpot, I'm going to setup a quick test page since the project where we needed this is running 2.1-dev and, since it's a seasonal project, it's not going to be upgraded to 2.1 beta or even 2.1 stable. I'll remove the |
@ruimarinho Can you rebase this PR and update it according to the comments ? |
@stof done - code fixed, including tests which have been rectified and are now passing. Removed the I'm going to add a new test case tomorrow to assert the validation of the widgets defined via the array notation. I look forward for your comments to see if I can improve that small code block using solely the |
@bschussek Can we included this in 2.2? |
@fabpot Yes we can, I really like this. @ruimarinho Can you move the normalization of the "widget" option to an option normalizer? Basically you can do it the same way as in the Furthermore, if we do this for |
To be precise, the same should be added to |
@bschussek I have moved the Regarding An example of what I have in mind: $builder->add('date', 'datetime', array(
'date_widget' => array(
'year' => 'text',
'month' => 'text',
'day' => 'choice'
),
'date_options' => array(
'year' => array('attr' => array(
'data-mask' => 'yyyy'
))
)
)); |
$partOptions[$passOpt] = $options[$passOpt]; | ||
} | ||
|
||
$builder->add($part, $widget, $partOptions); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this code change have any benefit? I think it is more complicated to read than the previous version and does not really add anything.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be more elegant to simply split the original if into three if-statements:
if ('choice' === $options['widget']['year']) {
$yearOptions['choices'] = $this->formatTimestamps($formatter, '/y+/', $this->listYears($options['years']));
$yearOptions['empty_value'] = $options['empty_value']['year'];
}
if ('choice' === $options['widget']['year']) {
$monthOptions['choices'] = $this->formatTimestamps($formatter, '/M+/', $this->listMonths($options['months']));
$monthOptions['empty_value'] = $options['empty_value']['month'];
}
if ('choice' === $options['widget']['year']) {
$dayOptions['choices'] = $this->formatTimestamps($formatter, '/d+/', $this->listDays($options['days']));
$dayOptions['empty_value'] = $options['empty_value']['day'];
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was looking to avoid verbosity, but I guess at the cost of clarity. Reverted back to original if-statements structure.
Your last question is a good one. Apparently we currently use several different ways of passing options to fields: (a) By introducing dedicated options $builder->add('date', 'datetime', array(
'date_widget' => ...,
)); (b) By letting existing options accept arrays $builder->add('date', 'date', array(
'empty_value' => array(
'day' => ...,
),
)); (c) By letting the user pass all options himself $builder->add('password', 'repeated', array(
'first_options' => ...,
)); I think we should clean this up, but the question is how. |
The most efficient and flexible way is definitely (c), but it clutters up the API a bit. So instead of $builder->add('date', 'datetime', array(
'date_widget' => 'choice',
)); you'd then write $builder->add('date', 'datetime', array(
'date_options' => array(
'widget' => 'choice',
),
)); or $builder->add('date', 'datetime', array(
'date_options' => array(
'month_options' => array(
'widget' => 'choice',
),
),
)); if you want to have even more fine-grained control, which is a little less concise than (a theoretical) $builder->add('date', 'datetime', array(
'widget' => array(
'date' => array(
'month' => 'choice',
),
),
)); or even $builder->add('date', 'datetime', array(
'widget' => array(
'month' => 'choice',
),
)); What do you think? |
…pes per date/time part
I actually noticed that and I even got confused when accessing the values to merge the widget part options ( Regarding the different options you presented: a) Looks concise and practical, but not very extensible. As the widgets get more complex, the harder it gets to maintain this facade. b) This option requires you to learn about which options can accept an array structure. Unless we can assure we always offer support for this kind of structure, I don't think it is as practical as option a). Plus, on the c) More verbose but also more explicit. Users should not have to learn anything new if they already know how to use the A more complex example that didn't feel awkward to write: $builder->add('date', 'datetime', array(
'date' => array(
'widget' => array(
'year' => 'text',
'month' => 'text',
'day' => 'choice'
),
'options' => array(
'year' => array(
'attr' => array(
'data-mask' => 'yyyy'
)
),
'month' => array(
'attr' => array(
'data-month' => 'MM'
)
),
'day' => array(
'attr' => array(
'data-day' => 'dd'
)
)
)
),
'time' => array(
'widget' => array(
'hour' => 'text',
'minute' => 'choice',
'seconds' => 'choice'
),
'hours' => range(0, 12),
'empty_value' => array(
'hour' => 10,
'minute' => 20,
'seconds' => 30
)
)
)); I also think $builder->add('time', 'time', array(
'data' => array(
'hour' => range(0, 12)
)
)); What do you think? |
Let's save the question about the Your API sample is ambiguous. First, you renamed Second, you nested a key I'm alright with solution c) but we need to decide whether to name the options |
Closed in favor of #9177 |
Bug fix: yes
Feature addition: yes
Backwards compatibility break: no
Symfony2 tests pass:
Fixes the following tickets: #3490
Todo: discuss with @bschussek if it is possible to add support for padded dates per date type (not just globally, as it is now).
The DateType widget is incredibly powerful it offers developers a wealth of features and customization options. This PR builds on this work and adds some extra flexibility to this widget, without compromising BC:
Features:
widget
option now accepts an array foryear
,month
andday
date parts, which allows you to have something like achoice
widget formonth
andtext
widgets foryear
andday
. It defaults tochoice
if any of those parts is missing when using the array format.year_options
,month_options
andday_options
. A typical use case is passing an attribute likedata-mask
to control user input client side using JavaScript masks.DateTimeToArrayTransformer
defaults to not pad dates. What happens is that when usingchoice
widgets, the value is casted to int and it removes the padding, but the representation on the HTML still shows the padded date. This PR changes this by passing the correct padding option to the transform so that the output is either completely padded or not (both thevalue
and its representation). This can be passed through the widgetoptions
option (padded
: boolean).Tests were added for these new features.