Javascript Code128 Barcode

This is a departure from my usual postings. I’m not going to give a whole lot of background or write up on it. Instead I’m just going to give you the code. You either need code that can generate code128 or you don’t. The code provided here should give you a working page that will generate a Code128 barcode in either horizontal or vertical format. I’ve tested the generation in IE (7+) and Firefox (3.5) and tested the reading of the barcode with the AABBY OCR software.

My reason for pursuing this was because I’ve got several different methods to read barcodes, but not many to generate them. One involves special fonts, which is fine for server based generation, but when I need to generate a barcode based on data that is on a web page, the options were lacking.

This code is derived from the code at: Code128. The updates that I’m providing are:

  1. Original Page does not display barcode in IE 7+. This has been fixed.
  2. Separated CSS and Javascript into separate files
  3. Removed requirement of base2.js library (I didn’t see any value-add to include this large of a library)
  4. Added code to support Vertical Barcode (top to bottom)
  5. The original form generation was a bit odd and convoluted, so it has been simplified

For the most part, except for removing the base2.js dependencies, I left the javascript in-tact. I must say that some of it is exceptionally well-done by the original author.

To switch between vertical layout and horizontal layout, change the css class of the div element with the “barcode” id in the base128.htm file. Please note that the vertical barcode sets a z-index of 99. This means that you should set a left margin for your base elements, otherwise the barcode will float over the top and be unreadable.

***The HTML file: code128.htm

<link rel="StyleSheet" href="barcode.css" type="text/css" />
<script src="barcode.js"></script>
<script type="text/javascript">
function encode()
  var strValue = document.getElementById("barcode_input").value;
  var strBarcodeHTML = code128(strValue);
  document.getElementById("barcode").innerHTML = strBarcodeHTML;
<div class="barcode128v" id="barcode"></div>
<br /><br />
<input style="margin-left:45px" type="text" id="barcode_input"></input>
<input type="button" value="Encode" onclick="encode()"/>

***The CSS file: barcode.css

                CODE 128 styles

