Replace an HTML select box with onchange without jquery


Sometimes you will need to replace an HTML <select> box by a custom one in order to apply special styles. Life might not allow you to use beautiful frameworks such as Jquery or Dojo, so you will have to manage without them, just with your own two hands…

A first solution I found for this is here : http://v2.easy-designs.net/articles/replaceSelect/

But this solution doesn’t take care of “onchange” element on the select. So here is my solution :

/* Replace a <select> by a <select> customable */
 function selectReplacement(obj) {
	 // append a class to the select
     //obj.setAttribute('style','display: none;');
     //dojo.style(obj.id, 'display', 'none');
     obj.className = 'replaced';
     if (navigator.appName == 'Microsoft Internet Explorer')
     {
    	 var sUL = "<ul class=\"selectReplacement\" onchange=\""+obj.onchange+"\"  id=\""+obj.getAttribute('id')+"Adapted\" >";
    	 sToReturn = '';
     }
     else {
         // create list for styling
         var ul = document.createElement('ul');
         ul.className = 'selectReplacement';
         ul.setAttribute('onchange', obj.onchange);
         ul.setAttribute('id', obj.getAttribute('id')+'Adapted');

     }

     var opts = obj.options;
     for (var i=0; i<opts.length; i++) {
       var selectedOpt;
       if (opts[i].selected) {
         selectedOpt = i;
         break;
       } else {
         selectedOpt = 0;
       }
     }
     for (var i=0; i<opts.length; i++) {

    	 if (navigator.appName == 'Microsoft Internet Explorer')
    	 {
    	   var sFuncOnClick = " selectMe(this);";
    	   var sClassName = '';

	       if (i == selectedOpt) {
	    	 var sClassName = 'selected';
	    	 //sFuncOnClick += " dojo.addClass('"+obj.getAttribute('id')+"Adapted','selectOpen');" ;
	    	 sFuncOnClick += "this.parentNode.className += ' selectOpen'";
 	     }

	    	 var sFuncOnMouseOver = "this.className += ' hover';";
	    	 var  sFuncOnMouseOut = "this.className = this.className.replace(new RegExp(' hover\\\\b'), ''); ";

	       var sLI = "<li value=\""+opts[i].value+
		   "\" class=\""+sClassName+
		   "\"  onclick=\""+sFuncOnClick+
		   "\"  onmouseover=\""+sFuncOnMouseOver+
		   "\"  onmouseout=\""+sFuncOnMouseOut+
		   "\" > "+opts[i].text+" </li> ";
	       console.log(sLI);
	       sToReturn += sLI;
    	   }else{
    	       var li = document.createElement('li');
    	       var txt = document.createTextNode(opts[i].text);
    	       li.setAttribute('value', opts[i].value);
    	       li.appendChild(txt);
    	       li.selIndex = opts[i].index;
    	       li.selectID = obj.id;

    	       li.onclick = function() {
    	           eval("test = "+this.parentNode.getAttribute('onchange'));
    	           test(this.getAttribute('value'));
    	         selectMe(this);
    	       };

    	       if (i == selectedOpt) {
    	         li.className = 'selected';
    	         li.onclick = function() {
    	           this.parentNode.className += ' selectOpen';
    	           this.onclick = function() {
    	             selectMe(this);
    	           };
    	         };
    	         li.onmouseover = function() {
    	           this.className += ' hover';
    	           };
    	         li.onmouseout = function() {
    	           this.className =
    	             this.className.replace(new RegExp(" hover\\b"), '');
    	       };

    	     }
  	         ul.appendChild(li);

    	   }
     }
     if (navigator.appName == 'Microsoft Internet Explorer')
     {
    	 if(document.getElementById(obj.getAttribute('id')+'Adapted') != null) {
        	 document.getElementById(obj.getAttribute('id')+'Adapted').innerHTML = sToReturn;
    	 } else {
    		 sToReturn = sUL + sToReturn +'</ul>';
        	 document.getElementById(obj.parentNode.id).innerHTML = sToReturn;
    	 }

     } else {
	     // add the input and the ul
	     if(document.getElementById(obj.getAttribute('id')+'Adapted')!=null){
	         obj.parentNode.removeChild(document.getElementById(obj.getAttribute('id')+'Adapted'));
	         obj.parentNode.appendChild(ul);
	     } else {
	         obj.parentNode.appendChild(ul);
	     }
     }

   }
   function selectMe(obj) {
     var lis = obj.parentNode.getElementsByTagName('li');
     for (var i=0; i<lis.length; i++) {
       if (lis[i] != obj) { // not the selected list item
         lis[i].className='';
         lis[i].onclick = function() {
           selectMe(this);
         }
      } else {
    	  if(obj.className!='selected hover') {
	         if (navigator.appName == 'Microsoft Internet Explorer')
	         {
	        	 sFunction = obj.parentNode.onchange.toString();
			    testContainer = sFunction.replace(new RegExp(" anonymous\\b"), ' testMe');
			    eval(testContainer);
			    if(typeof(testMe)=='function')
			    testMe(obj.getAttribute('value'));
	         }
    	  }

         obj.className='selected';
         obj.parentNode.className =
           obj.parentNode.className.replace(new RegExp(" selectOpen\\b"), '');
         obj.onclick = function() {
           obj.parentNode.className += ' selectOpen';

           this.onclick = function() {
        	   selectMe(this);

           }
         }
       }
     }
   }
   function setForm() {
     var s = document.getElementsByTagName('select');
     for (var i=0; i<s.length; i++) {
       selectReplacement(s[i]);
     }
   }

So in the end, you include this javascript in your page, and just call setForm() every time you want!

Works on Chrome/Chromium, FF, Opera and IE.

Fab
Latest posts by Fab (see all)

About Fab

Solutions Architect, I build great workflows for the news and media production industries. I play with data too.

Leave a comment

Your email address will not be published. Required fields are marked *