I'm driving myself crazy here trying to get a checkbox to save on a plugin settings page.
Right now, as a template, I'm working through the excellent example given here: Settings API with arrays example
I'm also referring to a very useful tutorial at / with a detailed git at .php
I've also read about a half dozen posts with similar questions but none have my answer, at least that I can find and understand.
I think I'm stumbling on the syntax of a checked() function.
--- Updated code ---
Here are the key pieces of code:
The overall data in the function that calls register_setting(), add_settings_section() and add_settings_fields
$option_name = 'rpq_plugin_option_name'; // free to choose this name
// Fetch existing options.
$option_values = get_option( $option_name );
$default_values = array (
'number' => 500,
'color' => 'blue',
'long' => '',
'activity' => array(
'baseball' => '',
'golf' => '',
'hockey' => '')
);
$data = shortcode_atts( $default_values, $option_values );
The add_settings_field() for the checkboxes:
add_settings_field(
'section_2_field_2',
'Checkboxes',
'rpq_plugin_render_section_2_field_2', // callback to render html
'rpq-default-settings', // menu slug
'section_2',
array (
'label_for' => 'label4', // makes the field name clickable,
'name' => 'activity', // value for 'name' attribute
'value' => array_map( 'esc_attr', $data['activity'] ) ,
'options' => array (
'baseball' => 'Baseball',
'golf' => 'Golf',
'hockey' => 'Hockey'
),
'option_name' => $option_name
)
);
The callback to render the html:
function rpq_plugin_render_section_2_field_2( $args )
{
$options_markup = '';
$iterator = 0;
$values = $args['value'];
$options = $args['options'];
rpq_plugin_debug_var( $options, 'Options: ' );
rpq_plugin_debug_var( $values, 'Values: ' );
foreach ( $args['options'] as $key => $title ) {
rpq_plugin_debug_var( $key, 'Key: ' );
rpq_plugin_debug_var( $title, 'Title: ' );
$checked = checked((in_array($title, $values)), true, false);
rpq_plugin_debug_var($checked, 'Checked: ');
$iterator ++;
$options_markup .= sprintf(
'<label for="%1$s_%6$s"><input id="%1$s_%6$s" name="%1$s[%2$s]" type="checkbox" value="%3$s" %4$s /> %5$s</label><br/>',
$args['option_name'],
$args['name'],
$key,
$checked,
$title,
$iterator
);
}
printf( '<fieldset>%s</fieldset>', $options_markup );
//print '</select>';
rpq_plugin_debug_var( $values, 'Values: ');
}
The output from the debug dump of the initial variables is as I'd expect:
Options: = array (
'baseball' => 'Baseball',
'golf' => 'Golf',
'hockey' => 'Hockey',
)
Values: = array (
'baseball' => '',
'golf' => '',
'hockey' => '',
)
Key: = 'baseball'
Title: = 'Baseball'
Checked: = ''
Key: = 'golf'
Title: = 'Golf'
Checked: = ''
Key: = 'hockey'
Title: = 'Hockey'
Checked: = ''
After trying to save, i get:
Values: = NULL
I've tried a host of variations on ways to get cjhecked set but I can't get the checkboxes to save.
I'm driving myself crazy here trying to get a checkbox to save on a plugin settings page.
Right now, as a template, I'm working through the excellent example given here: Settings API with arrays example
I'm also referring to a very useful tutorial at https://www.smashingmagazine.com/2016/04/three-approaches-to-adding-configurable-fields-to-your-plugin/ with a detailed git at https://github.com/rayman813/smashing-custom-fields/blob/master/smashing-fields-approach-1/smashing-fields.php
I've also read about a half dozen posts with similar questions but none have my answer, at least that I can find and understand.
I think I'm stumbling on the syntax of a checked() function.
--- Updated code ---
Here are the key pieces of code:
The overall data in the function that calls register_setting(), add_settings_section() and add_settings_fields
$option_name = 'rpq_plugin_option_name'; // free to choose this name
// Fetch existing options.
$option_values = get_option( $option_name );
$default_values = array (
'number' => 500,
'color' => 'blue',
'long' => '',
'activity' => array(
'baseball' => '',
'golf' => '',
'hockey' => '')
);
$data = shortcode_atts( $default_values, $option_values );
The add_settings_field() for the checkboxes:
add_settings_field(
'section_2_field_2',
'Checkboxes',
'rpq_plugin_render_section_2_field_2', // callback to render html
'rpq-default-settings', // menu slug
'section_2',
array (
'label_for' => 'label4', // makes the field name clickable,
'name' => 'activity', // value for 'name' attribute
'value' => array_map( 'esc_attr', $data['activity'] ) ,
'options' => array (
'baseball' => 'Baseball',
'golf' => 'Golf',
'hockey' => 'Hockey'
),
'option_name' => $option_name
)
);
The callback to render the html:
function rpq_plugin_render_section_2_field_2( $args )
{
$options_markup = '';
$iterator = 0;
$values = $args['value'];
$options = $args['options'];
rpq_plugin_debug_var( $options, 'Options: ' );
rpq_plugin_debug_var( $values, 'Values: ' );
foreach ( $args['options'] as $key => $title ) {
rpq_plugin_debug_var( $key, 'Key: ' );
rpq_plugin_debug_var( $title, 'Title: ' );
$checked = checked((in_array($title, $values)), true, false);
rpq_plugin_debug_var($checked, 'Checked: ');
$iterator ++;
$options_markup .= sprintf(
'<label for="%1$s_%6$s"><input id="%1$s_%6$s" name="%1$s[%2$s]" type="checkbox" value="%3$s" %4$s /> %5$s</label><br/>',
$args['option_name'],
$args['name'],
$key,
$checked,
$title,
$iterator
);
}
printf( '<fieldset>%s</fieldset>', $options_markup );
//print '</select>';
rpq_plugin_debug_var( $values, 'Values: ');
}
The output from the debug dump of the initial variables is as I'd expect:
Options: = array (
'baseball' => 'Baseball',
'golf' => 'Golf',
'hockey' => 'Hockey',
)
Values: = array (
'baseball' => '',
'golf' => '',
'hockey' => '',
)
Key: = 'baseball'
Title: = 'Baseball'
Checked: = ''
Key: = 'golf'
Title: = 'Golf'
Checked: = ''
Key: = 'hockey'
Title: = 'Hockey'
Checked: = ''
After trying to save, i get:
Values: = NULL
I've tried a host of variations on ways to get cjhecked set but I can't get the checkboxes to save.
I finally got this one. I'll write out the solution for any other inexperienced person, like me, who is trying to handle a checkbox array when using just one options array.
First, the two articles I linked two at the top of the question are good for learning the basic about the topic.
Solution - part one:
I am using an options array, with all the possible options, and a values array to hold just the items that are checked. I was creating the values array incorrectly. Rather than being an associative array, it needs to be just a "regular array" holding just the keys from the options array.
So, in my setup, instead of setting 'activities' in the default settings to
array (
'baseball' => '',
'golf' => '',
'hockey' => ''
),
I want just
array ()
Solution - part two
If no checkboxes are chosen, when the settings are saved the $values array becomes NULL. But I need to use functions that require an array to make my tests for validation and for evaluating the checkboxes. So I need to make sure $values is always an array. So I need
if (is_null($data['activity'])) {
$data['activity'] = array();
}
Solution - part 3
My checked() function was wrong. Once I had fixed my array as discussed above, I am searching if the current $key from the $options array is a value from the $values array.
$checked = checked((in_array($key, $values)), true, false);
Solution - part 4
Since 'activities' is a sub array of the option values, I need to set the name variable in the checkbox statements to reflect that.
So I use
name="%1$s[%2$s][]"
which generates
name="rpq_plugin_option_name[activity][]"
Now my checkboxes update and save.