How To Make a Custom HTML5 Select Menu with Selectize.js

by Jake Rocheleau

on August 22, 2013

in Tutorials

Detailed and customized input fields have been a great focus of modern web development. The jQuery library along with similar open source projects have provided a framework to build with. It has lead to numerous advances within the field of user interface design. Especially for customizing the typical “default” components in form elements.

In this tutorial I want to introduce the Selectize plugin for jQuery. It allows developers to greatly alter the presentation of input fields related to select menus and tag-formatted text fields. This can provide a tremendous benefit on projects where you need a cleaner, updated interface. It is a fairly straightforward process and shouldn’t take more than 60 minutes to create. Take a peek at my live demo to see what we are making.

jquery selectize custom select menus html5 demo

Getting Started

First we need to download a copy of Selectize and keep the local CSS/JS files stored in the same location. You can download this archive from the Selectize.js Github repo which also includes a few sample demos. All we need is selectize.min.js and selectize.css. Copy these files into a new folder /js and /css, respectively.

<!doctype html>
<html lang="en-US">
<head>
  <meta charset="utf-8">
  <meta http-equiv="Content-Type" content="text/html">
  <title>Customized Input Select Menus - Demo</title>
  <meta name="author" content="Jake Rocheleau">
  <link rel="shortcut icon" href="http://designm.ag/favicon.ico">
  <link rel="icon" href="http://designm.ag/favicon.ico">
  <link rel="stylesheet" type="text/css" media="all" href="css/style.css">
  <link rel="stylesheet" type="text/css" media="all" href="css/selectize.css">
  <script type="text/javascript" src="js/jquery-1.10.2.min.js"></script>
  <script type="text/javascript" src="js/selectize.min.js"></script>
</head>

You should notice I downloaded a local copy of jQuery to store in the same /js folder. Also I created another stylesheet named style.css which helps to structure the website layout. Overall there are only 4 resource files and jQuery is the only dependency we need.

Now Selectize.js offers a multitude of various setups to choose from. The default configuration requires no parameters at all. But this plugin is heavily documented with all of the parameter options you could include, and what they do. I want to get us started with two basic elements inside a sample HTML form – but remember this link when you need to go back and customize some functionality.

Inner Body Content

The form elements are pretty standard and I am using jQuery e.preventDefault() to stop the form submission. Each .formrow class is used to split up the content into horizontal sections. We only need to apply selectize() onto the select menu and the tags menu.

  <form id="testform" method="post" action="#">
    <div class="formrow">
      <label for="name">Name:</label>
      <input type="text" id="name" class="basictxt" placeholder="Your name...">
    </div>
    
    <div class="formrow">
      <label for="email">Email:</label>
      <input type="text" id="email" class="basictxt" placeholder="Your email...">
    </div>
    
    <div class="formrow">
      <label for="subject">Subject:</label>
      <select id="subject">
        <option value="1">General Inquiry</option>
        <option value="2">Advertising</option>
        <option value="3">Press</option>
        <option value="5">Account Problems</option>
        <option value="4">Content Submission</option>
      </select>
    </div>
    
    <div class="formrow">
      <label for="tags">Tags:</label>
      <input type="text" id="tags" value="website,graphics,question">
    </div>
    
    <div class="formrow">
      <label for="message">Message:</label>
      <textarea class="basictxtarea" id="message"></textarea>
      <input type="submit" class="large button" value="Send Message">
    </div>
  </form>

After this initial starting block you’ll notice that I have included both the dropdown and the text-based tags input. Selectize handles this interface beautifully and it is worth the effort to get things setup if you need this functionality in your script. The ID #subject and #tags will be used for targeting the element itself.

Internal option values from the select menu can be determined using simple jQuery. This means you can pass the same values into your form through Ajax or regular user submission. But even using the tag field we can still get return values naturally after the form is submitted. My example here provides the default value=”website,graphics,question” which can be updated as the user appends more tags onto the list.

CSS Styling

The default Selectize styles are very important and should always be included within the page header. These will create the tag styles and other various input select features. If you wish to customize them, check each item’s scope within the CSS file and overwrite the properties in your own stylesheet.

/* form styles */
.basictxt {
  display: block;
  padding: 7px 8px;
  width: 550px;
  color: #555;
  font-size: 1.5em;
  border: 1px solid #ccc;
  font-family: Helvetica, Arial, sans-serif;
}

.basictxtarea {
  display: block;
  padding: 8px 10px;
  width: 600px;
  height: 115px;
  color: #555;
  font-size: 1.6em;
  border: 1px solid #ccc;
  margin-bottom: 14px;
  font-family: Helvetica, Arial, sans-serif;
}

.selectize-control { width: 60%; }

Many of these properties are not useful aside from resetting basic HTML forms. The .selectize-control class is applied onto every element running this jQuery function. Normally the input fields are using display: inline and the width can appear too short for the inner text. I am using 60% because it fits nicely into the layout, however you should customize this value to whatever suits your design.

.button::-moz-focus-inner {
  border: 0;
  padding: 0;
}

