Getting Multiple Select Box Options to Stay Selected Using Chosen Select

I’m trying to get the selected options to stay selected in the following select box. (The select box resides in the Menus page in WordPress admin). I’ve verified the data is being saved to the database, but I’m having difficulty figuring out to get the data back from the database to mark the options selected for a given select box after the page is saved. There are multiple select boxes on the page.

enter image description here

Read More

The select box makes use of the Chosen Select jQuery plugin. Here’s a question and answer providing some guidance on marking the options selected with JS: Chosen select an option by default with jQuery. I couldn’t get it to work having multiple select boxes on the page.

<script type="text/javascript">
    jQuery(document).ready(function($){ 
        $(".chzn-select").chosen();
    });
</script>

<select name="locations[<?php echo $item_id; ?>]" id="edit-menu-item-visibility-<?php echo $item_id; ?>" class="chzn-select" multiple="true">
    <option value="DZ">Algeria</option>
    <option value="AS">American Samoa</option>
    <option value="AD">Andorra</option>
    ...

This is how the data gets to the database:

function update_option_text( $menu_id, $menu_item_db_id, $args ) {
    $meta_value = get_post_meta( $menu_item_db_id, 'locations', true );
    $new_meta_value = stripcslashes( $_POST['locations'][$menu_item_db_id] );
    if( '' == $new_meta_value ) {
        delete_post_meta( $menu_item_db_id, 'locations', $meta_value );
    }
    elseif( $meta_value !== $new_meta_value ) {
        update_post_meta( $menu_item_db_id, 'locations', $new_meta_value );
    }
}

Below is my non-working attempt. If I understand correctly, the values can be set to selected with JS. But I couldn’t get that to work either. Any assistance is greatly appreciated.

<option value="AF" <?php $val = implode(",",get_post_meta( $menu_item_db_id, 'locations', true )); if(in_array("AF", $val)){echo "selected='selected'";}else{echo "";} ?> >Afghanistan</option>

Here is how the original text input worked:

<input
    type="text" 
    class="widefat code" 
    id="edit-menu-item-visibility-<?php echo $item_id; ?>" 
    name="locations[<?php echo $item_id; ?>]" 
    value="<?php echo esc_html( get_post_meta( $item_id, 'locations', true ) ); ?>" />
    <?php echo 'Enter 2-digit country codes separated by commas, e.g. US,CA,SG' ?></br>

The entire file can be found here.

UPDATE:

$val = get_post_meta( $item_id, 'locations', true );
$val2 = array_filter(array_map('trim', explode(',', strtoupper(get_post_meta( $item_id, 'locations', true )))));
var_dump($val);
echo "</br>";   
var_dump($val2);

Gives string(2) "AD" and array(1) { [0]=> string(2) "AD" }(The value “AD” being one of my selections.)

No matter how many options are selected, it only returns one country code.

UPDATE:

This is what finally worked…

<select name="menu-item-visibility[<?php echo $item_id; ?>][]" id="edit-menu-item-visibility-<?php echo $item_id; ?>" class="chzn-select" multiple="true">
    <option value="TH" <?php 
                        $val = get_post_meta( $item_id, 'locations', true );
                        if(is_array($val)) {
                            if(in_array("TH", $val)) {
                                echo "selected='selected'";
                            } else {
                                echo "";
                            }
                        } 
                        ?> >Thailand</option>

Related posts

2 comments

  1. As you have written

    <option value="AF" <?php $val = implode(",",get_post_meta( $menu_item_db_id, 'locations', true )); if(in_array("AF", $val)){echo "selected='selected'";}else{echo "";} ?> >Afghanistan</option>
    

    The implode() function will convert the array to a string , so no logic of using in_array()

    Alternative 1

    If get_post_meta( $menu_item_db_id, 'locations', true ) is providing an array, then use the below code instead :

    <option value="AF" <?php $val = get_post_meta( $menu_item_db_id, 'locations', true ); if(in_array("AF", $val)){echo "selected='selected'";}else{echo "";} ?> >Afghanistan</option>
    

    Alternative 2

    If the value is saved as a serialized string then need to unserialize the output first then check it by in_array()

    So use maybe_unserialize() : It Unserialize value only if it was serialized.

    So the code becomes :

    <option value="AF" <?php $val = maybe_unserialize(get_post_meta( $menu_item_db_id, 'locations', true )); if(in_array("AF", $val)){echo "selected='selected'";}else{echo "";} ?> >Afghanistan</option>
    

    Alternative 3

    Use the code as per Alternative 2 and put the script below the <select>
    that is :

    <select></select>
    <script type="text/javascript">
        jQuery(document).ready(function($){ 
            $(".chzn-select").chosen();
        });
    </script>
    

    One important thing

    First try to print the output of like

    $val = get_post_meta( $menu_item_db_id, 'locations', true );
    echo '<pre>';
    print_r($val);
    echo '</pre>';
    

    So you will be sure that you are not getting a blank output.

    Update

    As you told in your update , no matter how many countries you select it only saves one country.

    This might be because the name of select box is not an array to save multiple location values

    Replace this

    <select name="locations[<?php echo $item_id; ?>]" id="edit-menu-item-visibility-<?php echo $item_id; ?>" class="chzn-select" multiple="true">
        <option value="DZ">Algeria</option>
        <option value="AS">American Samoa</option>
        <option value="AD">Andorra</option>
        ...
    

    To

    <select name="locations[<?php echo $item_id; ?>][]" id="edit-menu-item-visibility-<?php echo $item_id; ?>" class="chzn-select" multiple="true">
            <option value="DZ">Algeria</option>
            <option value="AS">American Samoa</option>
            <option value="AD">Andorra</option>
            ...
    

    And then your code $meta_value = get_post_meta( $menu_item_db_id, 'locations', true ); should get an array of values of countries

    rest all the above code might work then .. try printing the $val output again after changing the code as in the update.. below code might get you multiple values in array now

    $val = get_post_meta( $menu_item_db_id, 'locations', true );
        echo '<pre>';
        print_r($val);
        echo '</pre>';
    
  2. Assuming that $locations is an array of selected country codes,

    <option value="DZ"<?php echo (in_array('DZ', $locations)) ? ' selected' : '' ?>>Algeria</option>
    

    and so forth for every other option. I’m not quite sure in which format WordPress stores your $locations array though, so you have to figure that one out on your own.

Comments are closed.