I'm making a plugin administration page with the settings API. I'd like to know a way to display a warning message when the user submits an invalid value.
For example, with the below code, if the user sends an empty value for Option A, the first input field, I'd like to show a message that says it's invalid and please fill the form. And the other submitted option values should not be saved to the database but remain in the input fields with the message on the page.
<?php
/*
Plugin Name: Demo Verification Notice with Settings API
Description: Learning how to warn invalid values when submitting the form and take back the user to the setting page without saving the options.
Author: Teno
*/
add_action('admin_init', 'settingsapi_init');
function settingsapi_init(){
register_setting( 'settingsapi_optiongroupname', 'settingsapi_optionname');
add_settings_section('plugin_main', 'Section 1', 'settingsapi_sectiondescription', 'settingsapi_pageslug');
add_settings_field('plugin_text_string_a', 'Option A', 'settingsapi_setting_string_a', 'settingsapi_pageslug', 'plugin_main');
add_settings_field('plugin_text_string_b', 'Option B', 'settingsapi_setting_string_b', 'settingsapi_pageslug', 'plugin_main');
}
function settingsapi_sectiondescription() {
echo '<p>This is a section description.</p>';
}
function settingsapi_setting_string_a() {
$options = get_option('settingsapi_optionname');
echo "<input id='plugin_text_string' name='settingsapi_optionname[option_a]' size='40' type='text' value='{$options['option_a']}' />";
}
function settingsapi_setting_string_b() {
$options = get_option('settingsapi_optionname');
echo "<input id='plugin_text_string' name='settingsapi_optionname[option_b]' size='40' type='text' value='{$options['option_b']}' />";
}
// admin menu
add_action('admin_menu', 'plugin_admin_add_page');
function plugin_admin_add_page() {
add_options_page('Custom Plugin Page', 'Demo Settings API Menu for Verification', 'manage_options', 'settingsapi_pageslug', 'settingsapi_adminpage');
}
function settingsapi_adminpage() {
?>
<div class="wrap">
<?php screen_icon(); ?> <h2>Demo Plugin for Settings API</h2>
<form action="options.php" method="post">
<?php settings_fields('settingsapi_optiongroupname'); ?>
<?php do_settings_sections('settingsapi_pageslug'); ?>
<?php submit_button(); ?>
</form>
</div>
<?php
}
?>
Is that possible with the settings API?
The register_setting() function accepts the third parameter as validation function call. However, it can be used to just fix the passed value but it accepts the form submission and saves the options. That is not what I'm looking for.
[Edit]
Okey, I'm almost there. This validates the submitted value with the callback function set in the register_setting() function. And if the value is invalid it leaves a flag, invalid, in the option array and displays a warning message.
However, there is one remaining issue. Otherwise, it is almost done.
- Once an empty value is set to the first input option, it shows the warning message. It is what we've achieved so far. And if the user leaves the page showing the warning, somehow the empty value is saved to the option. It should revert the previous value.
The code below is ready to use as a plugin. If you run it, you'll see what I'm talking about.
<?php
/*
Plugin Name: Demo Verification Notice with Settings API
Description: Learning how to warn invalid values when submitting the form and take back the user to the setting page without saving the options.
Author: Teno
*/
add_action('admin_init', 'settingsapi_init');
function settingsapi_init(){
register_setting( 'settingsapi_optiongroupname', 'settingsapi_optionname','validation_callback');
add_settings_section('plugin_main', 'Section 1', 'settingsapi_sectiondescription', 'settingsapi_pageslug');
add_settings_field('plugin_text_string_a', 'Option A', 'settingsapi_setting_string_a', 'settingsapi_pageslug', 'plugin_main');
add_settings_field('plugin_text_string_b', 'Option B', 'settingsapi_setting_string_b', 'settingsapi_pageslug', 'plugin_main');
}
function settingsapi_sectiondescription() {
echo '<p>This is a section description.</p>';
}
function settingsapi_setting_string_a() {
$options = get_option('settingsapi_optionname');
?>
<input type="hidden" name="settingsapi_optionname[submitted]" value="1" />
<? print_r($options); ?><br />
<input id="plugin_text_string" name="settingsapi_optionname[preview][option_a]" size="40" type="text" value="<?php echo $options['submitted'] ? $options['preview']['option_a'] : $options['valid']['option_a']; ?>" />
<?php echo ($options['invalid'] && $options['submitted'] ) ? '<font color="red">* cannot be blank.</font>' :'' ?>
<?php
}
function settingsapi_setting_string_b() {
$options = get_option('settingsapi_optionname');
?>
<? print_r($options); ?><br />
<input id="plugin_text_string" name="settingsapi_optionname[preview][option_b]" size="40" type="text" value="<?php echo $options['submitted'] ? $options['preview']['option_b'] : $options['valid']['option_b']; ?>" />
<?php
}
// admin menu
add_action('admin_menu', 'plugin_admin_add_page');
function plugin_admin_add_page() {
add_options_page('Custom Plugin Page', 'Demo Settings API Menu for Verification', 'manage_options', 'settingsapi_pageslug', 'settingsapi_adminpage');
}
function settingsapi_adminpage() {
?>
<div class="wrap">
<?php screen_icon(); ?> <h2>Demo Plugin for Validation Message with Settings API</h2>
<?php
$options = get_option('settingsapi_optionname');
print_r($options); // for debugging purpose
if (!($options['invalid'] && $options['submitted'])) {
// update the correct option values
$options['valid'] = is_array($options['valid']) ? $options['valid'] : array(); // if the options['valid'] is called for the first time, make it an array
$options['valid'] = array_merge($options['valid'], $options['preview']);
// $options['preview'] = ''; // initialize the preview option data. //<-- this seems to cause a problem
update_option('settingsapi_optionname', $options);
}
?>
<form action="options.php" method="post">
<?php
settings_fields('settingsapi_optiongroupname');
do_settings_sections('settingsapi_pageslug');
// after displaying the form content, set the invalid flag and the subbmited flag to false
$options['invalid'] = False;
$options['submitted'] = False;
update_option('settingsapi_optionname', $options);
submit_button();
?>
</form>
</div>
<?php
print_r($options);
?>
<?php
}
function validation_callback($input){
if (strlen(trim($input['preview']['option_a'])) == 0 && $input['submitted']) {
// $input['preview']['option_a'] = '';
unset($input['preview']['option_a']);
$input['invalid'] = True; // <-- this one is the problem. It seems to be called multiple times and setting the invalid flag to true when it's not necessary.
add_settings_error('unique_identifyer',esc_attr('settings_updated'),__('Settings NOT saved.'),'error');
add_action('admin_notices', 'print_errors');
} else {
$input['invalid'] = False;
}
return $input;
}
function print_errors(){
settings_errors( 'unique_identifyer' );
}
?>
[Edit]
It might be easier to do it without the Settings API. Here is a working example.
<?php
/*
Plugin Name: Demo Verification Warning without Settings API
Description: Demo plugin demonstrating how to display a warning message when the user tries to save an invalid value in the option page.
Author: Teno
*/
// define constants
define("DEMOVERIFICATIONKEY", "demo_verification_option");
// create an option array
$arrOption = get_option(DEMOVERIFICATIONKEY);
if (!(is_array($arrOption))) {
$arrOption = array(
"tab1" => array(),
"tab2" => array(),
"tab3" => array()
);
update_option(DEMOVERIFICATIONKEY, $arrOption);
}
// admin menu
add_action('admin_menu', 'demo_verification_adminmenu');
function demo_verification_adminmenu() {
add_options_page('Demo Plugin Menu for Verification without Settings API', 'Demo Plugin Menu for Verification without Settings API', 'manage_options', 'demo_verification_admin_menu', 'demo_verification_adminpage');
}
// admin page
function demo_verification_adminpage() {
$options = get_option(DEMOVERIFICATIONKEY);
print_r($_POST); // for debugging
echo '<br />';
if(isset($_POST[DEMOVERIFICATIONKEY]['tab1']['submitted']) && $_POST[DEMOVERIFICATIONKEY]['tab1']['submitted'] == 1){
if (strlen(trim($_POST[DEMOVERIFICATIONKEY]['tab1']['option_a'])) == 0) {
$options['tab1']['invalid'] = True;
echo '<div class="error settings-error"><p>Options are not saved.</p></div>';
} else {
$options = array_merge($options, $_POST[DEMOVERIFICATIONKEY]);
update_option(DEMOVERIFICATIONKEY, $options);
echo '<div class="updated"><p>Updates are saved.</p></div>';
}
}
?>
<div class="wrap">
<?php screen_icon(); ?> <h2>Demo Plugin for Validation Message without Settings API</h2>
<form method="post" action=""> <?php // 'action=""' means to send the form post data to this page itself. ?>
<input type="hidden" name="<?php echo DEMOVERIFICATIONKEY; ?>[tab1][submitted]" value="1" />
<table class="form-table">
<tbody>
<tr valign="top">
<th scope="row">Option A</th>
<td>
<input name="<?php echo DEMOVERIFICATIONKEY; ?>[tab1][option_a]" size="40" type="text" value="<?php echo $options['tab1']['invalid'] ? $_POST[DEMOVERIFICATIONKEY]['tab1']['option_a'] : $options['tab1']['option_a']; ?>" />
<?php echo ($options['tab1']['invalid'] && $options['tab1']['invalid'] ) ? '<font color="red">* cannot be blank.</font>' :'' ?>
</td>
</tr>
<tr valign="top">
<th scope="row">Option B</th>
<td>
<input name="<?php echo DEMOVERIFICATIONKEY; ?>[tab1][option_b]" size="40" type="text" value="<?php echo $options['tab1']['invalid'] ? $_POST[DEMOVERIFICATIONKEY]['tab1']['option_b'] : $options['tab1']['option_b']; ?>" />
</td>
</tr>
</tbody>
</table>
<?php submit_button(); ?>
</form>
</div>
<?php
}
?>
But in case if somebody can figure it out with the Settings API, please post the solution.