Hi, I'm building a theme with an options page that gives the user the ability to choose a menu type (categories, pages or custom) for each menu location. Everything works fine when selecting the the menu type but the next time the theme options page is loaded it sets the menu selection back to the default option. It doesn't actually change the setting just changes the selected <option>... but if you then if you save your options again the default menu get set because that is what was selected.
FYI, this is a framework type theme and you must be familiar with AJAX saved options. Let me know if any of you want to take a look I'll send the theme files.
UPDATE:
Here is the code where I think the problem is. What am I missing?
<?php
foreach($value['options'] as $sel_opt):
$this_value='';
if($values):
$this_value = ' value="'.$values[$ctr].'"';
$ctr++;
endif;
if(get_option($value['id']) == $sel_opt) $default=get_option($value['id']);
else $default = $value['default'];
$selected='';
if($sel_opt == $default) $selected=' selected="selected"';
?>
<option <?php echo $selected . $this_value;?>><?php echo $sel_opt; ?></option>
<?php
endforeach;
?>
John Cotton answers:
It sounds like your dropdown isn't having selected="selected" put against the current option.
Could be a typo, could be some missing code...
John Cotton comments:
The code looks OK in terms of structure, so there must be something wrong in the comparison of current loop value to set value.
Could you add this line:
print_r($value);
just before
foreach($value['options'] as $sel_opt):
and post the output of the print_r?
Joe Calithia comments:
Array
(
[type] => select
[name] => Primary Header Menu
[id] => dt_primary_menu
[options] => Array
(
[0] => Pages
[1] => Categories
[2] => Custom Menu → Test Primary Menu
[3] => Custom Menu → Secondary Menu
[4] => Custom Menu → Tertiary Menu
)
[values] => Array
(
[0] => Pages
[1] => Categories
[2] => test-primary-menu
[3] => secondary-menu
[4] => tertiary-menu
)
[desc] => Choose the menu you would like displayed in the primary header menu location.<br /><br />If you are using WordPress version 3.0 or above you can create a custom nav menu and it will be listed as an option in this dropdown.
[default] => Categories
)
John Cotton comments:
Very odd....
The id value that is tested against the current option doesn't even exist in the values!
This line is the probelm:
if(get_option($value['id']) == $sel_opt)
get_option($value['id']) should be something else...but what I'm not sure...
When it saves correctly, do you know where that value gets stored?
If you could post the "save" code as well, that might help....
JC
Joe Calithia comments:
I think this is it... I can send you the whole theme if you want.
//Save options via AJAX
add_action('wp_ajax_dt_ajax_save', 'dt_ajax_save'); //Add support for AJAX save from theme options
function dt_ajax_save(){
update_option('dt_options_saved', 'true');
$save_types=array("text", "multitext", "textarea", "image", "checkbox", "radio", "radio_img", "select");
global $wpdb; //Now WP database can be accessed
global $options;
global $language_options;
if (isset($_POST['action']) && $_POST['action'] == 'dt_ajax_save' ) {
dt_save_ajax_options($options);
}
else if(isset($_POST['action']) && $_POST['action'] == 'dt_ajax_language_save' ) {
dt_save_ajax_options($language_options);
}
else if (isset($_POST['action']) && $_POST['action'] == 'reset' ) {
//Delete all options from the options table in WPDB, where it has dt_ as a prefix
$query = "DELETE FROM $wpdb->options WHERE option_name LIKE 'dt_%'";
$wpdb->query($query);
}
die();
}
function dt_save_ajax_options($this_options){
$save_types=array("text", "multitext", "textarea", "image", "checkbox", "radio", "radio_img", "select");
foreach ($this_options as $value) {
$the_type=$value['type'];
if(in_array($the_type, $save_types)){ //if its in the array, its an input element
if($the_type=="checkbox"){
$ctr=0;
foreach( $value['options'] as $cbopt):
$curr_id=$value['id'][$ctr];
if(isset($_REQUEST[$curr_id]))
update_option($curr_id, 'true');
else
update_option($curr_id, 'false');
$ctr++;
endforeach;
}
if($the_type=="multitext"){
foreach( $value['id'] as $mt_id):
update_option($mt_id, $_REQUEST[ $mt_id ]);
endforeach;
}
if($the_type!="checkbox" and $the_type!="multitext"){
update_option($value['id'], $_REQUEST[ $value['id'] ]);
}
}
}
}
John Cotton comments:
Sorry, I misread - the code get_option($value['id']) is probably correct - it's the saving that is the issue....let's see that code...
John Cotton comments:
Hmm...that looks OK
This line:
update_option($value['id'], $_REQUEST[ $value['id'] ]);
would do the work.
Can you check in the output html that the dropdown has a name of dt_primary_menu?
John Cotton comments:
Try changing this
if(get_option($value['id']) == $sel_opt) $default=get_option($value['id']);
else $default = $value['default'];
$selected='';
if($sel_opt == $default) $selected=' selected="selected"';
to this
if(get_option($value['id']) == $this_value) $default=get_option($value['id']);
else $default = $value['default'];
$selected='';
if($this_value == $default) $selected=' selected="selected"';
That code could be much neater if I was certain that the values weren't used elsewhere, but I've left it as written for now.
JC
Joe Calithia comments:
Not clear on what you're asking me to do from this comment.
John Cotton comments:
There are two code blocks in my comment. The first is a snippet your existing code. That snippet needs replacing with the code in the second code block.
Joe Calithia comments:
I made that comment before I saw your find/replace comment.
Anyway, I tried that and same thing is happening. I'll PM you a link to download the theme zip. Probably easier to see all code.
Joe Calithia comments:
Any luck John?
Rashid Aliyev answers:
JUST ADD AFTER <strong>OPTION</strong> keyword <strong>SELECTED</strong> keyword.
Read here more: [[LINK href="http://www.w3schools.com/TAGS/att_option_selected.asp"]]http://www.w3schools.com/TAGS/att_option_selected.asp[[/LINK]] here