0

I am retrieving taxonomy terms. The code is working.
Foreach creates three options for the select tag. There are three terms. But, when I wanted to echo "selected" for each options, after selecting one. it returns odd result. What is the problem? Here is the code.

$terms = get_terms( 'department' );
    if ( ! empty( $terms ) && ! is_wp_error( $terms ) ){
        echo '<select class="widefat" name="departments">';
            foreach ( $terms as $term ) {
                echo '<option value="'. $term->name .'"'.($_POST['departments'] == $term->name) ? ' selected="selected" ' : ''.'>'. $term->name . '</option>';
            }
        echo '</select>';

    }

Returns this:

<select class="widefat" name="departments"> selected="selected"  selected="selected"  selected="selected" </select>

Custom post name: employee Taxonomy name: department There are three terms available: Web Designer, Web Developer, Graphics Designer

I am getting the taxonomy terms if I use this code.

$terms = get_terms( 'department' );
if ( ! empty( $terms ) && ! is_wp_error( $terms ) ){
  echo '<select class="widefat" name="departments">';
    foreach ( $terms as $term ) {
      $value = $term->name;
         for ($i=0; $i < count($term); $i++) { 
            echo '<option value="'
               . $value .'"'.'>'
               . $value . '</option>';
    }

}
echo '</select>';

Returns:

<select class="widefat" name="departments">
<option value="Graphic Designer">Graphic Designer</option>
<option value="Web Designer">Web Designer</option>
<option value="Web Devloper">Web Devloper</option>
</select>

But if I want to implement selected into the selected option then it is collapsing.

I want to add if you chose Graphic Designer then the option would look like

<option value="Graphic Designer" selected="selected">Graphic Designer</option>

But this is not happening.

1
  • Of note, you'll want to include code that sanitises the values, otherwise you'll have issues once you start adding departments or roles that include characters that can't go inside attribute values, e.g. quotes. Consider using the term slug as the value, and using the term name purely for descriptive purposes, rather than using the name for both
    – Tom J Nowell
    Commented Feb 19, 2016 at 1:11

2 Answers 2

0

I believe this has more to do with the ternary operator being used inside of string concatenation.

I would eliminate this issue by relying on a classic if statement, but WordPress provides a helpful function selected, giving us:

$terms = get_terms( 'department' );
if ( ! empty( $terms ) && ! is_wp_error( $terms ) ) {
    echo '<select class="widefat" name="departments">';
    foreach ( $terms as $term ) {
        echo '<option value="'. $term->name .'"'.selected($_POST['departments'], $term->name, false ).'>'. $term->name . '</option>';
    }
    echo '</select>';

}

However, there is something more egregious going on here that is unrelated to your question. What if we have a term named "><script>alert('hello world');</script><option>? We have an avenue for an injection attack here due to an unescaped variable output. So lets update the code with some escaping so that it's secure:

$terms = get_terms( 'department' );
if ( ! empty( $terms ) && ! is_wp_error( $terms ) ) {
    echo '<select class="widefat" name="departments">';
    foreach ( $terms as $term ) {
        echo '<option value="'. esc_attr( $term->name ) .'"'.selected($_POST['departments'], $term->name, false).'>'. esc_html( $term->name ) . '</option>';
    }
    echo '</select>';

}

Now any HTML or entities that may have been unexpectedly inserted have been made safe, and the code is secure. We can also simplify the code to make it easier to read:

$terms = get_terms( 'department' );
if ( ! empty( $terms ) && ! is_wp_error( $terms ) ) {
    echo '<select class="widefat" name="departments">';
    foreach ( $terms as $term ) {
        ?>
        <option value="<?php echo esc_attr( $term->name ); ?>"
            <?php selected($_POST['departments'], $term->name);?>>
            <?php echo esc_html( $term->name );?>
        </option>
        <?php
    }
    echo '</select>';

}
7
  • Thank you. I am using term slug for values. It is working. After selecting option if I click "save" button it is echoing "selected". But I want to echo "selected" without submitting.When someone select an option then it must echo. How to do that?
    – rushdi
    Commented Feb 19, 2016 at 1:19
  • You want to change the markup without doing a page load, you'll need to use javascript. The browser should handle that. By the time the user has selected something, PHP has finished its job and the server has ended the connection, the page has been generated and you can't go back and change it via PHP. You need to use javascript. That's beyond the scope of this site as it's no longer WordPress specific
    – Tom J Nowell
    Commented Feb 19, 2016 at 1:37
  • hmm or do you mean you need it to show the selected one that you've saved? You've not shown how you've saved this option, but you would need to change what you pass into the selected function, namely the $_POST['departments']. Retrieve your saved value and pass that into selected instead
    – Tom J Nowell
    Commented Feb 19, 2016 at 1:39
  • What I am trying to do is there are 3 taxonomy terms - web Developer, Web Designer, Graphic Designer - which are retrieving and showing as an option. Now if you select 1 option then php echo selected without pressing save button. Suppose, you select Graphic designer then it will be selected. Another script take the value of option graphic designer and retrieve the posts that has the term graphic designer and generate another select box. First select box: Departmens |_ Graphic designer |_ Web developer |_ Web designer You select Web designer Then 2nd select box Employee |_ 1 |_ 2
    – rushdi
    Commented Feb 19, 2016 at 6:34
  • As I said, instead of passing $_POST['departments'] into the selected function, pass a variable instead, and give that variable the value of your option. If you're asking for a quick copy paste I will not give it, but the solution is trivial if you understand basic beginner PHP. Please read up on function arguments and variables. Also get_option() is your friend.
    – Tom J Nowell
    Commented Feb 19, 2016 at 13:49
0

I think an alternative to using get_terms() is to use get_categories() instead.

Here's a snippet i did with your codes:

    $args = ['taxonomy'  => 'department'];
    $terms = get_categories($args);
    if ( ! empty( $terms ) && ! is_wp_error( $terms ) ){
    echo '<select class="widefat" name="departments">';
        foreach ( $terms as $term ) {
            echo '<option value="'. $term->name .'"'.($_POST['departments'] == $term->name) ? ' selected="selected" ' : ''.'>'. $term->name . '</option>';
        }
    echo '</select>';
}

Hope it will help you.

4
  • WIthout the "selected" part my code is working too. If I add selected part then it is not working.
    – rushdi
    Commented Feb 19, 2016 at 0:57
  • hmmm. are you trying to get the term of the department taxonomy where the post is link by using '$_POST[]'? Commented Feb 19, 2016 at 0:59
  • NO, check the edited question.
    – rushdi
    Commented Feb 19, 2016 at 1:08
  • Just a note, get_categories() actually uses get_terms() ;-) Commented Feb 19, 2016 at 4:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.