Tag Archives: Javascript

Internet Explorer Browser Detect Script

24 Nov 2012

Someone asked a question about detecting different versions of IE the other day – this is my take at it – it is not a universal browser detect script rather it only cares about MSIE.

The original question had to do with dealing with old versions of MSIE which didn’t render some website properly and needing to direct users to some other web page as a result – which I took to mean – “how do I detect the browser type and perform some desired action?”

The navigator object’s userAgent property contains all the information needed to determine the type of browser. A Google search will reveal many scripts to do browser detection – but I’ll provide a quick script of my own written specifically for this question.

In addition to the userAgent you may also discover some details about the user’s client via two additional navigator properties which are navigator.appName and navigator.appVersion. You will find the appVersion property to be less then ideal (for example, MSIE9 will report as version 5) and the appName will be the full name of the browser – which is ok. For me I find it more convenient to deal with the userAgent property since everything that I’ll be looking for is contained in the resulting string.

First, add a script tag to your page and while we are at it lets assign the userAgent’s value to a variable so that we can easily reference it:

...
<script type="text/javascript">
   var ua = navigator.userAgent;
</script>
...

Next, lets come up with a simple regular expression for detecting MSIE.

...
<script type="text/javascript">
   var ua = navigator.userAgent;
   var msieTest = /MSIE/gi;
</script>
...

Regular expressions are pretty powerful tools for finding patterns in strings. The navigator.userAgent value is a string and the regular expression (/MSIE/gi) will let us discover if “MSIE” is contained within it. If it is, then we know that we’re dealing with Internet Explorer.

To use the regular expression we will use the regular expression “test” method. See below:

...
<script type="text/javascript">
   var ua = navigator.userAgent;
   var msieTest = /MSIE/gi;
   var isMSIE = msieTest.test(ua);
</script>
...

Looking at the above, you can see that I’ve created a variable called “isMSIE” and set it equal to the result of the “test”. The “test” method will return true if “MSIE” is found and “false” otherwise.

Knowing that, we just need to compare against the value of “isMSIE” and then take whatever action we deem necessary as seen below.

...
<script type="text/javascript">
   var ua = navigator.userAgent;
   var msieTest = /MSIE/gi;
   var isMSIE = msieTest.test(ua);
   if (isMSIE){
     alert('You are using Internet Explorer');
  } else {
    alert('You are not using Internet Explorer');
  }
</script>
...

We now have a pretty basic yet effective browser sniffer that is looking specifically for Internet Explorer. It would be more useful though to know the browser version as well. For that, lets use another regular expression to find where the version number is in the userAgent string. We know that the version comes right after the “MSIE” characters within the userAgent value so we write an expression that looks for it:

...
/MSIE \d.\d/gi
...

The regular expression “match” method will return to us an array of all matching values based on the above expression – in this case we know that there will always only be a single answer so we will look at the first index of the array to retrieve it. The next step will be to extract the numerical value – see the following:

...
var msieVersionStr = ua.match(/MSIE \d.\d/gi);
var msieVersionNum = parseFloat(msieVersionStr[0].substr(5,msieVersionStr[0].length));
...

“msieVersionNum” will hold the browser version for Internet Explorer. As it will **only** work for Internet Explorer we need to put it inside of the if statement that checks for the existence of Internet Explorer. That would look like this:

...
<script type="text/javascript">
  var ua = navigator.userAgent;
  console.log(ua);
   var ua = navigator.userAgent;
   var msieTest = /MSIE/gi;
   var isMSIE = msieTest.test(ua);
  if (isMSIE){
    var msieVersionStr = ua.match(/MSIE \d.\d/gi);
    var msieVersionNum = parseFloat(msieVersionStr[0].substr(5,msieVersionStr[0].length));
  } else {
    alert('You are not using Internet Explorer');
  }
</script>
...

Finally, to wrap this all up, we add some version checks in the form of additional “if” statements:

...
<script type="text/javascript">
  var ua = navigator.userAgent;
  console.log(ua);
   var ua = navigator.userAgent;
   var msieTest = /MSIE/gi;
   var isMSIE = msieTest.test(ua);
  if (isMSIE){
    var msieVersionStr = ua.match(/MSIE \d.\d/gi);
    var msieVersionNum = parseFloat(msieVersionStr[0].substr(5,msieVersionStr[0].length));
    if (msieVersionNum > 9){
       alert('You are using MSIE ' + msieVersionNum);
    } else if (msieVersionNum == 9){
       alert('You are using MSIE 9');
    } else if (msieVersionNum == 8){
       alert('You are using MSIE 8');
    } else if (msieVersionNum == 7){
       alert('You are using MSIE 7');
    } else if (msieVersionNum > 6){
       alert('You are using MSIE 6 or earlier');
    }
  } else {
    alert('You are not using Internet Explorer');
  }
