#1
  1. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2010
    Posts
    195
    Rep Power
    45

    Marking <select> option as "selected" based on another array.


    That thread title is probably clear as mud. Let me try to do better in my explanation.

    I am using PHP to create a form <select> field based on an existing array ($popular_articles). Since I want to use the same form for both creating a new submission, as well as editing an existing submission, I've added an if statement that checks to see if the url var ($_GET['date']) exists. If it does, it runs an additional bit of code to mark the previously selected articles as "selected".

    Here's a snippet of code to illustrate what I'm doing:

    PHP Code:
    $popular_articles = array("312" => "Headline 1","288" => "Headline 2","184" => "Headline 3","100" => "Headline 4","94" => "Headline 5");
    $popular_articles_selected = array("312","100","94");

    $counter 1;
    $max_articles 3;
    while(
    $counter <= $max_articles) {
        echo 
    "
        <div data-role='fieldcontain' class='noborder'>
            <label for='email_popular_article"
    .$counter."'><strong>Popular Article #".$counter."</strong></label>
            <select data-native-menu='false' name='email_popular_article[]' id='email_popular_article"
    .$counter."'>            
                <option data-placeholder='true'>Choose an article...</option>"
    ;
        foreach(
    $popular_articles} as $article_ID => $article_headline) {
            
    $selected '';
            if(
    $_GET['date']!='' && in_array($article_ID,$popular_articles_selected)) {
                
    $selected ' selected';                            
                unset(
    $popular_articles_selected[$article_ID]);
            }
            
            echo 
    "
                <option value='
    $article_ID'$selected>".stripslashes($article_headline)."</option>\n";
        }                
        echo 
    "
            </select>
        </div>\n"
    ;
        
    $counter++;

    As you can see above, I tried using unset() to remove the first array value once it has been selected. Thus, on the next loop, the <select> box will mark the next item in $popular_articles_selected as "selected". At least in theory, since it's not working. It works when I simply hardcode the unset() line after the array creation, but once it's in the loop, it's like it's rebuilding the array each time.

    The result is that I end up with 3 select boxes all of which have the same article selected. I need them to each have one of the articles stored in $popular_articles_selected.

    Does that make any sense at all?
    Last edited by BlackAce; December 20th, 2012 at 12:33 PM.
  2. #2
  3. Sarcky
    Devshed Supreme Being (6500+ posts)

    Join Date
    Oct 2006
    Location
    Pennsylvania, USA
    Posts
    10,846
    Rep Power
    6351
    $popular_articles_selected[$article_ID]

    If $article_ID is 312, that snip would refer to index 312 of $popular_articles_selected, which doesn't exist.

    You want something more like

    unset($popular_articles_selected[array_search($article_ID, $popular_articles_selected)]);

    Though this isn't how I'd do it.
    HEY! YOU! Read the New User Guide and Forum Rules

    "They that can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety." -Benjamin Franklin

    "The greatest tragedy of this changing society is that people who never knew what it was like before will simply assume that this is the way things are supposed to be." -2600 Magazine, Fall 2002

    Think we're being rude? Maybe you asked a bad question or you're a Help Vampire. Trying to argue intelligently? Please read this.
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2010
    Posts
    195
    Rep Power
    45
    Originally Posted by ManiacDan
    Though this isn't how I'd do it.
    Don't be shy...

    I tried what you provided and it does indeed stop all of the selects from using the same article. However, after selecting one for the first dropdown, the others are left without any articles selected.

    EDIT: Further investigation shows that it is always "selecting" the last element in the $popular_articles_selected array. If I reverse sort the array before running the above code, it does select another element for the first box, but the second box is still left "unselected."

    I assume this is because unset is unsetting the last item in the array, and since there are no more items in the array for the next dropdown to display, it is showing as blank?
    Last edited by BlackAce; December 20th, 2012 at 01:40 PM.
  6. #4
  7. Sarcky
    Devshed Supreme Being (6500+ posts)

    Join Date
    Oct 2006
    Location
    Pennsylvania, USA
    Posts
    10,846
    Rep Power
    6351
    I would keep a pointer to the selected_articles array, then ++ it at the end of your loop along with $counter.

    You're using stripslashes in this code, which says very bad things about your setup. Why?

    Also, I don't know what this means:
    after selecting one for the first dropdown, the others are left without any articles selected
    Unless there's javascript or something in the page that you're not showing, this doesn't make sense.
    HEY! YOU! Read the New User Guide and Forum Rules

    "They that can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety." -Benjamin Franklin

    "The greatest tragedy of this changing society is that people who never knew what it was like before will simply assume that this is the way things are supposed to be." -2600 Magazine, Fall 2002

    Think we're being rude? Maybe you asked a bad question or you're a Help Vampire. Trying to argue intelligently? Please read this.
  8. #5
  9. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2010
    Posts
    195
    Rep Power
    45
    Originally Posted by ManiacDan
    I would keep a pointer to the selected_articles array, then ++ it at the end of your loop along with $counter.
    Let me try that. I had ventured down this road before without success, but I'm willing to give it a shot if you think this is better practice.

    Originally Posted by ManiacDan
    You're using stripslashes in this code, which says very bad things about your setup. Why?
    I'm using this to prevent the escape slashes from showing on headlines that contain an apostrophe. For display only. Can you explain why this is bad?

    Originally Posted by ManiacDan
    Also, I don't know what this means:
    Unless there's javascript or something in the page that you're not showing, this doesn't make sense.
    Let me try again. In the example I gave above, 3 dropdown boxes are created by the loop ($max_articles=3). When I added your code, the first of these dropdowns has an article selected (<option value='94' selected>). The other two dropdowns default back to the placeholder option (<option data-placeholder='true'>Choose an article...</option>), with nothing marked as the selected item.

    I appreciate your help, as always.
  10. #6
  11. Sarcky
    Devshed Supreme Being (6500+ posts)

    Join Date
    Oct 2006
    Location
    Pennsylvania, USA
    Posts
    10,846
    Rep Power
    6351
    I'm using this to prevent the escape slashes from showing on headlines that contain an apostrophe. For display only. Can you explain why this is bad?
    Strip_slashes only works on code which has magic_quotes or addslashes in it, both of which are wrong and ancient. If you have escaped quotes in your database, you're probably inserting it wrong.

    Working version of your code:

    PHP Code:
    $popular_articles = array("312" => "Headline 1","288" => "Headline 2","184" => "Headline 3","100" => "Headline 4","94" => "Headline 5"); 
    $popular_articles_selected = array("312","100","94"); 

    $counter 1
    $popular 0;
    $max_articles 3
    while(
    $counter <= $max_articles) { 
        echo 

        <div data-role='fieldcontain' class='noborder'> 
            <label for='email_popular_article"
    .$counter."'><strong>Popular Article #".$counter."</strong></label> 
            <select data-native-menu='false' name='email_popular_article[]' id='email_popular_article"
    .$counter."'>             
                <option data-placeholder='true'>Choose an article...</option>"

        foreach(
    $popular_articles as $article_ID => $article_headline) { 
            
    $selected ''
            if(
    $_GET['date']!='' && $article_ID == $popular_articles_selected[$popular]) { 
                
    $selected ' selected';                             
            } 
             
            echo 

                <option value='
    $article_ID'$selected>".stripslashes($article_headline)."</option>\n"
        }                 
        echo 

            </select> 
        </div>\n"

        
    $counter++; 
        
    $popular++;

    This won't work if $_GET['date'] isn't set, just like your original code.
    HEY! YOU! Read the New User Guide and Forum Rules

    "They that can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety." -Benjamin Franklin

    "The greatest tragedy of this changing society is that people who never knew what it was like before will simply assume that this is the way things are supposed to be." -2600 Magazine, Fall 2002

    Think we're being rude? Maybe you asked a bad question or you're a Help Vampire. Trying to argue intelligently? Please read this.
  12. #7
  13. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2010
    Posts
    195
    Rep Power
    45
    Works like a charm. You version is just slightly different than the one I was working up, but I like how you used the pointer whereas I was just using a counter with a while statement. Yours is shorter, cleaner, and frankly, I trust you more than I trust myself, so I've implemented your version.

    The issue with it using the last array value wasn't actually valid. I was querying the database wrong... had it sorting DESC instead of ASC, which in turn, reversed the order of the array values.

    Originally Posted by ManiacDan
    Strip_slashes only works on code which has magic_quotes or addslashes in it, both of which are wrong and ancient. If you have escaped quotes in your database, you're probably inserting it wrong.
    I'll dig around on this some more. This is an older site that I'm adding some functionality to, and I don't do this all the time, so I may be a bit out of date. The headlines are added to the database using mysql_real_escape_string(). I'll do some research to learn more about the deprecation of this that you are referencing.

    Also, since you mentioned magic quotes, I was pretty sure they were on this server from what I remember. Just ran a test using:

    PHP Code:
    if (get_magic_quotes_gpc()) {
            echo 
    "Magic Quotes are ON!";

    and it confirmed that they are indeed on this server. We are using the default Bluehost setup.
  14. #8
  15. Sarcky
    Devshed Supreme Being (6500+ posts)

    Join Date
    Oct 2006
    Location
    Pennsylvania, USA
    Posts
    10,846
    Rep Power
    6351
    If magic quotes are on, that's a pretty bad thing. They were officially deprecated more than a decade ago and have been solidly on the "worst practices" list for nearly that long. I would call your host or even switch hosts.
    HEY! YOU! Read the New User Guide and Forum Rules

    "They that can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety." -Benjamin Franklin

    "The greatest tragedy of this changing society is that people who never knew what it was like before will simply assume that this is the way things are supposed to be." -2600 Magazine, Fall 2002

    Think we're being rude? Maybe you asked a bad question or you're a Help Vampire. Trying to argue intelligently? Please read this.

IMN logo majestic logo threadwatch logo seochat tools logo