In woocommerce, I have 2 selects fields:
The first one is "Car Brands",
And the second one is "Car Models" of these Car Brands.
What I would like to do is to get dynamically "Car Models" for the selected "Car Brand"
The "Car Brands" come from WooCommerce product attributes taxonomies. For each "car brand", the related "car models" are the terms of this product attribute taxonomy.
Here is the code for "Car Brands" (the first select field):
$attributes = wc_get_attribute_taxonomies();
if($attributes) {
echo '<select id="car-brands"><option value="noselection">Car Brand</option>';
foreach ( $attributes as $attribute ) {
echo '<option value="' . $attribute->attribute_name . '">' . $attribute->attribute_label . '</option>';
}
echo '</select>';
}
And a generated html sample code:
<select id="car-brands">
<option value="noselection">Car Brand</option>
<option value="toyota">TOYOTA</option>
<option value="lexus">LEXUS</option>
</select>
Then the code for "Car models" (the second select field):
$selected_attribute_name = 'toyota';
$taxonomy = 'pa_' . $selected_attribute_name;
$term_names = get_terms( array( 'taxonomy' => $taxonomy, 'fields' => 'names' ) );
echo '<select id="car-models"><option value="noselection">Car Model</option>';
echo '<option>' . implode( '</option><option>', $term_names ) . '</option>';
echo '</select>';
And a generated html sample code:
<select id="car-models">
<option value="noselection">Car Model</option>
<option value="toyota">AVENSIS</option>
<option value="lexus">CAMRY</option>
</select>
As you can see I'm getting the specific car models for "toyota" brand, because I have hard coded "toyota" as "Car brand":
$selected_attribute_name = 'toyota';
So what I would like is to have $selected_attribute_name as a dynamic variable, so when user select the car brand "LEXUS" or "TOYOTA", second select field loads dynamically the related terms (options).
I found a lot of related threads, but I haven't be able to understand how can I make it work on my case.
How I can have dynamic "car models" select field options based on selected car brand?
EDIT
All my php is in a action hook function like so:
function _themename_woocommerce_custom_filter() {
$attributes = wc_get_attribute_taxonomies();
if($attributes) {
echo '<select id="car-brands"><option value="noselection">Car Brand</option>';
foreach ( $attributes as $attribute ) {
echo '<option value="' . $attribute->attribute_name . '">' . $attribute->attribute_label . '</option>';
}
echo '</select>';
}
$selected_attribute_name = '';
$taxonomy = 'pa_' . $selected_attribute_name;
$term_names = get_terms( array( 'taxonomy' => $taxonomy, 'fields' => 'names' ) );
echo '<select id="car-models"><option value="noselection">Car Model</option>';
echo '<option>' . implode( '</option><option>', $term_names ) . '</option>';
echo '</select>';
}
add_action( 'woocommerce_before_shop_loop', '_themename_woocommerce_custom_filter', 3 );
The following uses Ajax to get the corresponding terms from the selected "car brand" (product attribute taxonomy) to generate dynamically the "car model" select field options (terms of the selected product attribute taxonomy):
// Display 2 select fields (car brands and car models)
add_action( 'woocommerce_before_shop_loop', 'before_shop_loop_action_callback', 3 );
function before_shop_loop_action_callback() {
if( $attributes = wc_get_attribute_taxonomies() ) {
## 1st dropdown
echo '<select id="car-brands" style="min-width:100px;"><option value="">' . __("Car Brand"). '</option>';
// Loop through attribute taxonomies
foreach ( $attributes as $attribute ) {
echo '<option value="' . $attribute->attribute_name . '">' . $attribute->attribute_label . '</option>';
}
echo '</select>';
## 2nd dropdown
echo '<select id="car-models" style="min-width:100px;"><option value=""> … </option></select>';
}
}
// jQuery / Ajax (client side)
add_action( 'wp_footer', 'car_brand_selectors_script' );
function car_brand_selectors_script() {
?>
<script type="text/javascript">
jQuery(function( $ ) {
if (typeof woocommerce_params === 'undefined')
return false;
var b = 'select#car-brands', // 1st field
m = 'select#car-models', // 2nd field
r = $(m).html(); // Original 2nd field select options
function ajaxSendCarBrand( carBrand ) {
$.ajax({
url: woocommerce_params.ajax_url,
type : 'POST',
data : {
'action' : 'get_brand_terms',
'car_brand' : carBrand
},
success: function( response ) {
var options = $.parseJSON(response),
opt = '';
if ( $.isEmptyObject(options) ) {
$(m).html(r);
} else {
$.each( options, function( key, value ){
opt += '<option value="'+key+'">'+value+'</option>';
});
$(m).html(opt);
}
}
});
}
// On change live event
$( document.body ).on( 'change', b, function() {
ajaxSendCarBrand($(this).val());
});
});
</script>
<?php
}
// WP AJAX HANDLER (Server side)
add_action('wp_ajax_get_brand_terms', 'get_car_brand_models');
add_action('wp_ajax_nopriv_get_brand_terms','get_car_brand_models');
function get_car_brand_models() {
if( isset($_POST['car_brand']) ) {
$brand = wc_clean( $_POST['car_brand'] );
$taxonomy = wc_attribute_taxonomy_name($brand);
$options = [];
if( taxonomy_exists( $taxonomy ) ) {
$terms = get_terms( array( 'taxonomy' => $taxonomy ) );
foreach( $terms as $term ){
$options[$term->slug] = $term->name;
}
}
echo json_encode( $options );
}
wp_die();
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works.
Here take a look at a working ajax example.
Javascript Part:
jQuery('#car-brands').change(function() {
let carBrandName = jQuery(this).val();
YourFunctionNameHere(carBrandName);
});
//function to execute
function YourFunctionNameHere(carBrandName) {
//formdata variable consists of
//action: this is ajax action name for WordPress which we define in PHP with a callback function with same name. See in PHP code part.
//brandName: this is your custom post attributes name
let formdata = "action=get_car_models&brandName="+carBrandName;
jQuery.ajax({
type: "POST",
url: ajaxurl, // since WordPress version 2.8 ajaxurl is always defined in the admin header and points to admin-ajax.php
data: formdata,
cache: false,
success: function(response, textStatus, jqXHR) {
jQuery("#car-models").html(response);
},
error: function(jqXHR, textStatus, errorThrown) {
//do stuff here in case of error
}
});
}
PHP Part:
//here wp_ajax is the required prefix for your custom actions
//first parameter is action name with wp_ajax prefix
//second parameter is callback function to execute with same name as your action
//for example if your action name is wp_ajax_get_car_models then your callback will be get_car_models
add_action( 'wp_ajax_get_car_models', 'get_car_models' );
function get_car_models() {
global $wpdb; // this is how you get access to the database
//require_once any files here in which the below code is available or just write your code here.
$selected_attribute_name = $_POST['brandName'];
$taxonomy = 'pa_' . $selected_attribute_name;
$term_names = get_terms( array( 'taxonomy' => $taxonomy, 'fields' => 'names' ) );
$html = '';
$html .= '<select id="car-models"><option value="noselection">Car Model</option>';
$html .= '<option>' . implode( '</option><option>', $term_names ) . '</option>';
$html .= '</select>';
echo $html;
wp_die(); // this is required to terminate immediately and return a proper response
}
Related
I want to add a custom dropdown list of an attribute (in this case it's the brand), with the options lead to the attribute page as a link.
I got this working
add_filter('woocommerce_before_shop_loop','wc_reg_for_menus', 1, 2);
function wc_reg_for_menus() {
$terms = get_terms( 'pa_marke' );
if ( ! empty( $terms ) && ! is_wp_error( $terms ) ){
echo '<select>';
foreach ( $terms as $term ) {
echo '<option value="'.$term->name.'">'.$term->name.'</option>';
}
echo '</select>';
}
}
And I think I somehow need to add this part
get_term_link( WP_Term|int|string $term, string $taxonomy = '' )
Thank you!
Felix
Your code works well for getting values for a specific taxonomy (attribute).I only changed the get_terms function.
I also added some data attributes to get the taxonomy and slug of each term (option).
add_filter( 'woocommerce_before_shop_loop','wc_reg_for_menus' );
function wc_reg_for_menus() {
$terms = get_terms( array(
'taxonomy' => 'pa_marke',
'hide_empty' => false,
));
if ( ! empty( $terms ) && ! is_wp_error( $terms ) ){
echo '<select id="shop_pa_marke">';
foreach ( $terms as $term ) {
echo '<option value="' . $term->name . '" data-taxonomy="' . $term->taxonomy . '" data-slug="' . $term->slug . '">' . $term->name . '</option>';
}
echo '</select>';
}
}
Then you will need to use a jQuery script to redirect the user based on the chosen attribute option.
add_action( 'wp_footer', 'redirect_after_select_option' );
function redirect_after_select_option() {
?>
<script type="text/javascript">
jQuery( function($){
$('#shop_pa_marke').change(function(){
const url = window.location.href;
const taxonomy = $(this).children("option:selected").data('taxonomy').replace('pa_','filter_');
const slug = $(this).children("option:selected").data('slug');
let urlParams = new URLSearchParams(window.location.search);
urlParams.set(taxonomy, slug);
window.location.replace( '?'+urlParams.toString() );
});
});
</script>
<?php
}
The code has been tested and works. Add it to your active theme's functions.php.
Thank you!
Just now I found a solution without jQuery, that works quite fine as well:
add_filter('woocommerce_before_shop_loop','wc_reg_for_menus', 1, 2);
function wc_reg_for_menus() {
$terms = get_terms( 'pa_marke' );
if ( ! empty( $terms ) && ! is_wp_error( $terms ) ){
echo '<select onchange="location = this.value;">';
foreach ( $terms as $term ) {
echo '<option value="'.get_term_link( $term ).'">'.$term->name.'</option>';
}
echo '</select>';
}
}
Only after the new page loaded, the first option of the menu is selected again, but that´s ok for me, because it won't be displayed there later on.
I have 2 dropdown boxes, when you select from the first dropdown which is a main category, the second one will then load subcategories for the user to select from.
However, on selecting from the first category dropdown a 0 then shows below the second.
Then when you select a category a 0 shows
Can anyone assist to why this is happening please, Here is my code
if ( ! class_exists( 'frontendAjaxDropdown' ) ):
class frontendAjaxDropdown
{
/**
* Loading WordPress hooks
*/
function __construct()
{
/**
* Add shortcode function
*/
add_shortcode( 'ajax-dropdown', array($this, 'init_shortocde') );
/**
* Register ajax action
*/
add_action( 'wp_ajax_get_subcat', array($this, 'getSubCat') );
/**
* Register ajax action for non loged in user
*/
add_action('wp_ajax_nopriv_get_subcat', array($this, 'getSubCat') );
}
function init_shortocde()
{
$parent_id = 420;
$args = array(
'hierarchical' => 1,
'show_option_none' => '',
'hide_empty' => 0, // Set to 0 to show empty categories and 1 to hide them
'parent' => $parent_id,
'taxonomy' => 'location'
);
$subcategories = get_categories($args);
echo '<select name="main_cat" id="main_cat" class="postform"><option value="">Category...</option>';
;
foreach ($subcategories as $category) {
echo '<option value="' . $category->term_id . '">' . $category->name . '</option>'; // ID of the category as the value of an option
}
echo '</select>';
?>
<script type="text/javascript">
(function($){
$("#main_cat").change(function(){
$("#sub_cat").empty();
$.ajax({
type: "post",
url: "<?php echo admin_url( 'admin-ajax.php' ); ?>",
data: { action: 'get_subcat', cat_id: $("#main_cat option:selected").val() },
beforeSend: function() {$("#loading").fadeIn('slow');},
success: function(data) {
$("#loading").fadeOut('slow');
$("#sub_cat").append(data);
}
});
});
})(jQuery);
</script>
<div id="loading" style="display: none;">Loading...</div>
<div id="sub_cat"></div>
<?php
}
/**
* AJAX action: Shows dropdown for selected parent
*/
function getSubCat()
{
$parent_id = $_POST['cat_id'];
$args = array(
'hierarchical' => 1,
'show_option_none' => '',
'hide_empty' => 1, // Set to 0 to show empty categories and 1 to hide them
'parent' => $parent_id,
'taxonomy' => 'location'
);
$subcategories = get_categories($args);
echo '<select name="sub_cat" id="sub_cat" class="postform"><option value="">Category...</option>';
foreach ($subcategories as $category) {
echo '<option value="' . $category->term_id . '">' . $category->name . '</option>'; // ID of the category as the value of an option
}
echo '</select>';
}
}
endif;
new frontendAjaxDropdown();
At the end of the function getSubCat , add this
wp_die();
Or
die();
This will solve the issue.
I was using the Chosen plugin to populate a second dropdown based on the selection of the first. I would like to change over to the Selectize plugin for performance reasons now, but am having trouble doing so. My setup is as follows:
1st Dropdown = Custom Post Type (type)
2nd Dropdown = Taxonomy (location)
In my functions.php file, I have the following:
// SECOND DROPDOWN
function my_dropdown_categories( $taxonomy, $current_selected = '', $include = null ) {
// Get all terms of the chosen taxonomy
$terms = get_terms($taxonomy, array('orderby' => 'name'));
// our content variable
$list_of_terms = '<select id="location" class="selectboxSingle" name="location">';
if ( ! is_wp_error( $terms ) ) foreach($terms as $term){
// If include array set, exclude unless in array.
if ( is_array( $include ) && ! in_array( $term->slug, $include ) ) continue;
$select = ($current_selected == $term->slug) ? "selected" : ""; // Note: ==
if ($term->parent == 0 ) {
// get children of current parent.
$tchildren = get_term_children($term->term_id, $taxonomy);
$children = array();
foreach ($tchildren as $child) {
$cterm = get_term_by( 'id', $child, $taxonomy );
// If include array set, exclude unless in array.
if ( is_array( $include ) && ! in_array( $cterm->slug, $include ) ) continue;
$children[$cterm->name] = $cterm;
}
ksort($children);
// OPTGROUP FOR PARENTS
if (count($children) > 0 ) {
// $list_of_terms .= '<optgroup label="'. $term->name .'">';
if ($term->count > 0)
$list_of_terms .= '<option class ="group-result" value="'.$term->slug.'" '.$select.'>' . $term->name .' </option>';
} else
$list_of_terms .= '<option value="'.$term->slug.'" '.$select.'>'. $term->name .' </option>';
//$i++;
// now the CHILDREN.
foreach($children as $child) {
$select = ($current_selected == $child->slug) ? "selected" : ""; // Note: child, not cterm
$list_of_terms .= '<option value="'.$child->slug.'" '.$select.'>'. $child->name.' </option>';
} //end foreach
if (count($children) > 0 ) {
$list_of_terms .= "</optgroup>";
}
}
}
$list_of_terms .= '</select>';
return $list_of_terms;
}
// FIRST DROPDOWN
add_action( 'wp_ajax_wpse158929_get_terms_for_cpt', 'wpse158929_get_terms_for_cpt' );
add_action( 'wp_ajax_nopriv_wpse158929_get_terms_for_cpt', 'wpse158929_get_terms_for_cpt' );
function wpse158929_get_terms_for_cpt() {
$ret = array( 'html' => '', 'error' => false );
if ( ! check_ajax_referer( 'wpse158929_get_terms_for_cpt_submit_', 'nonce', false /*die*/ ) ) {
$ret['error'] = __( 'Permission error', 'wpfm' );
} else {
$post_type = isset( $_REQUEST['post_type'] ) ? $_REQUEST['post_type'] : '';
$taxonomy = isset( $_REQUEST['taxonomy'] ) ? $_REQUEST['taxonomy'] : '';
$current_selected = isset( $_REQUEST['current_selected'] ) ? $_REQUEST['current_selected'] : '';
if ( ! $post_type || ! $taxonomy ) {
$ret['error'] = __( 'Params error', 'wpfm' );
} else {
global $wpdb;
$sql = $wpdb->prepare( 'SELECT t.slug FROM ' . $wpdb->terms . ' t'
. ' JOIN ' . $wpdb->term_taxonomy . ' AS tt ON tt.term_id = t.term_id'
. ' JOIN ' . $wpdb->term_relationships . ' AS tr ON tr.term_taxonomy_id = tt.term_taxonomy_id'
. ' JOIN ' . $wpdb->posts . ' AS p ON p.ID = tr.object_id'
. ' WHERE tt.taxonomy = %s AND p.post_type = %s AND p.post_status = %s'
. ' GROUP BY t.slug'
, $taxonomy, $post_type, 'publish' );
$include = $wpdb->get_col($sql);
$ret['html'] = preg_replace( '/<\/?select[^>]*>/', '', my_dropdown_categories( $taxonomy, $current_selected, $include ) );
}
}
wp_send_json( $ret );
}
And for the page with the dropdowns, I have:
<form action="<?php bloginfo('url'); ?>" method="get">
<?php
//$post_type = get_post_type_object( get_post_type($post) ); // GET SINGULAR NAME
$args = array(
'public' => true,
'_builtin' => false
);
$output = 'objects'; // names or objects, note names is the default
$operator = 'and'; // 'and' or 'or'
$post_types = get_post_types($args, $output, $operator);
ksort($post_types);
echo '<select data-placeholder="I need a:" class="fade-in three selectboxSingle" name="post_type">';
foreach ( $post_types as $post_type ) {
$exclude = array('competition');
if(TRUE === in_array($post_type->name,$exclude)){
continue;
}
// Note: I think you need to use query_var here, rather than slug.
echo '<option value="'.$post_type->query_var.'">' . ucfirst($post_type->labels->singular_name) . '</option>';
}
echo "</select>";
?>
<?php
// Set your custom taxonomy
$taxonomy = "location";
// Factored out taxonomy dropdown into function my_dropdown_categories() in "functions.php".
echo my_dropdown_categories( $taxonomy );
?>
<div class="submit-button-blanket">
<button class="submit-button alt" type="submit">Search</button>
</div>
</form>
</div>
</div>
</div>
<script type="text/javascript">
jQuery(document).ready(function($) {
var xhr;
var select_cpt, $select_cpt;
var select_location, $select_location;
$select_cpt = $(".selectboxSingle").selectize({
onChange: function(value) {
if (!value.length) return;
select_location.disable();
select_location.clearOptions();
select_location.load(function(callback) {
xhr && xhr.abort();
xhr = $.ajax({
url: "<?php echo admin_url('admin-ajax.php'); ?>",
success: function(results) {
select_location.enable();
callback(results);
},
error: function() {
callback();
}
})
});
}
});
$select_location = $('#location').selectize({
valueField: 'name',
labelField: 'name',
searchField: ['name']
});
select_location = $select_location[0].selectize;
select_cpt = $select_cpt[0].selectize;
select_location.disable();
});
I've gone a bit out of my depth here now, and any guidance would be greatly appreciated!!
I added a content rating system to my platform where the authors can select which audience their post is appropriate for. Currently, these options are available:
Unrated
G
PG
R
The code that I use to display the rating options on the post edit page is:
// Article Content Rating
add_action( 'add_meta_boxes', 'rating_select_box' );
function rating_select_box() {
add_meta_box(
'rating_select_box', // id, used as the html id att
__( 'Content Rating (optional)' ), // meta box title
'rating_select_cb', // callback function, spits out the content
'post', // post type or page. This adds to posts only
'side', // context, where on the screen
'low' // priority, where should this go in the context
);
}
function rating_select_cb( $post ) {
global $wpdb;
$value = get_post_meta($post->ID, 'rating', true);
echo '<div class="misc-pub-section misc-pub-section-last"><span id="timestamp"><label>Article Content Rating: </label>';
$ratings = array(
1 => ' G ',
2 => ' PG ',
3 => ' R ',
);
echo '<select name="rating">';
echo '<option value=""' . ((($value == '') || !isset($ratings[$value])) ? ' selected="selected"' : '') . '> Unrated </option>';
// output each rating as an option
foreach ($ratings as $id => $text) {
echo '<option value="' . $id . '"' . (($value == $id) ? ' selected="selected"' : '') . '">' . $text. '</option>';
}
echo '</select>';
echo '</span></div>';
}
add_action( 'save_post', 'save_metadata');
function save_metadata($postid)
{
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return false;
if ( !current_user_can( 'edit_page', $postid ) ) return false;
if( empty($postid) ) return false;
if ( is_null($_REQUEST["rating"]) ) {
delete_post_meta($postid, 'rating');
} else {
update_post_meta($postid, 'rating', $_REQUEST['rating']);
}
}
// END Article Content Rating
Now, the problem is, what code do I add to single.php to display their choice? So for instance, if the author selected PG, then I want to echo 'Content Rating: PG'; or if it was on default (unrated), I want to echo 'Content Rating: Unrated';. How is this possible? Ideally, a solution that is light on the server as my platform is heavily trafficked.
You already use the delete_post_meta() and update_post_meta() functions to remove and modify the custom values. Simply use the get_post_meta() function to obtain the value for the current post, and echo it out as you see fit.
If you're in The Loop, it would be something like:
$rating = get_post_meta(get_the_ID(), 'rating', TRUE);
Edit:
You already know your ID to rating mapping (I might make this mapping a global array, or some defines, or something similar). Simply use that to look up the string to output:
$ratings = array(
1 => 'G',
2 => 'PG',
3 => 'R'
);
if(array_key_exists($rating, $ratings)) {
echo "Content Rating: $ratings[$rating]";
} else {
echo "Content Rating: Unrated";
}
It looks as if you're saving the key to your custom field rather than its value. I suppose this would be alright if you planned on redeclaring your $ratings array, or (God forbid) use it globally. But still, it would probably be best if you saved the actual Rating rather than its ID number.
So change this line:
foreach ($ratings as $id => $text) {
echo '<option value="' . $id . '"' . (($value == $id) ? ' selected="selected"' : '') . '">' . $text. '</option>';
}
To this:
echo '<option value="Unrated"' . ((!$value || $value == 'Unrated' ? ' selected="selected"' : '') . '">Unrated</option>';
foreach ($ratings as $id => $text) {
echo '<option value="' .trim($text). '"' . (($value == trim($text)) ? ' selected="selected"' : '') . '">' . $text. '</option>';
}
After setting your value within the post, you can add this in single.php:
if(have_posts()) : while(have_posts()) : the_post();
echo 'Content Rating: '.get_post_meta($post->ID, 'rating', true);
endwhile;endif;
UPDATE:
As mentioned in my comments, I personally try to avoid globals and redeclaring things as much as possible. So if you would prefer to still reference your ratings by Key, you can get around globals and redeclaring your ratings array by adding a few simple functions:
functions.php
function gw_get_ratings_array()
{
$ratings = array(
1 => 'G',
2 => 'PG',
3 => 'R'
);
return $ratings;
}
function gw_get_rating($key=0)
{
$i = (int)$key;
$ratings = gw_get_ratings_array();
return isset($ratings[$i]) && $ratings[$i] ? $ratings[$i] : 'Unrated';
}
single.php
if(have_posts()) : while(have_posts()) : the_post();
$rating_id = get_post_meta($post->ID, 'rating', true);
echo 'Content Rating: '.gw_get_rating($rating_id);
endwhile;endif;
This way, if you ever need to add more Rating Types, you only need to alter the gw_get_ratings_array function rather than searching for each declaration of the array itself.
Adding the following script to the function.php file in Wordpress:
add_action( 'add_meta_boxes', 'rating_select_box' );
function rating_select_box() {
add_meta_box(
'rating_select_box', // id, used as the html id att
__( 'Select rating:' ), // meta box title, like "Page Attributes"
'rating_select_cb', // callback function, spits out the content
'post', // post type or page. We'll add this to posts only
'side', // context (where on the screen
'low' // priority, where should this go in the context?
);
}
function rating_select_cb( $post )
{
global $wpdb;
$value = get_post_meta($post->ID, 'rating', true);
echo '<div class="misc-pub-section misc-pub-section-last">
<span id="timestamp">'
. '<label>Select a rating:<br></label>';
$selected = ($value == $result->post_name) ? ' selected="selected" ' : null;
echo '<select name="rating">';
echo '<option value="" default="default"> None... </option>';
echo '<option value="0" '.$selected.'> G — Suitable for all audiences </option>';
echo '<option value="1" '.$selected.'> PG — Possibly offensive, usually for audiences 13 and above </option>';
echo '<option value="2" '.$selected.'> R — Intended for adult audiences above 17 </option>';
echo '<option value="3" '.$selected.'> X — Even more mature than above </option>';
echo '</select>';
echo '</span></div>';
}
add_action( 'save_post', 'save_metadata');
function save_metadata($postid)
{
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return false;
if ( !current_user_can( 'edit_page', $postid ) ) return false;
if( empty($postid) ) return false;
if ( is_null($_REQUEST["rating"]) ) {
delete_post_meta($postid, 'rating');
} else {
update_post_meta($postid, 'rating', $_REQUEST['rating']);
}
}
Will add a box in the post page with a drop down list. I want the default option to be on None... so I added a default="default" to that option, but it does not work. By default, the highest number value is selected, in this case, it is X — Even more mature than above.
What am I doing wrong? How can I make it so that the None... option is selected by default?
In a select list, the correct way to "select" an option is with selected="selected", not default="default". Changing your 'None' option to the following should fix it:
echo '<option value="" selected="selected"> None... </option>';
However, you're not dynamically creating your select list, you're just outputting a full list and you'll run into issues selecting the other values too. To fix this, if the options won't be changing, you can put them in an array to loop through them. You can modify your rating_select_cb() method with the following new code to achieve this:
function rating_select_cb( $post ) {
global $wpdb;
$value = get_post_meta($post->ID, 'rating', true);
echo '<div class="misc-pub-section misc-pub-section-last"><span id="timestamp"><label>Select a rating:<br></label>';
// build an array of each available rating
$ratings = array(
1 => 'G — Suitable for all audiences',
2 => 'PG — Possibly offensive, usually for audiences 13 and above',
3 => 'R — Intended for adult audiences above 17',
4 => 'X — Even more mature than above'
);
echo '<select name="rating">';
echo '<option value=""' . ((($value == '') || !isset($ratings[$value])) ? ' selected="selected"' : '') . '> None... </option>';
// output each rating as an option
foreach ($ratings as $id => $text) {
echo '<option value="' . $id . '"' . (($value == $id) ? ' selected="selected"' : '') . '">' . $text. '</option>';
}
echo '</select>';
echo '</span></div>';
}
This method will default-select the "None" option if the selected $value is not in the available list of ratings. After that, it will loop through each rating and output it as an option. If the rating's $id matches the selected $value, it will be marked as selected.
You should use it like this:
echo '<option value="" selected="selected"> None... </option>';