.button {
  display: inline-block;
  *display: inline;
  zoom: 1;
  padding: 6px 20px;
  margin: 0;
  cursor: pointer;
  border: 1px solid #bbb;
  overflow: visible;
  font: bold 13px arial, helvetica, sans-serif;
  text-decoration: none;
  white-space: nowrap;
  color: #555;
  background-color: #ddd;
  background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(255,255,255,1)), to(rgba(255,255,255,0)));
  background-image: -webkit-linear-gradient(top, rgba(255,255,255,1), rgba(255,255,255,0));
  background-image: -moz-linear-gradient(top, rgba(255,255,255,1), rgba(255,255,255,0));
  background-image: -ms-linear-gradient(top, rgba(255,255,255,1), rgba(255,255,255,0));
  background-image: -o-linear-gradient(top, rgba(255,255,255,1), rgba(255,255,255,0));
  background-image: linear-gradient(top, rgba(255,255,255,1), rgba(255,255,255,0));
  -webkit-transition: background-color .2s ease-out;
  -moz-transition: background-color .2s ease-out;
  -ms-transition: background-color .2s ease-out;
  -o-transition: background-color .2s ease-out;
  transition: background-color .2s ease-out;
  background-clip: padding-box; /* Fix bleeding */
  -moz-border-radius: 3px;
  -webkit-border-radius: 3px;
  border-radius: 3px;
  -moz-box-shadow: 0 1px 0 rgba(0, 0, 0, .3), 0 2px 2px -1px rgba(0, 0, 0, .5), 0 1px 0 rgba(255, 255, 255, .3) inset;
  -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, .3), 0 2px 2px -1px rgba(0, 0, 0, .5), 0 1px 0 rgba(255, 255, 255, .3) inset;
  box-shadow: 0 1px 0 rgba(0, 0, 0, .3), 0 2px 2px -1px rgba(0, 0, 0, .5), 0 1px 0 rgba(255, 255, 255, .3) inset;
  text-shadow: 0 1px 0 rgba(255,255,255, .9);
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  -khtml-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}

.button:hover {
  background-color: #eee;
  color: #555;
}

.button:active {
  background: #e9e9e9;
  position: relative;
  top: 1px;
  text-shadow: none;
  -moz-box-shadow: 0 1px 1px rgba(0, 0, 0, .3) inset;
  -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, .3) inset;
  box-shadow: 0 1px 1px rgba(0, 0, 0, .3) inset;
}

.button[disabled], .button[disabled]:hover, .button[disabled]:active {
  border-color: #eaeaea;
  background: #fafafa;
  cursor: default;
  position: static;
  color: #999;
  /* Usually, !important should be avoided but here it's really needed :) */
  -moz-box-shadow: none !important;
  -webkit-box-shadow: none !important;
  box-shadow: none !important;
  text-shadow: none !important;
}

.button.large {
  padding: 12px 30px;
  text-transform: uppercase;
}

.button.large:active {
  top: 2px;
}

If you wish to duplicate the submit button style I copied over the important properties above. This original interface scheme comes from a design on Codepen with many other CSS3 effects. The button design is fantastic and it should blend nicely with any layout. Other styles are just common CSS resets and so we should move on to the final JS syntax.

Selectize.js with jQuery

As usual we need to create a script tag at the bottom of the page, before the closing </body> tag. This will contain the JS code to prevent form submission, as well as the selectize functions. If you need the form to work properly then remove this $(‘#testform’).submit() function entirely.

$(function() {
  $('#testform').submit(function(e){
    e.preventDefault();
  });
  
  $('#subject').selectize({create: true});
  $('#tags').selectize({    
    delimiter: ',',
    persist: true,
    create: function(input) {
      return {
        value: input,
        text: input
      }
    }
  });
});

The first method is targeting the select dropdown menu. It runs selectize({create: true}) which passes the create parameter. When true, this allows users to actually type in their own value for the select menu. It is very unique and may be helpful in some specific instances.

Looking over at the tags function I am passing quite a few more options. When creating a new tag we need to call a function which can return these values to be added back to the input field. Since this is a text field it will behave differently than a select menu. The delimiter string is what separates all these tags when passed into the form as one long value. Also persist will force all user-added values to stay in the menu as a potential choice until the page is refreshed.

There are so many other parameters you can include which provide a heck of a lot more functionality. Many of these options are also callbacks, which means you can trigger a new function once a certain event has happened(like the user clicks an option). And if you really want to get technical look through their plugin documentation for creating your own extended effects.

jquery selectize custom select menus html5 demo

Final Thoughts

Referencing jQuery plugins for your website design can be a huge time saver. I have been thoroughly impressed with many newer plugins that have been released over 2012 and 2013. There is never a shortage of new ideas when developers are willing to build these on top of existing open source platforms. I do hope this tutorial will prove useful in future web projects. Additionally feel free to download a copy of my source codes for easy-access to the sample project.

Powered by Shutterstock

About Jake Rocheleau

Jake is a digital researcher and writer on many popular design magazines. He frequently writes on topics including web design, user experience, mobile apps, and project management. You can find him all throughout Google and tweeting @jakerocheleau. Connect with Jake on google+