How to Create Unique Block-Style Radio Inputs With jQuery

by on 11th November 2013 with No Comments

tutorial screenshot digg block radio input links howto jquery

Input buttons are used in web forms where a user needs to select one option from a larger collection. This often happens with unique values like newsletter subscriptions, profile settings, and submission categories. I have always liked the old-school Digg-style input buttons where you click a link to choose your story category.

In this tutorial I want to demonstrate how we can build a similar interface using CSS3 and jQuery. All of the input radio buttons are still present within the form itself, but they are hidden on the page. Instead we update the selected choice using JavaScript and even have the possibility to display this value in HTML (or return it to a backend script). Check out my sample demo to get an idea for what we are building.

Live DemoDownload Source Code

Building the Webpage

First we need to download a local copy of jQuery and include a link to an external CSS document named styles.css. The JS code isn’t too complicated, but you could benefit by moving them into a separate .js file. It depends if your website requires additional scripting which would shave off time when rendering the page.

<!doctype html>
<html lang="en-US">
<head>
  <meta charset="utf-8">
  <meta http-equiv="Content-Type" content="text/html">
  <title>jQuery Block Radio Inputs - Design Shack Demo</title>
  <meta name="author" content="Jake Rocheleau">
  <link rel="shortcut icon" href="http://designshack.net/favicon.ico">
  <link rel="icon" href="http://designshack.net/favicon.ico">
  <link rel="stylesheet" type="text/css" media="all" href="css/styles.css">
  <script type="text/javascript" src="js/jquery-1.10.2.min.js"></script>
</head>

Now the inner page body contains a small number of important pieces. We have a span using the ID #radiovaltxt which is how I am displaying the selected input. Whenever a user clicks one of the page links, this span value gets updated with the currently-selected input value. Beneath this I’ve created a new form which doesn’t load anything – it is more of a placeholder to see how the HTML should look.

  <div id="radioval">Current value: <span id="radiovaltxt"></span></div>
  
  <form id="fakeform" name="fakeform" method="post" action="#">
    <div id="radiobtns">
      <div class="row">
        <ul class="clearfix">
          <li class="parent">World News:</li>
          <li><a href="#" id="world">World News</a></li>
          <li><a href="#" id="politics">US Politics</a></li>
          <li><a href="#" id="business">Business</a></li>
          <li><a href="#" id="finance">Finance</a></li>
          <li><a href="#" id="breaking">Breaking</a></li>
        </ul>
      </div>

You’ll find the div #radiobtns contains a number of div rows which further contain unordered lists of elements. Each row is based on a single category topic and the user can select one of the options to mark the selected category. I only copied over one row of links but they are all structured very similar.

One important piece to understand is that the anchor link ID matches up to a corresponding input button value. This is how we can determine which link has been clicked and how this matches up with the radio selection. You will find these actual inputs located within a div #fullradios at the bottom of the form.

<div id="fullradios">
  <input type="radio" name="category" id="world-rdio" value="world">
  <input type="radio" name="category" id="politics-rdio" value="politics">
  <input type="radio" name="category" id="business-rdio" value="business">
  <input type="radio" name="category" id="finance-rdio" value="finance">
  <input type="radio" name="category" id="breaking-rdio" value="breaking">
  <input type="radio" name="category" id="technews-rdio" value="technews">
  <input type="radio" name="category" id="hardware-rdio" value="hardware">
  <input type="radio" name="category" id="software-rdio" value="software">
  <input type="radio" name="category" id="mobile-rdio" value="mobile">
  <input type="radio" name="category" id="webdesign-rdio" value="webdesign">
  <input type="radio" name="category" id="programming-rdio" value="programming">
  <input type="radio" name="category" id="opensource-rdio" value="opensource">
  <input type="radio" name="category" id="nintendo-rdio" value="nintendo">
  <input type="radio" name="category" id="playstation-rdio" value="playstation">
  <input type="radio" name="category" id="xbox-rdio" value="xbox">
  <input type="radio" name="category" id="pcgames-rdio" value="pcgames">
  <input type="radio" name="category" id="indie-rdio" value="indie">
  <input type="radio" name="category" id="celebrities-rdio" value="celebrities">
  <input type="radio" name="category" id="music-rdio" value="music">
  <input type="radio" name="category" id="comedy-rdio" value="comedy">
  <input type="radio" name="category" id="movies-rdio" value="movies">
  <input type="radio" name="category" id="webseries-rdio" value="webseries">
  <input type="radio" name="category" id="fashion-rdio" value="fashion">
  <input type="radio" name="category" id="travel-rdio" value="travel">
  <input type="radio" name="category" id="health-rdio" value="health">
  <input type="radio" name="category" id="education-rdio" value="education">
  <input type="radio" name="category" id="arts-rdio" value="arts">
  <input type="radio" name="category" id="homedecor-rdio" value="homedecor">
</div>

