Problem/Background
Currently, I’m creating a plugin for a client that will enable them to mark and modify predetermined Google Map polygons (displayed on the site) in the dashboard.
I want to let the user mark a polygon as important, set a custom color, opacity, and info window text — all of which I have been able to do so far. The problem is that these field sets need to exist for all 180-ish polygons. With the WP settings API I can create and save the fields, but it would be ridiculous to create 500+ callbacks to cover each specific field. So for the past couple of days I’ve been trying to loop through the field set a specific number of times and appending a variable number.
Current Code
Here’s the current option field registration for one set of polygons (as stored in a class):
<?php
public function page_init() {
//[. . . ]
add_settings_section(
'rangers_txs',
'Texas Senate District Options',
array($this, 'print_txs_info'),
'rangers_txs_option'
);
register_setting(
'rangers_txs',
'rangers_txs_option',
array($this, 'ranger_txs_sanitize')
);
$i=1;
while($i <= 31) {
add_settings_field(
'rangers_txs_checkbox_'.$i, //id
'Is District '.$i.' important?', //Title
array( $this, 'rangers_txs_check_callback_'.$i), //callback
'rangers_txs_option', //page
'rangers_txs', //section
array('field' => 'txs_checkbox')
);
add_settings_field(
'rangers_txs_colorpicker_'.$i, //id
'District Color', //Title
array( $this, 'rangers_txs_color_callback_'.$i ), //callback
'rangers_txs_option', //page
'rangers_txs', //section
array('field' => 'txs_colorpicker')
);
add_settings_field(
'rangers_txs_opacity_'.$i, //id
'How important is it?', //Title
array( $this, 'rangers_txs_opacity_callback_'.$i ), //callback
//array($this, 'rangers_txs_input_array'),
//'rangers_txs_opacity_callback_'.$i, //callback
'rangers_txs_option', //page
'rangers_txs', //section
array('field' => 'txs_opacity')
);
add_settings_field(
'rangers_txs_info_'.$i, //id
'District Information', //Title
array( $this, 'rangers_txs_info_callback_'.$i ), //callback
'rangers_txs_option', //page
'rangers_txs', //section
array('field' => 'txs_info')
);
$i++;
}
}
?>
And here’s one set of callbacks, which I’ve tested and work properly:
<?php
public function colorpicker_init() {
echo '<script type="text/javascript">
jQuery(document).ready(function($) {
$(".tr-color-picker").wpColorPicker();
});
</script>';
}
public function rangers_txs_check_callback_1() {
printf(
'<input type="checkbox" id="rangers_txs_checkbox_1" name="rangers_txs_option[rangers_txs_checkbox_1]" %1$s />
<label for="rangers_txs_option[rangers_txs_checkbox_1]">Yep, it's important.',
checked( isset($this->txsoptions['rangers_txs_checkbox_1']), true, false)
);
}
public function rangers_txs_color_callback_1() {
$this->colorpicker_init();
$color = $this->txsoptions['rangers_txs_colorpicker_1'] != '' ? sanitize_text_field($this->txsoptions['rangers_txs_colorpicker_1']) : '#0A64A4';
printf(
'<input type="text" name="rangers_txs_option[%1$s]" id="%1$s" class="tr-color-picker" data-default-color="#0A64A4" value="'.$color.'" />',
'rangers_txs_colorpicker_1'
);
}
public function rangers_txs_opacity_callback_1() {
print '<p><em>On a scale of 1-10 (determines opacity of district, default: 5).</em></p>';
printf(
'<input type="text" id="rangers_txs_opacity_1" name="rangers_txs_option[rangers_txs_opacity_1]" value="%s" />',
isset( $this->txsoptions['rangers_txs_opacity_1'] ) ? esc_attr( $this->txsoptions['rangers_txs_opacity_1']) : ''
);
}
public function rangers_txs_info_callback_1() {
isset($this->txsoptions['rangers_txs_info_1']) ? $content = $this->txsoptions['rangers_txs_info_1'] : $content = '';
echo '<textarea id="rangers_txs_info_1" name="rangers_txs_option[rangers_txs_info_1]" rows="6" cols="50">'.$content.'</textarea>';
}
?>
Question
As you can see, I have a check box, a color picker, an opacity input, and a text area. I want the entire set to be looped for each polygon. I attempted to run the fields in one callback, but it simply lumped all of the same options together (i.e., 31 check boxes then 31 color pickers, etc.). I have also tried setting the callbacks outside of the class and looping a while
around the function set, but using the $i
variable in the function name returned errors, as did appending it before calling and when calling the functions.
I would greatly appreciate any suggestions that could help me achieve the result of looping field sets.
I figured it out after a little work.
To start, I ended up using a single callback:
array($this, 'txs_loop_callbacks')
using the sameadd_settings_field
registration above. Then I altered the final argument in the field resgistration, making each unique to that specific field:array('field' => 'txs_opacity_'.$i)
.Then in the loop callback I stored each field’s HTML in a anonymous function defined as a variable. Like so:
I defined this type of variable for each field type (i.e.,
$txs_checkbox
,$txs_colorpicker
, and on).After that, I called the anonymous functions inside a loop with a check to display only one kind of field per set.
With those elements all together, I was able to achieve the result of repeating field sets.