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('');



ImageNow 6.x Iscript prompting

It isn’t publicized and even when you read the documentation, it isn’t that obvious (to me anyway).

I have a script that runs from the intool command that will merge records in ImageNow.  We use ImageNow in AP (and HR), and when vendors merge (or they were duplicates), we need a way to update all of the ImageNow records after they have been through the Lawson Vendor Merge so we can find them again.  After several months of manually updating the script to the new vendor numbers, which were declared with the #define, I needed a better way.

The answer lies in the Clib library that is part of Iscript.  The function I use is gets(), although there are several ways that have their own pluses and minuses.

//Get inputs from user and validate
Clib.printf("Enter Old Vendor Number: ");
var oldVendor = Clib.gets();
if (!checkNumber(oldVendor))
printf("Old Vendor is not a valid number");
Clib.printf("Enter New Vendor Number: ");
var newVendor = Clib.gets();
if (!checkNumber(newVendor))
printf("New Vendor is not a valid number");

First the script outputs the prompting text using printf, then waits for input from the command line.  checkNumber is a custom function that verifies that the input is a number.  I don’t use isNaN(), because I also need to check for length – hence the custom function.  If it fails the number test, then the script exits and returns an error code.

The script, which is called intoolVendorMerge.js, gets called from the command line:

\inserver6\bin>intool --cmd run-iscript --file intoolVendorMerge.js

So there you have it – prompting in Iscript.