/* ------------------- Horizontal Barcode -------------------- */
.barcode128h  {
    clear: both;
    padding: 0 10px /*quiet zone*/;
    overflow: auto;
    height: 0.35in   /*size*/;

.barcode128h div {
    /*float: left;*/
    height: 0.2 in  /*size*/;
    display: inline;

.barcode128h label {
    clear: both;
    display: block;
    text-align: center;
    font: 0.125in/100% helvetica /*size*/;

.barcode128h .bar1 { border-left: 1px solid black }
.barcode128h .bar2 { border-left: 2px solid black }
.barcode128h .bar3 { border-left: 3px solid black }
.barcode128h .bar4 { border-left: 4px solid black }
.barcode128h .space0 { margin-right: 0px }
.barcode128h .space1 { margin-right: 1px }
.barcode128h .space2 { margin-right: 2px }
.barcode128h .space3 { margin-right: 3px }
.barcode128h .space4 { margin-right: 4px }

/* ------------------- Vertical Barcode --------------------- */
.barcode128v  {
    /*float: top;*/
    clear: left;
    position: absolute;
    padding: 10 0px /*quiet zone*/;
    overflow: auto;
    width: 30px  /*size*/;
    z-index: 99;


.barcode128v div {
    float: top;
    display: block;
    /*width: 20px;

.barcode128v label {
    clear: right;
    display: block;
    text-align: center;
    font: 0.125in/100% helvetica /*size*/;
    writing-mode: tb-rl;
    filter: flipH() flipV();

.barcode128v .bar1 { border-top: 1px solid black; z-index: 99;}
.barcode128v .bar2 { border-top: 2px solid black; z-index: 99;}
.barcode128v .bar3 { border-top: 3px solid black; z-index: 99;}
.barcode128v .bar4 { border-top: 4px solid black; z-index: 99;}
.barcode128v .space0 { margin-bottom: 0px; z-index: 99; }
.barcode128v .space1 { margin-bottom: 1px; z-index: 99; }
.barcode128v .space2 { margin-bottom: 2px; z-index: 99; }
.barcode128v .space3 { margin-bottom: 3px; z-index: 99; }
.barcode128v .space4 { margin-bottom: 4px; z-index: 99; }

***The Javascript file: barcode.js

BARS       = [212222,222122,222221,121223,121322,131222,122213,122312,132212,221213,221312,231212,112232,122132,122231,113222,123122,123221,223211,221132,221231,213212,223112,312131,311222,321122,321221,312212,322112,322211,212123,212321,232121,111323,131123,131321,112313,132113,132311,211313,231113,231311,112133,112331,132131,113123,113321,133121,313121,211331,231131,213113,213311,213131,311123,311321,331121,312113,312311,332111,314111,221411,431111,111224,111422,121124,121421,141122,141221,112214,112412,122114,122411,142112,142211,241211,221114,413111,241112,134111,111242,121142,121241,114212,124112,124211,411212,421112,421211,212141,214121,412121,111143,111341,131141,114113,114311,411113,411311,113141,114131,311141,411131,211412,211214,211232,23311120];
STOP       = 106 //BARS[STOP]==23311120 (manually added a zero at the end)

var fromType128 = {
    A: function(charCode) {
        if (charCode>=0 && charCode<32)
            return charCode+64;
        if (charCode>=32 && charCode<96)
            return charCode-32;
        return charCode;
    B: function(charCode) {
        if (charCode>=32 && charCode<128)
            return charCode-32;
        return charCode;
    C: function(charCode) {
        return charCode;

function code128(code, barcodeType) {
    if (arguments.length<2)
        barcodeType = code128Detect(code);
    if (barcodeType=='C' && code.length%2==1)
        code = '0'+code;
    var a = parseBarcode128(code,  barcodeType);
    return bar2html128(a.join('')) ;//+ '<label>' + code + '</label>';

function code128Detect(code) {
    if (/^[0-9]+$/.test(code)) return 'C';
    if (/[a-z]/.test(code)) return 'B';
    return 'A';

function parseBarcode128(barcode, barcodeType) {
    var bars = [];
    bars.add = function(nr) {
        var nrCode = BARS[nr];
        this.check = this.length==0 ? nr : this.check + nr*this.length;
        this.push( nrCode || format("UNDEFINED: %1->%2", nr, nrCode) );

    bars.add(START_BASE + barcodeType.charCodeAt(0));
    for(var i=0; i<barcode.length; i++)
        var code = barcodeType=='C' ? +barcode.substr(i++, 2) : barcode.charCodeAt(i);
        converted = fromType128[barcodeType](code);
        if (isNaN(converted) || converted<0 || converted>106)
            throw new Error(format("Unrecognized character (%1) at position %2 in code '%3'.", code, i, barcode));
        bars.add( converted );
    bars.push(BARS[bars.check % 103], BARS[STOP]);

    return bars;

function format(c){
    var d=arguments;
    var e= new RegExp("%([1-"+(arguments.length-1)+"])","g");
    return(c+"").replace(e,function(a,b){return d[b]})

function bar2html128(s) {
    for(var pos=0, sb=[]; pos<s.length; pos+=2)
        sb.push('<div class="bar' + s.charAt(pos) + ' space' + s.charAt(pos+1) + '"></div>');
    return sb.join('');




    1. You would need to modify the css file. It depends on which barcode you’re talking about (horizontal or vertical) when you refer to width.

      When talking about the horizontal (left-to-right), you need to modify the .bar and .space sections. Be careful doing this, you must make sure that you keep relationship the same in that the size of bar1 must equal space1 and bar4 must be four times the size of bar1. These relationships are defined by the specification and if you violate them, your barcode will not be readable. I would also caution you against trying to make the width too much smaller because you have to deal with a printer actually being able to reproduce something smaller than 1 pixel (the current smallest bar).

      When talking about the vertical barcode (top-to-bottom), you just need to change the .width property. I’m not aware of any restrictions on the width in this respect other than what your barcode reader can handle.

    1. I don’t see any reason why you couldn’t build the barcode on page load. A lot will depend on where the users are coming from though. Is it a page you control or from somewhere else. The easiest would probably be to call the page with a URL parameter. You would need to write a function that would parse the parameter and pass to encode(). However, in that scenario, you probably need to worry about special characters, so you’d have to make sure that the calling page does some level of URL encoding and you would need to decode when the barcode page is called.

  1. Note, you need to change in the css file : barcode128h div { display: inline } to { display: inline-block } to make the horizontal bar code resizable. Thanks for the code!

  2. Hi, this is a fantastic solution!!! Well done. The question I have is How can I change the height of the horizontal bar code? I know it is a CSS change and I think its the .barcode128h div {height: 0.2 in} parameter, but that really doesn’t appear to drive change in the output. No matter what I do, its still always only about 1/2 inch tall. I am testing with ie 10.



  3. Thank God for you and Google search. I was up much of the night trying to solve a problem where a javascript based barcode generator would render fine on the screen, but would only print on Macs but not on PCs. Found your page, replaced the offending code and voila! I was able to go home and catch a nap before starting a new day.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s