Skip to content
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

Broken date after widget formats the date after form submission #91

Open
atrandafir opened this issue Aug 13, 2020 · 2 comments
Open

Broken date after widget formats the date after form submission #91

atrandafir opened this issue Aug 13, 2020 · 2 comments
Labels

Comments

@atrandafir
Copy link

What steps will reproduce the problem?

You create a form and you set the date format to 'dateFormat' => 'php:d/m/Y',.

Then you click the input and select 1 august 2020, and you get 01/08/2020 with the format specified, everything good.

The problem is if you then submit the form and stay on the same page (ej: some form validation fails), the widget will get 01/08/2020 value from the form and then re-format it, as it is here:

https://github.com/yiisoft/yii2-jui/blob/master/src/DatePicker.php#L179

if ($value !== null && $value !== '') {
	// format value according to dateFormat
	try {
		$value = Yii::$app->formatter->asDate($value, $this->dateFormat);
	} catch(InvalidParamException $e) {
		// ignore exception and keep original value if it is not a valid date
	}
}

And you end up with this date in the input: 08/01/2020.

My feedback:

It looks like I have to manually reparse the date value to a different format, eg: Y-m-d, before rendering the datepicker after the model has been filled with post data.

What's expected?

To keep 01/08/2020.

What do you get instead?

Re-formatted date 08/01/2020.

Additional info

Q A
Yii vesion 2.0.29
PHP version 7.3.6
Operating system Windows
@samdark samdark added the type:bug Bug label Aug 14, 2020
@samdark
Copy link
Member

samdark commented Aug 14, 2020

That's definitely not desired behavior. Any idea on how to fix it?

@atrandafir
Copy link
Author

atrandafir commented Aug 17, 2020

Well in my case I did a workaround without having to modify the widget's code.

Basically I'm re-converting the date to Y-m-d after the attributes were set, inside model's setAttributes, so next time the page renders if the validation falied, the format is Y-m-d again and the widget converts it to the desired format.

But I think it is not the best solution.

The solution I think is best, and should be adopted is to actually remove the part with the formatting of the value from inside the widget.

I mean:

  • The widget should never format the value, it's the developer's job to prepare the value to that format before calling the widget.

And if you look at Yii 1's DatePicker, you can specify a date format (for the javascript option), but the widget never formats the value to that format, it expects the value to be already formatted like that:

https://github.com/yiisoft/yii/blob/master/framework/zii/widgets/jui/CJuiDatePicker.php

So if we remove the formatting from the widget:

  • If you have a form based only on Model (without DB), and you post it, the widget will work properly, on all the page renders
  • If you have a form based on ActiveRecord model retrieved from DB:
    • A) If you use a MySQL date field such as Y-m-d, then you set the Widget to that format and all is working well, no conversion needed
    • B) If you want to use a different format for the user, let's say d/m/Y, then, from the controller you should convert your Y-m-d to d/m/Y before rendering, and then, after post is made and validation is passed, before saving you should convert back the d/m/Y to Y-m-d
    • C) Same goes if you save your date inside an INT field in the database, conversion will be required before rendering the form

Of course some of the conversions could be inside the model's methods such as afterFind and beforeSave, but I personally think it is safer to do it manually inside the controller only when working with a form that will affect the date fields. Because if you put the code inside afterFind and beforeSave, it will be called always even if you're not working with a form. And I personally don't want my model's date fields to be converted to user friendly format always, just in the cases when I need them to.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants