{"id":611,"date":"2010-07-16T16:56:55","date_gmt":"2010-07-16T21:56:55","guid":{"rendered":"http:\/\/cssnewbie.com\/?p=611"},"modified":"2010-07-16T16:56:55","modified_gmt":"2010-07-16T21:56:55","slug":"intelligent-select-box-filtering","status":"publish","type":"post","link":"https:\/\/cssdeck.com\/blog\/intelligent-select-box-filtering\/","title":{"rendered":"Intelligent Select Box Filtering"},"content":{"rendered":"<p><a href=\"http:\/\/cssnewbie.com\/example\/filtering-select-boxes\/\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/cssdeck.com\/blog\/wp-content\/uploads\/2010\/07\/filtering-select.png\" alt=\"\" title=\"Intelligent Select Box Filtering\" width=\"500\" height=\"200\" class=\"alignnone size-full wp-image-613\" \/><\/a><\/p>\n<p>One of the great things about building websites for a living is the challenges tend to change from day to day. There\u2019s always a new puzzle to solve.<\/p>\n<p>Take today, for example. I was building a page that contained a series of select (dropdown) boxes. Now, I\u2019ve been around the block once or twice before, and this wasn\u2019t my first time using selects. However, this implementation came with a unique twist: all the boxes contained the exact same options, but we only wanted each to be selectable once. Specifically, each box contained a list of security questions &mdash; your mom\u2019s best friend\u2019s grandmother\u2019s maiden name, that sort of thing. <\/p>\n<p>The code looks something like this:<\/p>\n<pre lang=\"html4strict\" escaped=\"true\">&lt;select class=&quot;security&quot; name=&quot;security1&quot;&gt;\n\t&lt;option value=&quot;0&quot;&gt;Select a question.&lt;\/option&gt;\n\t&lt;option value=&quot;1&quot;&gt;Who's your daddy?&lt;\/option&gt;\n\t&lt;option value=&quot;2&quot;&gt;What's your favorite color?&lt;\/option&gt;\n\t&lt;option value=&quot;3&quot;&gt;What time is it?&lt;\/option&gt;\n&lt;\/select&gt;\n&lt;select class=&quot;security&quot; name=&quot;security2&quot;&gt;\n\t&lt;option value=&quot;0&quot;&gt;Select a question.&lt;\/option&gt;\n\t&lt;option value=&quot;1&quot;&gt;Who's your daddy?&lt;\/option&gt;\n\t&lt;option value=&quot;2&quot;&gt;What's your favorite color?&lt;\/option&gt;\n\t&lt;option value=&quot;3&quot;&gt;What time is it?&lt;\/option&gt;\n&lt;\/select&gt;<\/pre>\n<p>Now, naturally, we want the user to select several different security questions. But what\u2019s to stop them from selecting the same question several times? Well, in our case, back-end validation&#8230; but I wanted to solve the problem before we got to that point. I wanted to eliminate \u201cselected\u201d questions from all the other dropdown boxes, so it wouldn&#8217;t even be an option. This has the added benefit of shortening the list of options as the user goes along, which would make scanning the options easier.<!--more--><\/p>\n<p>After a bit of playing, I came up with the following jQuery script which seems to do the trick:<\/p>\n<pre lang=\"javascript\" escaped=\"true\">$(function () {\n  $('.security').change(function () {\n    $('.security option').show(0);\n    $('.security option:selected').each(function () {\n      oIndex = $(this).index();\n      if (oIndex &gt; 0) {\n        $('.security').each(function () {\n          $(this).children('option').eq(oIndex).not(':selected').hide(0);\n        });\n      }\n    });\n  });\n  $('.security').change();\n});<\/pre>\n<p>I\u2019ll walk you through what I\u2019m doing here.<\/p>\n<p>First, we\u2019re setting the script to fire whenever the \u201csecurity\u201d select boxes are changed. In other words, whenever someone makes a new selection in one of our dropdowns.<\/p>\n<p>When a selection is made, the first thing we do is re-display any previously hidden options, to put us back on even footing. Then we loop through each of the selected options in our select boxes. If the first item isn\u2019t selected, we\u2019ll proceed. (In our use-case, the first option was a generic \u201cmake a selection\u201d option, so I didn\u2019t want it to count as a question).<\/p>\n<p>Once we know a true question has been selected, we\u2019ll loop through all our select boxes. We\u2019re making heavy use of the jQuery .index() and .eq() functions here. Both functions use the idea of zero-based array indexing to number all of our elements; the fifth option in a dropdown would have an index of 4, the third dropdown with a class of \u201csecurity\u201d would have an index of 2, and so on. The .index() function lets us grab the index number of any item we already have, and the .eq() function lets us specify which new element we want to grab.<\/p>\n<p>So first up, we grab the index value of the currently selected option. Since all of our questions are in the same order in each dropdown, those questions have the same indexes across the board. Then we loop through each of our select boxes. If the option is <strong>not currently selected<\/strong> in that dropdown, we hide it \u2013 in other words, the only dropdown that will still contain that question is the one in which it was already selected.<\/p>\n<p>And then, at the very end, we fire our change function. The first time our page loads, that won\u2019t do much. But if anyone refreshes the browser window, the browser will save their select options&#8230; which means we need to filter them right when the page loads. Otherwise, all of our questions would be visible again whenever the page reloaded.<\/p>\n<p><a href=\"http:\/\/cssnewbie.com\/example\/filtering-select-boxes\/\">I put together a demo here. Take a look!<\/a><\/p>\n<div class=\"wp-socializer wpsr-share-icons \" data-lg-action=\"show\" data-sm-action=\"show\" data-sm-width=\"768\" ><h3>Share and Enjoy !<\/h3><div class=\"wpsr-si-inner\"><div class=\"wpsr-counter wpsrc-sz-32px\" style=\"color:#000\"><span class=\"scount\"><span data-wpsrs=\"\" data-wpsrs-svcs=\"facebook,twitter,linkedin,pinterest,print,pdf\">0<\/span><\/span><small class=\"stext\">Shares<\/small><\/div><div class=\"socializer sr-popup sr-32px sr-circle sr-opacity sr-pad sr-count-1 sr-count-1\"><span class=\"sr-facebook\"><a rel=\"nofollow\" href=\"https:\/\/www.facebook.com\/share.php?u=\" target=\"_blank\"  title=\"Share this on Facebook\"  style=\"color: #ffffff\" ><i class=\"fab fa-facebook-f\"><\/i><span class=\"ctext\"><span data-wpsrs=\"\" data-wpsrs-svcs=\"facebook\">0<\/span><\/span><\/a><\/span>\n<span class=\"sr-twitter\"><a rel=\"nofollow\" href=\"https:\/\/twitter.com\/intent\/tweet?text=%20-%20%20\" target=\"_blank\"  title=\"Tweet this !\"  style=\"color: #ffffff\" ><i class=\"fab fa-twitter\"><\/i><\/a><\/span>\n<span class=\"sr-linkedin\"><a rel=\"nofollow\" href=\"https:\/\/www.linkedin.com\/sharing\/share-offsite\/?url=\" target=\"_blank\"  title=\"Add this to LinkedIn\"  style=\"color: #ffffff\" ><i class=\"fab fa-linkedin-in\"><\/i><\/a><\/span>\n<span class=\"sr-pinterest\"><a rel=\"nofollow\" href=\"https:\/\/www.pinterest.com\/pin\/create\/button\/?url=&amp;media=&amp;description=\" target=\"_blank\"  title=\"Submit this to Pinterest\"  style=\"color: #ffffff\" data-pin-custom=\"true\"><i class=\"fab fa-pinterest\"><\/i><span class=\"ctext\"><span data-wpsrs=\"\" data-wpsrs-svcs=\"pinterest\">0<\/span><\/span><\/a><\/span>\n<span class=\"sr-print\"><a rel=\"nofollow\" href=\"https:\/\/www.printfriendly.com\/print?url=\" target=\"_blank\"  title=\"Print this article \"  style=\"color: #ffffff\" ><i class=\"fa fa-print\"><\/i><\/a><\/span>\n<span class=\"sr-pdf\"><a rel=\"nofollow\" href=\"https:\/\/www.printfriendly.com\/print?url=\" target=\"_blank\"  title=\"Convert to PDF\"  style=\"color: #ffffff\" ><i class=\"fa fa-file-pdf\"><\/i><\/a><\/span><\/div><\/div><\/div>","protected":false},"excerpt":{"rendered":"<p>These select boxes all contain the exact same security question. However, each question can only be selected once &mdash; we&#8217;re using jQuery to remove selected questions from all the other dropdowns. [&#8230;]<\/p>\n<p><a class=\"more-link article\" href=\"https:\/\/cssdeck.com\/blog\/intelligent-select-box-filtering\/\" title=\"Click to read 'Intelligent Select Box Filtering'\">Read Article<\/a><\/p>\n","protected":false},"author":18,"featured_media":613,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[165,184],"tags":[62,270,55,291,293],"_links":{"self":[{"href":"https:\/\/cssdeck.com\/blog\/wp-json\/wp\/v2\/posts\/611"}],"collection":[{"href":"https:\/\/cssdeck.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cssdeck.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cssdeck.com\/blog\/wp-json\/wp\/v2\/users\/18"}],"replies":[{"embeddable":true,"href":"https:\/\/cssdeck.com\/blog\/wp-json\/wp\/v2\/comments?post=611"}],"version-history":[{"count":0,"href":"https:\/\/cssdeck.com\/blog\/wp-json\/wp\/v2\/posts\/611\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cssdeck.com\/blog\/wp-json\/wp\/v2\/media\/613"}],"wp:attachment":[{"href":"https:\/\/cssdeck.com\/blog\/wp-json\/wp\/v2\/media?parent=611"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cssdeck.com\/blog\/wp-json\/wp\/v2\/categories?post=611"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cssdeck.com\/blog\/wp-json\/wp\/v2\/tags?post=611"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}