Bug #93527
closedAssigned form-object does not overwrite default-values
0%
Description
In the documentation of input viewhelpers of a form, it states "If used in conjunction with <f:form object='…'>, 'name' and 'value' properties will be ignored."
However only the name property is getting ignored. The (default) value attribute overwrites whatever the assigned object contains.
Testcase:
<f:form name="object" object="{object}">
With default value: <f:form.textfield type="text" property="withDefaultValue" value="Defaultvalue"/><br/>
Only default value: <f:form.textfield type="text" property="onlyDefaultValue" value="Defaultvalue"/><br/>
No default value: <f:form.textfield type="text" property="noDefaultValue" /><br/>
</f:form>
public function showAction() {
$this->view->assign('object', [
"withDefaultValue" => "Value from object",
"noDefaultValue" => "Value from object",
]);
}
Expected result:
Actual result:
Files
Updated by Ralf Zimmermann about 3 years ago
- Category changed from Form Framework to Fluid
Updated by David Henninger about 3 years ago
I think the issue lies with both getValueAttribute and getValueFromSubmittedFormData of \TYPO3\CMS\Fluid\ViewHelpers\Form\AbstractFormFieldViewHelper.
Here is the excerpt of getValueAttribute, with getValueFromSubmittedFormData being very similar:
/**
* Returns the current value of this Form ViewHelper and converts it to an identifier string in case it's an object
* The value is determined as follows:
* * If property mapping errors occurred and the form is re-displayed, the *last submitted* value is returned
* * Else the bound property is returned (only in objectAccessor-mode)
* * As fallback the "value" argument of this ViewHelper is used
*
* Note: This method should *not* be used for form elements that must not change the value attribute, e.g. (radio) buttons and checkboxes.
*
* @return mixed Value
*/
protected function getValueAttribute()
{
$value = null;
if ($this->respectSubmittedDataValue) {
$value = $this->getValueFromSubmittedFormData($value);
} elseif ($this->hasArgument('value')) {
$value = $this->arguments['value'];
} elseif ($this->isObjectAccessorMode()) {
$value = $this->getPropertyValue();
}
$value = $this->convertToPlainValue($value);
return $value;
}
The order is simply wrong and the value-attribute gets preferential treatment over the assigned object property. The description of the method itself already states the correct and expected order:
- Previously submitted value
- Mapped value through assigned object
- Value attribute
EDIT:
Just switching the order doesn't fix this tho, as the check isObjectAccessorMode always returns true when the name of a form is set:
/**
* Internal method which checks if we should evaluate a domain object or just output arguments['name'] and arguments['value']
*
* @return bool TRUE if we should evaluate the domain object, FALSE otherwise.
*/
protected function isObjectAccessorMode() {
return $this->hasArgument('property') && $this->renderingContext->getViewHelperVariableContainer()->exists(
\TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper::class,
'formObjectName'
);
}
Despite the description, it never actually checks whether an object has been assigned. So it should actually check for the formObject and not the formObjectName, at least in this case...
Updated by Andreas Kiessling 8 months ago
The value attribute seems to still override the assigned property in 11.5 and 12.4 :/
I don't see a usecase for that order but would love to have it the other way around, so i can easily set a default value in fluid without having a lot of conditions or php code
Updated by Simon Praetorius 7 months ago
- Is duplicate of Bug #99243: Wrong behaviour when using property and value together added
Updated by Simon Praetorius 7 months ago
- Status changed from New to Closed
Closing this as duplicate of #99243.
As I mentioned on Gerrit, there are valid use cases for this:
One possible use case for this I can think of is a form to edit a user. For the password field you would want to define property="password", but also value="" to not expose the current password hash to the form.