[TYPO3-mvc] Multiple Checkboxes for an object in a form
Franz Koch
typo3.RemoveForMessage at elements-net.de
Tue Nov 9 15:48:10 CET 2010
Hey,
>> Of which type is your categories property?
> It is an object storage but I use the "getMailCategoriesAsArray()" and
> method in the domain model to return a key-value array (i.e. the uid is
> the key, the title the value). The "setMailCategoriesAsArray()" takes an
> array of ids and (un-)links modified objects.
> Usually this should work.(?) The unexpected behavior occurs in the form
> validation with a messed up HMAC.
Ah, ok, then yes - that could interfere with the HMAC, but it actually
shouldn't as long as you use the viewHelpers to build the form fields.
>> Have you tried that approach by binding the checkbox to the property
>> instead?
>
> Yep. But I don't see how this should work. The only values shown are
> those that are already linked to the specific instance of the address. I
> could preselect all categories, but that is not really what I want.
> Additionally it would not be possible to subscribe to additional
> categories later on.
I think you got me wrong on this one. You traverse a custom
viewHelperVariable containing ALL selectable categories and build the
checkboxes for those. But those checkboxes are bound to your property
<f:for each="{allAvailableCategories}" as="category">
<f:form.checkbox property="categories" ... />
</f:for>
But as your property is of type objectStorage it won't work for you with
the default checkboxViewHelper. But that's what I do. This way, the
preselection is not bound to the already related category of the
subscription object and you can do the preselection however you like.
> Btw. I'm working with Fluid 1.2.0 and Exbase 1.2.0 - the versions
> shipped with TYPO3 4.4. I would have tried SVN trunk, but the mailing
> list states it was broken at this time.
Yepp, it's currently broken, but it should be fixed tomorrow after the
commit of the dispatcher refactoring.
>> Of course. Just yesterday I created a form where visitors can order
>> brochures and the selection is done via checkboxes (my custom
>> checkboxViewHelper allowing objectStorages though). For me your code
>> is working just fine, the only difference I have is that I bound the
>> checkbox to the property.
> I guess you did that by preselecting all brochures..?
No. As mentioned above, I fetched all selectable brochures from the
repository and assigned them to the view. Then I itterate over them and
create checkboxes bound to my object property.
My custom checkboxViewHelper looks like this:
--------------
> class Tx_ElementsExtbase_ViewHelpers_Form_CheckboxViewHelper extends Tx_Fluid_ViewHelpers_Form_CheckboxViewHelper {
>
> /**
> * Renders the checkbox.
> *
> * @param boolean $checked Specifies that the input element should be preselected
> *
> * @return string
> * @author Bastian Waidelich <###>
> * @author Franz Koch <###>
> * @api
> */
> public function render($checked = NULL) {
> $this->tag->addAttribute('type', 'checkbox');
>
> $nameAttribute = $this->getName();
> $valueAttribute = $this->getValue();
> if ($checked === NULL && $this->isObjectAccessorMode() && $this->viewHelperVariableContainer->exists('Tx_Fluid_ViewHelpers_FormViewHelper', 'formObject')) {
> $propertyValue = $this->getPropertyValue();
> if (is_bool($propertyValue)) {
> $checked = $propertyValue === (boolean)$valueAttribute;
> } else if ($propertyValue === NULL) {
> $checked = FALSE;
> } elseif (is_array($propertyValue) || $propertyValue instanceof Traversable) {
> if (method_exists($propertyValue, 'toArray')) {
> $propertyValue = $propertyValue->toArray();
> }
>
> if (gettype(current($propertyValue)) == 'object') {
> foreach($propertyValue as $object) {
> if (method_exists($object,'getUid') && $object->getUid() == $valueAttribute) {
> $checked = TRUE;
> break;
> } else if ($object->__toString() == $valueAttribute) {
> $checked = TRUE;
> break;
> }
> }
> } else {
> $checked = in_array($valueAttribute, $propertyValue);
> }
> $nameAttribute .= '[]';
> } else {
> throw new Tx_Fluid_Core_ViewHelper_Exception('Checkbox viewhelpers can only be bound to properties of type boolean or array. Property "' . $this->arguments['property'] . '" is of type "' . (is_object($propertyValue) ? get_class($propertyValue) : gettype($propertyValue)) . '".' , 1248261038);
> }
> }
>
> $this->registerFieldNameForFormTokenGeneration($nameAttribute);
> $this->tag->addAttribute('name', $nameAttribute);
> $this->tag->addAttribute('value', $valueAttribute);
> if ($checked) {
> $this->tag->addAttribute('checked', 'checked');
> }
>
> $this->setErrorClassAttribute();
>
> $hiddenField = $this->renderHiddenFieldForEmptyValue();
> return $hiddenField . $this->tag->render();
> }
> }
--------------
--
kind regards,
Franz Koch
More information about the TYPO3-project-typo3v4mvc
mailing list