Advanced radio button grouping with jQuery
I was asked to do something rather interesting with some radio button inputs the other day. I haven’t come across this particular problem before and google didn’t return anything helpful, so I decided to share what I came up with.
First, the scenario
We have a standard form with 4 radio button groups. Each group has 4 radio buttons labeled from “1” to “4”. Now, when the user selects “option 1” in “group 1”, all the remaining “option 1” items need to be disabled. To see an example in action, you can view the demo here.
The problem
When I first started, I thought that it’s simply a matter of giving each “option” (regardless of group) a common class name – then just disabling all other options with the same class name. That works, to a point, but what if the user changes his mind and selects another option ? Now I had to find all previously disabled options, re-enable them and start all over again.
The solution
Essentially what I came up with was a basic nested loop to handle setting and unsetting the relevant “disabled” attributes. To achieve this, first we assign all “option 1” a class of “number1”, “option 2” a class of “number2” and so on.
Next, we run a basic for loop, and go through each “number” class (i.e. number1 to number4). For each class, we call a function. Inside this function is another loop – this time iterating over each radio button assigned the current class name. Using this loop, we remove any “disabled” attributes which may have been assigned previously. We also find out which item in that group is currently selected (if any) – this is so we can run a second loop to disable all those options not currently selected. Confused ? Now might be a good time to go through the code
The code
$(function(){ // fire our code when a radio button has been selected $("input[type=radio]").change(function(){ var name = $(this).attr("name"); // get the current button's group name $("input[name="+name+"]").removeAttr("selected"); // first we deselect "all" radio buttons within the same group $(this).attr("selected","selected"); // make sure our currently "changed" button is selected for(i=1;i<=4;i++){ // go through the 4 radio classes processRadio(".radio"+i); } }); /** Loops through each item with same "class" name and disables/enables where appropriate **/ function processRadio(class){ var empty; var id = ""; var buttons = $(class); // read all buttons with the specified class name into a jQuery object buttons.each(function(){ // loop through each item var me = $(this); var isSelected = me.attr("selected"); // bool value, based on whether the "selected" attribute is present or not me.removeAttr("disabled"); // clear the disabled attribute if present me.siblings("label").removeClass("disabled"); // same with the associated label element if (isSelected != empty && isSelected != ""){ id = $(this).attr("id"); // set our tmp id var to our currently selected item } }); // make sure we have an id, otherwise we'll get an error if (id != empty && id != ""){ buttons.each(function(){ // loop through each radio button once again if ($(this).attr("id") != id){ // set the disabled attributes if id attribute doesn't match our tmp id var $(this).attr("disabled", "disabled").siblings("label").addClass("disabled"); } }); } } });
I’ve commented as best I could, which hopefully makes more sense than my rambling above. Once again, there is a working demo available for you to play with. Be sure to have a look at the markup as well, might clear up a few questions.
I strongly suspect that there’s a more efficient method for achieving the same result – so if you have a better suggestion, tweak or link please let me know – I’d greatly appreciate it.
6 jQuery snippets you can use to manipulate select inputs
When it comes to manipulating the DOM, fewer elements are more tiresome than the good old select input. Fortunately for us, jQuery makes what was once a headache, a walk in the park.
Listed below are 6 snippets which should make manipulating those selects more pleasant than say, pulling your own teeth.
1. Getting the value of a selected option.
$('#selectList').val();
This couldn’t be simpler. Remember how before jQuery, you had to use selectedIndex and all those lovely javascript methods. I do, and I don’t miss it one bit.
2. Getting the text of a selected option.
$('#selectList :selected').text();
Similar in concept to the first snippet with one difference. Where the first example gives you the “value” of the selected option, this example gives you the actual text contained inside the option tag.
3. Getting the text/value of multiple selected options.
var foo = []; $('#multiple :selected').each(function(i, selected){ foo[i] = $(selected).text(); }); // to get the selected values, just use .val() - this returns a string or array foo = $('#multiple :selected').val();
Once again, the same concept as the first two examples, except we’re now using jQuery’s “each()” method to loop through all selected options in a multiple select list. Each value or text value is read into an array for later use.
4. Using selected options in conditional statements
switch ($('#selectList :selected').text()) { case 'First Option': //do something break; case 'Something Else': // do something else break; }
Much like example 2, we’re getting the text() value of a selected option, only this time we’re going to use it inside a switch statement.
5. Removing an option.
$("#selectList option[value='2']").remove();
Using an attribute filter, we can find and therefore manipulate specific options within a select list. In this example we’re telling jQuery to find the option with value=”2″ and then remove it from the select list. We can similarly add options to a select list as we’ll see in example 6.
6. Moving options from list A to list B.
$().ready(function() { $('#add').click(function() { return !$('#select1 option:selected').appendTo('#select2'); }); $('#remove').click(function() { return !$('#select2 option:selected').appendTo('#select1'); }); });
Originally posted by Jeremy Martin, here we have 2 select lists and 2 buttons. If you click the “add” button, we remove the selected option from select1 and add that same option to select2. The “remove” button just does things the opposite way around. Thanks to jQuery’s chaining capabilities, what was once a rather tricky undertaking with JS can now be done in 6 lines of code.
And there you go. That wasn’t so bad now was it ? If you have any other handy snippets, or you’ve found an easier way to do something already covered here, why not leave a comment and share the love!
Update:
Incidentally, a few hours after first publishing this post I came across the following “select element cheat sheet”. Technically speaking, it may be a little big to be called a cheat sheet, but the author has given a very thorough and practical guide which I’m definitely going to be making use of.
Jquery UI Layout Manager Plugin
While working on my new framework the other day I came across this excellent Jquery Plugin : UI.Layout – The Ultimate Page Layout Manager.
What it does with minimal markup and some well written javascript is transform your html page into a professional pane based layout. Like most jQuery plugins, it’s incredibly simple to implement and through the use of CSS and a large number of options is highly customizable.
All in all, a very well rounded and executed use of the jQuery library. Kudos to Fabrizio.
Javascript / Jquery Bookmark script
Ever needed to add a button or link to your site which allows the user to save your site to their bookmarks/favorites ?
Here’s just the script for you. Using jquery, it works in Firefox 2+(tested), IE 6 (not tested), IE7(tested) and Opera 7+ (not tested). Unfortunately not all browsers support the action, so a generic “alert” has been added to inform the user.
You can download the full script here and follow along if you’d like a further explanation of the code involved. A demo can be viewed here.
bookmark.js
The script itself is really very basic. Firstly what needs to happen is on page load, the script checks to see if the user is browsing the site with Opera. If so, we set the rel attribute of all our bookmark anchor tags (class=”jqbookmark”) to “sidebar” – this is a standard Opera technique for creating this type of link.
Next we add an event listener which will execute whenever an anchor tag of class “jqbookmark” is clicked. Simply put, it checks to see which browser is being used and executes the necessary code.
The nice thing here though is that you can set the script to bookmark any url with any title by specifying the href and title attributes respectively.
$(document).ready(function(){ // add a "rel" attrib if Opera 7+ if(window.opera) { if ($("a.jqbookmark").attr("rel") != ""){ // don't overwrite the rel attrib if already set $("a.jqbookmark").attr("rel","sidebar"); } } $("a.jqbookmark").click(function(event){ event.preventDefault(); // prevent the anchor tag from sending the user off to the link var url = this.href; var title = this.title; if (window.sidebar) { // Mozilla Firefox Bookmark window.sidebar.addPanel(title, url,""); } else if( window.external ) { // IE Favorite window.external.AddFavorite( url, title); } else if(window.opera) { // Opera 7+ return false; // do nothing - the rel="sidebar" should do the trick } else { // for Safari, Konq etc - browsers who do not support bookmarking scripts (that i could find anyway) alert('Unfortunately, this browser does not support the requested action,' + ' please bookmark this page manually.'); } }); });
Demo.html
The html is straightforward. We include our two scripts (jquery and jqbookmark) and we add our links to the page. As mentioned above – the links need to have a class attribute with the value of “jqbookmark”, all other links will be ignored by the script.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <!-- include our jquery scripts --> <script src="js/jquery-1.2.6.min.js" type="text/javascript"></script> <script src="js/jqbookmark.js" type="text/javascript"></script> </head> <body> <div> <ul> <li><a href="http://www.google.com" title="Google.com" class="jqbookmark">Google bookmark</a></li> <li><a href="http://www.yahoo.com" title="Yahoo search engine" class="jqbookmark">Yahoo bookmark</a></li> <li><a href="https://calisza.wordpress.com" title="A wonderful Blog" class="jqbookmark">Blog bookmark</a></li> <li><a href="http://www.microsoft.com" title="Microsoft">Will not be bookmarked</a></ul> </div> </body> </html>
I’d love to know if this functionality could be expanded to include Safari, but so far my good friend google has come up with nothing. At the very least, I hope that someone can find this script useful.