I want to create a theme options page that will have sections. Those sections should be to be saved both one by one, and also all together.
The WordPress default function for that will, regardless where I put it, always save all at once. That’s fine for the final “Save All” button, but not for each single section
My Goal:
- Each section can be saved at once, and perhaps highlights shortly in
a slightly different color while saving. - The page should not be reloaded, that’s why AJAX has been recommended here: https://wordpress.org/support/topic/save-options-sections-one-by-one
Also my code (part of) can be seen there. I’m not sure if I should paste here my entire code for the theme sections (array and all the rest included).
I don’t want a ready to use code. I know it’s not the scope of StackOverflow, but perhaps somebody can give me a cool example, I am beginner in PHP, imagine AJAX. 🙁
I thank everybody for pointing me to correct direction or perhaps even tutorial?
I think this could also help the community
I share here the code of my theme functions. Note I did not include the Theme Options CSS and JavaScript sheet
<?php
// Define Variables
$themename = "MinimaX3";
$shortname = "mx3";
$version = "1.0.0";
// Create theme options in arrays, with options for sections and open/close them
global $options;
$options = array(
//Type + Name of array = section General
array(
"name" => "General",
"type" => "section"),
//Open section
array(
"type" => "open"),
//Options in General section
//Header Text
array(
"name" => "Header Text",
"desc" => "Your Header Text. If empty, the Blog Name will be displayed",
"id" => $shortname."_headertext",
"type" => "text",
"std" => ""),
//Wether to show Blog Name or not
array(
"name" => "Show the Blog name",
"desc" => "If you leave the Hedaer text empty, you canstill deicde if you want the Bloga nem displayed or not",
"id" => $shortname."_blogname",
"type" => "checkbox",
"std" => ""),
//Close General section
array(
"type" => "close"),
//Type + Name of next array = section Social Networks
array(
"name" => "Social Networks",
"type" => "section"),
//Open section
array(
"type" => "open"),
//Options in Social Networks section
//Twitter ID
array(
"name" => "Twitter ID",
"desc" => "Your Twitter user name, please. It will be shown in the navigation bar. Leaving it blank will keep the Twitter icon supressed.",
"id" => $shortname."_twitterid",
"type" => "text",
"std" => ""),
//Facebook URL
array(
"name" => "Facebook Page",
"desc" => "Link to your Facebook page, <strong>with http://</strong>. It will be shown in the navigation bar. Leaving it blank will keep the Facebook icon suppressed.",
"id" => $shortname."_facebookid",
"type" => "text",
"std" => ""),
//Close Social Networks section
array(
"type" => "close"),
//Type + Name of next array
array(
"name" => "Footer",
"type" => "section"),
//Open Footer section
array(
"type" => "open"),
//Options in Footer section
//Right Footer Area
array(
"name" => "Right Footer Text",
"desc" => "Paste your text, copyright statements, etc., here.",
"id" => $shortname."_right_footer_text",
"type" => "textarea",
"std" => ""),
//Left Footer Area
array(
"name" => "Left Footer Text",
"desc" => "Paste your text, copyright statements, etc., here.",
"id" => $shortname."_left_footer_text",
"type" => "textarea",
"std" => ""),
//Close Footer Area section
array(
"type" => "close"),
//Type + Name of next array
array(
"name" => "Google Analytics",
"type" => "section"),
//Open Google Analytics section
array(
"type" => "open"),
//Options in Google Anaslytics section
//Googel Analytics
array(
"name" => "Analytics/Tracking Code",
"desc" => "You can paste your Google Analytics or other website tracking code in this box. This will be automatically added to the footer.",
"id" => $shortname."_analytics_code",
"type" => "textarea",
"std" => ""),
//Close Google Anayltics section
array(
"type" => "close"),
//Type + Name of next array
array(
"name" => "Custom CSS",
"type" => "section"),
//Open Custom CSS section
array( "type" => "open"),
//Options in Custom CSS section
//Custom CSS
array(
"name" => "Custom CSS",
"desc" => "Want to add any custom CSS code? Put in here, and the rest is taken care of.",
"id" => $shortname."_custom_css",
"std" => "",
"type" => "textarea"),
//Close Custom CSS section
array(
"type" => "close"),
//Type + name of next array
array(
"name" => "Custom Header and Footer Code",
"type" => "section"),
//Open Custom Header and Fotter Code section
array(
"type" => "open"),
//Options in Custom Header and Footer Code
//Custom Header Code
array(
"name" => "Custom Header Code",
"desc" => "All code you enter here will be added to your Hedaer.php file",
"id" => $shortname."_custom_header_code",
"std" => "",
"type" => "textarea"),
//Custom Footer Code
array(
"name" => "Custom Footer Code",
"desc" => "All code you enter here will be added to your Footer.php file",
"id" => $shortname."_custom_footer_code",
"std" => "",
"type" => "textarea"),
//Close Custom Header and Footer Code section
array( "type" => "close"),
);
//How to save, wehn to save, URL definition
function mx3_add_admin() {
global $themename, $shortname, $options;
if ( isset ( $_GET['page'] ) && ( $_GET['page'] == basename(__FILE__) ) ) {
if ( isset ($_REQUEST['action']) && ( 'save' == $_REQUEST['action'] ) ){
foreach ( $options as $value ) {
if ( array_key_exists('id', $value) ) {
if ( isset( $_REQUEST[ $value['id'] ] ) ) {
update_option( $value['id'], $_REQUEST[ $value['id'] ] );
}
else {
delete_option( $value['id'] );
}
}
}
header("Location: admin.php?page=".basename(__FILE__)."&saved=true");
}
else if ( isset ($_REQUEST['action']) && ( 'reset' == $_REQUEST['action'] ) ) {
foreach ($options as $value) {
if ( array_key_exists('id', $value) ) {
delete_option( $value['id'] );
}
}
header("Location: admin.php?page=".basename(__FILE__)."&reset=true");
}
}
add_theme_page($themename, $themename, 'administrator', basename(__FILE__), 'mx3_admin');
add_theme_page(basename(__FILE__), $themename . ' Options', 'Theme Options', 'administrator', basename(__FILE__),'mx3_admin'); // Default
}
function mx3_add_init() {
$file_dir=get_template_directory_uri('template_directory');
wp_enqueue_style("mx3Css", $file_dir."/functions/theme-options.css", false, "1.0", "all");
wp_enqueue_script("mx3Script", $file_dir."/functions/theme-options.js", false, "1.0");
}
//Echos upon suuccesful save/reset operation + cases for rendering previous arrays
function mx3_admin() {
global $themename, $shortname, $version, $options;
$i=0;
if ( isset ($_REQUEST['saved']) && ($_REQUEST['saved'] ) )echo '<div id="message" class="updated fade"><p><strong>'.$themename.' Options saved.</strong></p></div>';
if ( isset ($_REQUEST['reset']) && ($_REQUEST['reset'] ) ) echo '<div id="message" class="updated fade"><p><strong>'.$themename.' Options reset.</strong></p></div>';
?>
<div class="wrap ">
<div class="options_wrap">
<h2 class="Options-title"><?php echo $themename; ?> Options</h2>
<form method="post">
<?php foreach ($options as $value) {
switch ( $value['type'] ) {
case "section":
?>
<div class="section_wrap">
<h3 class="section_title"><?php echo $value['name']; ?></h3>
<div class="section_body">
<?php
break;
case 'text':
?>
<div class="options_input options_text">
<span class="labels"><label for="<?php echo $value['id']; ?>"><?php echo $value['name']; ?></label></span>
<input name="<?php echo $value['id']; ?>" id="<?php echo $value['id']; ?>" style="width: 100%;" type="<?php echo $value['type']; ?>" value="<?php if ( get_option( $value['id'] ) != "") { echo stripslashes(get_option( $value['id']) ); } else { echo $value['std']; } ?>" />
<br>
<div class="options_desc"><?php echo $value['desc']; ?></div>
</div>
<?php
break;
case 'textarea':
?>
<div class="options_input options_textarea">
<span class="labels"><label for="<?php echo $value['id']; ?>"><?php echo $value['name']; ?></label></span>
<textarea name="<?php echo $value['id']; ?>" type="<?php echo $value['type']; ?>" cols="" rows="">
<?php if ( get_option( $value['id'] ) != "") { echo stripslashes(get_option( $value['id']) ); } else { echo $value['std']; } ?>
</textarea>
<br>
<div class="options_desc"><?php echo $value['desc']; ?></div>
</div>
<?php
break;
case 'select':
?>
<div class="options_input options_select">
<span class="labels"><label for="<?php echo $value['id']; ?>"><?php echo $value['name']; ?></label></span>
<select name="<?php echo $value['id']; ?>" id="<?php echo $value['id']; ?>">
<?php foreach ($value['options'] as $option) {
?>
<option <?php if (get_option( $value['id'] ) == $option) { echo 'selected="selected"'; } ?>><?php echo $option; ?></option>
<?php
}
?>
</select>
<br>
<div class="options_desc"><?php echo $value['desc']; ?></div>
</div>
<?php
break;
case "checkbox":
?>
<div class="options_input options_checkbox">
<label for="<?php echo $value['id']; ?>"><?php echo $value['name']; ?></label>
<br>
<?php if(get_option($value['id'])){ $checked = "checked="checked""; }else{ $checked = "";} ?>
<input type="checkbox" name="<?php echo $value['id']; ?>" id="<?php echo $value['id']; ?>" value="true" <?php echo $checked; ?> />
<br>
<div class="options_desc"><?php echo $value['desc']; ?></div>
<br>
</div>
<?php
break;
case "close":
$i++;
?>
<input name="save<?php echo $i; ?>" type="hidden" />
<?php submit_button() ?>
</div><!--#section_body-->
</div><!--#section_wrap-->
<?php
break;
}
}
?>
<input type="hidden" name="action" value="save" />
<?php submit_button( 'Save All Options' ) ?>
</form>
<form method="post">
<input type="hidden" name="action" value="reset" />
<div class="warning">
<?php echo _e('Warning! Next Step Resets ALL options!', 'minmax3'); ?>
</div>
<?php submit_button( 'Reset All Options' ); ?>
</form>
<br/>
</div><!--#options-wrap-->
</div><!--#wrap-->
<?php
}
add_action('admin_init', 'mx3_add_init');
add_action('admin_menu' , 'mx3_add_admin');
//Enqueue Custom CSS Front-End
function display_custom_css() {
$custom_css = get_option( 'mx3_custom_css' );
echo '<style> '.$custom_css.' </style>';
}
add_filter('wp_head', 'display_custom_css');
?>
EDIT:
I was able to bring it to work (save without re-loading page) by adding this after the </form>
tag of <form method="post">
:
<div id="saveResult"></div>
<script type="text/javascript">
jQuery(document).ready(function() {
jQuery('#myOptionsForm').submit(function() {
jQuery(this).ajaxSubmit({
success: function(){
jQuery('#saveResult').html("<div id='saveMessage' class='successModal'></div>");
jQuery('#saveMessage').append("<p><?php echo htmlentities(__('Settings Saved Successfully','wp'),ENT_QUOTES); ?> </p>").show();
},
timeout: 5000
});
setTimeout("jQuery('#saveMessage').hide('slow');", 5000);
return false;
});
});
</script>
And change the Form accordingly (add the class):
<form method="post" id="myOptionsForm">
I added some CSS too.
(this all is from a Tutorial here: http://www.wpoptimus.com/434/save-plugin-theme-setting-options-ajax-wordpress/)
So far, all is good now.
What I am now struggling with is:
- The current situation produces a “pop Up” message on save action, with a success message. Cool, but:
- I would like to “highlight” my Body (div) of the single Theme Options Sections (drop down body) shortly in a different color when settings are saved.
- I understand I must address the div of those bodies, and probably set a if/else statement, to call the “highlighting” CSS, ONLY when save the option.
I understand I must add this if/else statement in the new
"div id="saveResult"></div>
right?
Perhaps somebody here is faster then I am with try and fail, and can point me into the correct direction?
😀
If i understood that right, you need 2 dropdowns for themes for the 2 sections, then you need to post the 2 values via ajax, then in the php code you can just save the theme value to a datebase. So that you can read the values then ever the user opens a site. I don’t get there the problem is right now.
To highlight for some seconds you can use jquerys add class like this:
Then your div with Id sucessId will have the class solve for half a second so you just need a CSS file which gives the class solve like a orange border.
Ok now i wasted a lot of time to complete your solution. Hope its fine now: