• This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn more.

As designed  Inability To Clear Option With PHP Callback

digitalpoint

Well-known member
#1
If I have an option that is an array (checkboxes) with a PHP Callback, the $preparedOption variable passed to the method will include the last value if you uncheck it. Every other combination works (you can select any checkboxes you want), except if you uncheck them all. If you uncheck them all, $preparedOption['option_value'] still has a value (whatever the last item checked was). So it makes it so you can't uncheck all checkboxes for the array option.
 

digitalpoint

Well-known member
#3
The callback I'm using is to this file (obviously just one method, so the PHP Callback on the option is DigitalPointAdPositioning_Option_UsergroupSelector::renderOption:

PHP:
<?php

abstract class DigitalPointAdPositioning_Option_UsergroupSelector
{
/**
* Renders the usergroup chooser option.
*
* @param XenForo_View $view View object
* @param string $fieldPrefix Prefix for the HTML form field name
* @param array $preparedOption Prepared option info
* @param boolean $canEdit True if an "edit" link should appear
*
* @return XenForo_Template_Abstract Template object
*/
public static function renderOption(XenForo_View $view, $fieldPrefix, array $preparedOption, $canEdit)
{
$preparedOption['formatParams'] = array();
$usergroups = XenForo_Model::create('XenForo_Model_UserGroup')->getAllUserGroups();

foreach ($usergroups as $key => $usergroup) {
$preparedOption['options'][$usergroup['user_group_id']] = array('name' => $usergroup['title'], 'checked' => in_array($usergroup['user_group_id'], $preparedOption['option_value']));
}

return XenForo_ViewAdmin_Helper_Option::renderOptionTemplateInternal(
'option_template_AdPositioning_MultiSelect',
$view, $fieldPrefix, $preparedOption, $canEdit
);
}
}
The option_template_AdPositioning_MultiSelect admin template is as follows:

Code:
<xen:controlunit label="{$preparedOption.title}" hint="{$preparedOption.hint}">
<xen:explain>{xen:raw $preparedOption.explain}</xen:explain>
<xen:html>
<ul>
<xen:foreach loop="$preparedOption.options" key="$key" value="$item">
<li><label for="ctrl_options{$preparedOption.option_id}_{$key}"><input type="checkbox" name="options[{$preparedOption.option_id}][]" value="{$key}" id="ctrl_options{$preparedOption.option_id}_{$key}"<xen:if is="{$item.checked}">checked="checked"</xen:if> /> {$item.name}</label></li>
</xen:foreach>
</ul>
{xen:raw $editLink}
</xen:html>
</xen:controlunit>
As mentioned in the first post, it works fine unless you try to unselect all checkboxes, at which point, the last value will "stick". I tried to find some sort of "clear if null parameter" I missed, but no such luck...

Edit: No idea why tabs are getting stripped out... yuck! lol
 

Kier

XenForo Developer
Staff member
#5
The reason for this is that we only update options that are detected as having submitted data via POST. In this way we can be very flexible in our option grouping.

In the case of checkboxes, some genius at the W3C decided that they should submit no data whatsoever if they are unchecked, so we are unable to detect that they have been submitted and as a result we don't save the option if nothing is checked.

To work around this, we have a special hidden field that instructs the system that an option is present, even if the controls for the option submit no data. You can see it in use in the XenForo option_list_option_checkbox admin template.

Here is your template, updated to make use of it (immediately before the $editLink):
HTML:
<xen:controlunit label="{$preparedOption.title}" hint="{$preparedOption.hint}">
	<xen:explain>{xen:raw $preparedOption.explain}</xen:explain>
	<xen:html>
		<ul>
			<xen:foreach loop="$preparedOption.options" key="$key" value="$item">
				<li><label for="ctrl_options{$preparedOption.option_id}_{$key}"><input type="checkbox" name="options[{$preparedOption.option_id}][]" value="{$key}" id="ctrl_options{$preparedOption.option_id}_{$key}"<xen:if is="{$item.checked}">checked="checked"</xen:if> /> {$item.name}</label></li>
			</xen:foreach>
		</ul>
		<input type="hidden" name="{$listedFieldName}" value="{$preparedOption.option_id}" />
		{xen:raw $editLink}
	</xen:html>
</xen:controlunit>