</script>
...

And thats it, this script will check for Internet Explorer 6 and up.

Namespacing an existing JavaScript code base

23 Nov 2012

I read a question over on O’reilly’s website today that was posted way back in 2009 in the “Answers” section. The answer to the question IMO was not the best approach. The question was:

“I have to join a few home-made Javascript-libraries together. It’s so easy to use global variable-names, but how can I stay in my own namespace like “mycompany.strings”? “

The original reply was to do namespacing by writing a huge object literal. Going into the existing codebase and modifying code so as to lock up functions and variables within an object.

While doable, thats a heavy handed approach IMO. Seems to me that a javascript pattern called a “closure” is more appropriate. I went ahead and provided my thoughts to the 3-year old question figuring another approach wouldn’t hurt. Here’s the text of my response:

This post is a few years old, but I wanted to put forth another idea as to how to approach namespacing some existing code. It appears to me that the closure pattern would fit this need quite nicely. For example, see this typical bit of code, note the variable is in the global namespace as is the function:

...
var vehicle = {color:'red',type:'truck'}

function changeVehicleColor(str){
  vehicle.color = str;
}
...

With the closure pattern all that you would need to do is to wrap the above code within the closure construct, like so:

...
var myCompany = (function(){

  var vehicle = {color:'red',type:'truck'}

  function changeVehicleColor(str){
    vehicle.color = str;
  }

})();
...

Now the “vehicle” variable and the “changeVehicleColor” function are wrapped within the “myCompany” object. At this point they are private – they’re not accessible, so you have to expose a way of accessing them. You can do this with a return statement, see below:

...
var myCompany = (function(){

  var vehicle = {color:'red',type:'truck'}

  function changeVehicleColor(str){
    vehicle.color = str;
  }

  return {
    changeVehicleColor:changeVehicleColor
  }

})();
...

The “changeVehicleColor” method is now exposed for use while the “vehicle ” variable is still private. To change the vehicle color you would do the following:

...
myCompany.changeVehicleColor('yellow');
...

All done. The nice thing here is that you’re just wrapping the existing code within the closure construct. A lot easier than the original example, IMO, where you are creating an object literal and modifying the original code to do so. Not ideal for what the op claims are “a couple of libraries”. You can avoid that effort with a closure. The bonus is the notion of private and public bits of the existing code. The original sample, while it does work, leaves all variables open for manipulation outside of the namespace (see the “var1” example).

In addition, you can easily build upon the myCompany object. For example, if you have some utility methods, you could wrap them separately but within the same namespace like so – note that the “myCompany” namespace has already been created, so I am not using the var keyword (btw, this would also be true of the first answer):

...
myCompany.utils = (function(){
  // your code here
  return{
    // your methods, getters/setters here
  }
})();
...

Thus, you can break the library into different physical files if you like as long as the one that creates the namespace is the first file to load.

JQuery Mobile Checkboxes

31 Oct 2012

JQuery Mobile has some nice form element replacements that are more mobile device/touch-friendly than the way browsers currently present form elements. One of them is the visual replacement for a checkbox. To be clear the ugly checkbox is still there, its now layered underneath the JQM checkbox art.

The end results looks like this:

Click here to see a working example.

The docs IMO don’t quite tell you one critical thing – that certain tag attributes need to be identical in order for the framework to enhance the checkbox. If one of these is out of place you won’t get what you’re looking for.

Here’s how I implemented a checkbox today after trial and error:

...
  <style type="text/css">
    .checkboxWidth{
      width:53px;
    }
  </style>
...
  <fieldset data-role="controlgroup" class="checkboxWidth">
    <input type="checkbox" name="checkbox_value_0" id="checkbox_value_0" data-iconpos="notext" />
    <label for="checkbox_value_0" data="test"></label>
  </fieldset>
...

According to the docs the only thing to pay attention to is to ensure that the LABEL tag’s for attribute value is the same as the INPUT tag’s name value so that they are semantically linked together and displayed appropriately by the framework. There is one critical piece of information and that’s the INPUT tag’s id – it too must be the same value as the previous two attribute values. Omit that last bit and you don’t get any visual enhancement of the CHECKBOX element.

As far as getting the label removed all that is needed (as can be seen in the code sample above) is to add data-iconpos=”notext” to the input tag.

Lastly, I wanted to set the width so I added a class to the FIELDSET element and that was it, my check box was created and ready to go.

A handy tip is the use of the jQuery trigger method when inserting checkboxes into your document after it has loaded. Doing so ensures that you get the visual enhancement.

For example:

...
var newcbox = '<input type="checkbox" name="checkbox_value_0" id="checkbox_value_0" data-iconpos="notext" />';
    newcbox = '<label for="checkbox_value_0" data="test"></label>';