I have them hidden by default and the whole purpose is to never actually show them on the page. If users can interact with our own custom interface, then there is never any need for them to manipulate the radio inputs. Granted we could instead build the inputs linked to a label which doesn’t require any jQuery. But the effect is also more difficult to pull off and requires CSS3-compliant web browsers.

Styling the Cat Links

My default stylesheet includes all the typical resets and page structure as you would expect. The input fields are hidden using display: none by targeting the parent div element. Also the span text is designed to appear naturally centered towards the top of the page. You probably won’t use this on a live website but instead pass the value into the form using a hidden field.

/** radio buttons **/
#radiobtns { /* nothing special here */ }

#radiobtns .row { 
  display: block;
  margin-bottom: 8px;
  height: 28px;
}

#radiobtns .row ul { }

#radiobtns .row ul li {
  display: block;
  float: left;
  font-size: 1.2em;
  font-weight: bold;
  line-height: 28px;
}
#radiobtns .row ul li.parent {
  width: 110px;
}

#radiobtns .row ul li a {
  display: block;
  float: left;
  padding: 0 6px;
  margin-right: 6px;
  border: 1px solid #fff;
  -webkit-border-radius: 4px;
  -moz-border-radius: 45px;
  border-radius: 4px;
}
#radiobtns .row ul li a:hover {
  text-decoration: none;
  background: #cae0c7;
  color: #4a7145;
  border-color: #cae0c7;
}

#radiobtns .row ul li a.sel {
  background: #b5cfb1;
  color: #3a5f35;
  border: 1px solid #82a57e; 
}

#fullradios { 
  display: none;
}

Each row has a single unordered list and the very first item is given a class of .parent. This is how I’ve organized the list of categories. The parent item itself is not a link designated towards any input. You could change this in your own design, but it makes more sense to use a type of parent category label to define the choices. This parent item is given a fixed width of 110px to provide more space between the links.

I also wrote a notable class of .sel which is applied onto the selected link item. Once a user clicks one of the link values we need them to know it has been selected and confirmed. This selected class will be removed and re-applied onto new links as the user switches between categories.

Input Selection with jQuery

To manually select and deselect radio buttons you have to delve into jQuery a little bit. There are many popular questions on Stack Overflow which address this idea, and the techniques have changed over the various iterations of jQuery’s library. This script is located at the bottom of the index.html page and I’ll break it down into segments for easier comprehension.

  $('#radiobtns .row ul li a').on('click', function(e){
    e.preventDefault();
    var catid = '#'+$(this).attr('id') + "-rdio";
    
    var checkedinput = $("input[name='category']:checked").val();

Whenever a user clicks one of these links we immediately use event.preventDefault() passing in the click event variable. This stops the HREF value from loading so we don’t get the page jump associated with hashed links. The variable catid is a string formed in the syntax of a jQuery selector. It takes the link ID and re-forms it into the ID value of the corresponding radio input. The other variable checkedinput gets the value of the currently selected radio – if nothing is selected we get a return value of undefined.

    if(checkedinput == undefined) {
      // if no input is defined then we set the button clicked first
      $(catid).prop('checked', true);
    } else {
      // otherwise unset everything and then set the clicked button
      $("input[name='category']").prop('checked', false);
      $(catid).prop('checked', true);
    }
    
    var newval = $("input[name='category']:checked").val();
    if($(this).attr('id') == newval) {
      $('#radiovaltxt').html(newval);
    }

So now we can break more into the logical code by first checking if there is nothing already selected. In this case we use jQuery’s .prop() method for setting the checked property. Otherwise we target every single radio using input[name='category'] and remove the checked option so it reverts back to no selection. Then we update based on the most recently clicked radio link.

Afterwards I create another variable newval which again checks the currently-selected radio value. If this value matches the ID of the link then we know it has been successfully checked and we display the new value in HTML. This step probably won’t be useful on any live production website – but it’s nice for this demo to see how everything works behind-the-scenes.

    if($(this).hasClass('sel')) {
      // if already selected then we do nothing
    } else {
      $('#radiobtns .row ul li a').removeClass('sel');
      $(this).addClass('sel');
    }
  });

This final chunk of code deals with updating the currently selected link. If the current link already has a .sel class then it’s already been selected and we do nothing. Otherwise it’s easier targeting each link inside #radiobtns and removing the class, to then update our current link using $(this).addClass(‘sel’).

Remember $(this) is merely a placeholder for any currently active jQuery selector, and in this case we’re talking about the click event which is performed on any of the category links.

Live DemoDownload Source Code

I can only imagine the plethora of solutions for why developers would use radio inputs. Modern web techniques offer so much in the way of user interface design, and this is an interesting way to customise a radio button experience into something completely unique.

I hope this tutorial may provide some ideas to web developers working with large forms and input fields. Also you can download a copy of my tutorial source code to see exactly how this works on your own computer.

Comments & Discussion

Subscribe
Membership
About the Author