| @@ -74,8 +74,14 @@ | ||
| 74 | 74 | if ( 'input_name' === $argument ) { |
| 75 | 75 | return sprintf( '%s[%s][%s]', OPTION_NAME, $this->section, $this->field_id ); |
| 76 | 76 | } |
| 77 | 77 | |
| 78 | + // Stable DOM id for the rendered control, so the settings-table heading | |
| 79 | + // can be associated with it via `label_for` (accessible name). | |
| 80 | + if ( 'element_id' === $argument ) { | |
| 81 | + return sanitize_key( sprintf( '%s_%s_%s', OPTION_NAME, $this->section, $this->field_id ) ); | |
| 82 | + } | |
| 83 | + | |
| 78 | 84 | return $this->args[ $argument ]; |
| 79 | 85 | } |
| 80 | 86 | |
| 81 | 87 | /** |
| @@ -213,9 +219,10 @@ | ||
| 213 | 219 | * @since 2.0.0 |
| 214 | 220 | */ |
| 215 | 221 | private function render_number_field() { |
| 216 | 222 | printf( |
| 217 | - '<input type="number" name="%s" value="%s"', | |
| 223 | + '<input id="%s" type="number" name="%s" value="%s"', | |
| 224 | + esc_attr( $this->element_id ), | |
| 218 | 225 | esc_attr( $this->input_name ), |
| 219 | 226 | esc_attr( $this->get_saved_value() ) |
| 220 | 227 | ); |
| 221 | 228 | |
| @@ -240,9 +247,13 @@ | ||
| 240 | 247 | * @since 3.0.0 |
| 241 | 248 | */ |
| 242 | 249 | private function render_select_field() { |
| 243 | 250 | $saved_value = $this->get_saved_value(); |
| 244 | - printf( '<select name="%s">', esc_attr( $this->input_name ) ); | |
| 251 | + printf( | |
| 252 | + '<select id="%s" name="%s">', | |
| 253 | + esc_attr( $this->element_id ), | |
| 254 | + esc_attr( $this->input_name ) | |
| 255 | + ); | |
| 245 | 256 | |
| 246 | 257 | foreach ( $this->options as $option => $option_label ) { |
| 247 | 258 | printf( |
| 248 | 259 | '<option value="%s" %s>%s</option>', |