// add html to DOM and "trigger" jQuery visual enhancement
$(newcbox).appendTo('#contentWrapper').trigger('create');
...

Setting CSS Background Colors via Javascript – RGB triplet vs Hex

10 Oct 2012

We’ve all had to do it – change the color of text or visible html elements like Div backgrounds or borders, etc. One thing I’ve noticed is that when I request the background color of a Div I get the RGB triplet, not a hexadecimal value. Observe this example:

(Please use a modern browser, I’ve made no effort to make the examples work in old browsers)

<html><head><title></title>
<script language="javascript">
  function getColor(){
    document.getElementById('result').innerHTML = document.getElementById('dd').style.backgroundColor;
  }
</script>
</head>
<body>
<p><a href="javascript:getColor()">Click here to get the color of the box</a></p>
<p>The box color is: <span id="result"></span></p>
<div style="height:100px;width:100px;background-color:#185f8e;border:1px solid #ccc;" id="dd"></div>
</body>
</html>

 

Notice that the color obtained is not the hexadecimal value that you saw in the sample source provided above but the RGB equivalent even though its Hexadecimal to begin with.

Next, if I were to attempt to change the color by setting the css background-color value to an RGB value nothing will happen. See this example:

<html><head><title></title>
<script language="javascript">
function setColor(){
  document.getElementById('result').style.backgroundColor = 'rgb(122, 122, 122)';
}
</script>
</head>
<body>
<p><a href="javascript:setColor()">Click here to change the box color with an RGB value: rgb(122, 122, 122);</a></p>
<p>The box color is: <span id="result"></span></p>
<div style="height:100px;width:100px;background-color:#185f8e;border:1px solid #ccc;" id="dd"></div>
</body>
</html>

 

As you can see… nothing happens…. so in order to change the background color you must use a hexidecimal value.

If we get a hex value from an element it will be RGB so in order to make it useful elsewhere in our code we would need to convert the RGB back to hexadecimal. Below is a function I wrote that will do that for us.

...
function convertToHex(str){
  var raw = str.match(/(\d+)/g);
  var hexr = parseInt(raw[0]).toString(16);
  var hexg = parseInt(raw[1]).toString(16);
  var hexb = parseInt(raw[2]).toString(16);
      hexr = hexr.value == 1 ? '0' + hexr: hexr;
      hexg = hexg.length == 1 ? '0' + hexg: hexg;
      hexb = hexb.length == 1 ? '0' + hexb: hexb;
  var hex = '#' + hexr + hexg + hexb;
  return hex;
}
...

This function takes an RGB of the following format: rgb(x, x, x) where “x” is any number within the RGB number range. The short description of what is happening would be to say that hexadecimal is base 16, thus the toString(16) which gives us the hex equivalent of each individual RGB value.

The long description would to say that the basic usage of toString() is to convert a number to a string, but we can also pass an argument to the toString() method to tell it what base to convert the number to. A few different bases are available. If we wanted to convert a number to binary we would use toString(2) (pronounced to string base 2), to octal, we would use toString(8) and finally to convert to hexadecimal we use toString(16). Using a base of 10 as in toString(10) is the same as using nothing at all – base 10 is decimal which is what numbers are to begin with.

An interesting thing to note is that hexadecimal is a numbering system from 0 to 9 and then continuing from A to F which totals 16 characters. 15 in hex is “f” which is just one character in length. 16 is two characters – ’10’. So any RGB value lower than 16 in hexadecimal will be a single character in length. Such values need to be left-padded by a zero since a hexadecimal color is always a total of 6 characters (2 characters per R, G, and B). To use our example, 15 = f in hex, we need to left zero pad it to be “0f”. If your RGB value is rgb(15, 15, 15) the proper hexadecimal value would be “0f0f0f” and not “fff” (which is a completely different color, see below). You can see the zero-padding happening in the ternary operators on lines 7, 8, and 9.

The caveat to all of this are the “shortcode” hex values that you see from time to time. Such as “fff” for white which in its full form is “ffffff”, or “ccc” for a light grey which is really “cccccc”. How about this shortened hex: “7de” – that would be “77ddee”. See the pattern? If a browser sees a 3 character hex value then each individual character must represent R, G, and B. In the absence of any other data the rest of the hex values are implied by the existing data, so “7” = “77, “d” = “dd” and “e” = “ee”. It is then necessary to give a browser a full hexadecimal value where necessary to get the actual colors, not implied colors. Left zero-padding where needed achieves this.

So here now is my last example using a color palette toolbar to change the color of a Div element, where I take the background color of the clicked Div element, which is revealed as RGB, convert it back to hexadecimal and apply it to the color box:

<html><head><title></title>
<script language="javascript">
  function convertToHex(str){
    var raw = str.match(/(\d+)/g);
    var hexr = parseInt(raw[0]).toString(16);
    var hexg = parseInt(raw[1]).toString(16);
    var hexb = parseInt(raw[2]).toString(16);
        hexr = hexr.length == 1 ? '0' + hexr: hexr;
        hexg = hexg.length == 1 ? '0' + hexg: hexg;
        hexb = hexb.length == 1 ? '0' + hexb: hexb;
    var hex = '#' + hexr + hexg + hexb;
    return hex;
  }

  window.addEventListener('load',function(){
    document.getElementById('colorWrapper').addEventListener('click',function(e){
      if (e.target.attributes['class'].nodeValue == 'colorSwatch'){
        document.getElementById('box').style.backgroundColor = convertToHex(e.target.style.backgroundColor);
      }
    },false);
  },false);
</script>
<style type="text/css">
  #colorWrapper{
    padding:0px 8px 8px 8px;
    border:1px solid #000;
    width:228px;
    margin: 0px 0px 20px 0px;
  }
  .colorSwatch{
    height:50px;
    width:50px;
    display:inline-block;
  }
</style>
</head>
<body>

<div id="colorWrapper">
  <p>Select a color to change the box's background color.</p>
  <div class="colorSwatch" style="background-color:#5d8eae"></div>
  <div class="colorSwatch" style="background-color:#adae5d"></div>
  <div class="colorSwatch" style="background-color:#78ae5d"></div>
  <div class="colorSwatch" style="background-color:#a05dae"></div>
</div>
<div style="height:100px;width:100px;background-color:#185f8e;border:1px solid #ccc;" id="box"></div>
</body>
</html>

 

An interesting thing to note is that the hexedecimal is not inserted as hexadecimal – its inserted as RGB! Yeah… I don’t know why either… if someone knows, please enlighten me in the comments below….

Using JsDoc With Closures

05 Oct 2012

I’ve just recently switched over to using JsDoc to document my code. JsDoc will take commented JavaScript source-code and create formatted HTML documentation.

The only hurdle in my learning how to use JsDoc was getting it to document my variables/functions locked within closures and the answer turned out to be pretty simple.

To get started with JsDoc you have to first take a moment to get familiar with the JsDoc syntax. After that generating documentation is only a matter of executing JsDoc itself via command line.

Before I go any further here are some links:

Syntax

JsDoc syntax is easy to wrap your head around especially as examples can easily be found. The Wikipedia page for JsDoc is helpful, as is the actual JsDoc Wiki – and if you’ll permit me, this blog post! 😉

Here’s an example of using JsDoc with code written using the closure pattern:

...
/** 
 * module_1()
 * This function encapsulates all variables and methods used within module 1. 
 * @type {Object}
 * @return {} returns nothing
 * @name module_1
 * @namespace Hold all functionality
 */
var module_1 = (function(){
    /** 
    * createNewCustomerGroup()
    * This function handles creating new customer groups
    * @type {Function}
    * @return {} returns nothing
    * @param {String} The new customer group name
    * @see module_1.customerGroup.createCustomerGroup()
    */
    function createNewCustomerGroup(str){
        // code here
    }
})();
...

Of interest here are the @name and @namespace JsDoc tags – without this the object won’t be inspected by JsDoc.

Also note the description at the top of the comment – JsDoc assumes that any lines not starting with the @ symbol will be the description even though they are not preceeded by the @description tag.

Here’s an example of some JsDoc output:

Running JsDoc

JsDoc runs from the command line. Provided you have a compatible version of java installed (see the JsDoc Toolkit home page) its a pretty simple matter to generate your code.

First, as with any command-line applications that I personally use I place the apps themselves at the root of my machine so as to be able to get to them faster – in my case its my E: drive.

Next, take your javascript file and copy it into the JsDoc root – this location will contain jsrun.jar

With your file in place you’ll need to start up your machine’s command prompt and navigate to where your javascript file has just been copied to. The image below shows the location on my computer:

The next part is constructing the command to send to jsrun.jar – to make this easy on yourself just do what I do – write it once and keep it in a text file for quick editing/copying. In this example the command line looks like this:

java -jar jsrun.jar app\run.js -a -t=templates\jsdoc module1.js -a -p -v

Where “module1.js” is the script that I want to generate documentation of. Notice the switches at the end of the string, they are:

  • -a include all functions
  • -p include private/underscored functions
  • -v verbose feedback, this will print out within the command prompt

So, lets execute the above command line… I’ll just copy it, then right click on the Windows command prompt and paste, and then hit “return” to get things rolling. Here’s the result and feedback courtesy of the verbose switch:

The generated documentation will be in the “out” folder which exists in the JsDoc root. That’s all there is to it, go forth and document!

Logo

All content © 2012-2017.