JavaScript code works on chrome, doesn't work on IE and firefox
<p>I created this script for educational reasons in pure JS. It adds sorting to tables (when a header is clicked). I decided that it's quite useful and tried to use it in my project. It works fine on Google Chrome (I used this browser when I was creating the script), but doesn't on IE and Firefox. Can you help me?</p>

<pre><code>alert("Remember to add LoadSetup function to window.onload event and to remove this alert.\nAlso remember that table you want to sort must have class 'sortable' and an unique id.\nThe table must be build properly using &lt;thead&gt; and &lt;tbody&gt; tags.")


function addLoadEvent(func) {
// Dobra funkcja która radzi sobie z dodawaniem nowych funkcji do zdażenia window.onload
    var oldonload = window.onload;
    if (typeof window.onload != 'function') window.onload = func;
    else {
        window.onload = function() {
            if (oldonload) oldonload();
            func();
        }
    }
}

window.onload = LoadSetup;

function LoadSetup()
{
    //find sortable tables and set sorting state to 0 (not sorted)  
    tables = document.getElementsByTagName("table");
    tablesStates = new Array(tables.length);

    for(var i=0;i&lt;tables.length;i++){
        tableName = tables[i].getAttribute("id");
        if(hasClass(tables[i], "sortable") &amp;&amp; tableName != null){
            tablesStates[tableName] = new Array();

            thead = tables[i].getElementsByTagName("thead")[0];
            header = thead.getElementsByTagName("tr")[0].getElementsByTagName("th");

            for(var j=0; j&lt;header.length; j++){
                if(!hasClass(header[j], 'notsortable')){
                    tablesStates[tableName][header[j].innerHTML] = 0;
                    header[j].removeAttribute("onclick");
                    header[j].setAttribute("onclick", "sortTable('"+tableName+"', '"+header[j].innerHTML+"')");
                }
            }
        }
    }
}

function hasClass(ele, cls)
{
    return ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'));
}

String.prototype.capitalize = function() {
// fajna funkcja
    return this.charAt(0).toUpperCase() + this.slice(1);
}
String.prototype.capitalizeAll = function() {
// fajna funkcja
    result = '';
    for(var i=0; i&lt; this.length;i++)
        result += this.charAt(i).toUpperCase();
    return result;
}

function prepareStringForCmp(s){
    en = ['a','c','e','l','n','o','s','z','z','A','C','E','L','N','O','S','Z','Z'];
    pl = ['ą','ć','ę','ł','ń','ó','ś','ź','ż','Ą','Ć','Ę','Ł','Ń','Ó','Ś','Ź','Ż'];

    for(var i=0;i&lt;pl.length;i++){
        regex = new RegExp(pl[i],"g");
        s = s.replace(regex,en[i]);
    }
    return s.capitalizeAll();
}

function cmpStr(a, b){
    //a=prepareStringForCmp(a);
    //b=prepareStringForCmp(b);
    if(a == b)return 0;
    else if(a &gt; b) return 1;
    else return -1;
}
function cmpStrRev(a, b){return cmpStr(b, a);}

function cmpNum(a, b){ return a - b;}
function cmpNumRev(a, b){return cmpNum(b, a);}

function cmp(a,b,type,asc)
{
// returns -1 if a &lt; b ---- in ascending mode ( asc=true)
// returns 1 is a &gt; b ---- in ascending mode ( asc=true)
// returns 0 if a == b

    if(type == "number"){
        if(asc == true) return cmpNum(a,b);
        else return cmpNumRev(a,b);
    }
    else if(type == "date"){
        if(asc == true) return 0;
        else return 0;
    }
    else{
        if(asc == true) return cmpStr(a,b);
        else return cmpStrRev(a,b);

    }
}

/////////////////////////////////////////////////////////////
// Bubble Sort

function bubbleSortTable(tab, col, type, asc) {
    for(var i=0; i &lt; tab.length; i++){
        for(var j=0; j&lt; tab.length-1; j++){
            if(cmp(tab[j].getElementsByTagName("td")[col].innerText, tab[j+1].getElementsByTagName("td")[col].innerText, type, asc) &gt; 0)
            {
                buf = tab[j].innerHTML;
                tab[j].innerHTML = tab[j+1].innerHTML;
                tab[j+1].innerHTML = buf;
            }
        }
    }
}

/////////////////////////////////////////////////////////////
// Quick Sort

function partitionTable(l, r, A, col, type, asc)
{
    x = A[l].getElementsByTagName("td")[col].innerText;
    i = l-1;
    j = r+1;
    while(true){
        while(true){
            j = j-1;
            if(cmp(A[j].getElementsByTagName("td")[col].innerText, x, type, asc) &lt;= 0) break;
        }
        while(true){
            i = i+1;
            if(cmp(A[i].getElementsByTagName("td")[col].innerText, x, type, asc) &gt;= 0) break;
        }

        if(i&lt;j){
            buf = A[i].innerHTML;
            A[i].innerHTML = A[j].innerHTML;
            A[j].innerHTML = buf;
        }
        else return j;
    }

}

function qsortTable(l, r, A, col, type, asc)
{
//qsort(tablica, 0, tablica.lenght -1);
    if(l&lt;r){
        q = partitionTable(l, r, A, col, type, asc);
        qsortTable(l, q, A, col, type, asc);
        qsortTable(q+1, r, A, col, type, asc);
    }
}

/////////////////////////////////////////////////////////////

function sortTable(id, colName){
// sorts table
// returns true if sorting done; otherwise false
// works for strings and numbers


    if(tablesStates[id][colName] &gt;= 0) asc = true;
    else asc = false;

    tab = document.getElementById(id);
    thead = tab.getElementsByTagName("thead")[0];
    header = thead.getElementsByTagName("tr")[0].getElementsByTagName("th");
    tbody = tab.getElementsByTagName("tbody")[0];
    rows = tbody.getElementsByTagName("tr");

    col = -1;
    for(var i=0; i &lt; header.length; i++){
        if(header[i].innerHTML == colName){
            col = i;
            colType = header[i].getAttribute("class");      
            break;
        }
    }
    if(col == -1) return false;

    // demanded header found

    bubbleSortTable(rows, col, colType, asc);
    //qsortTable(0, rows.length-1,rows, col, colType, asc);
    if(tablesStates[id][colName] &gt;= 0) tablesStates[id][colName] = -1;
    else tablesStates[id][colName] = 1;
}
</code></pre>

<p>And also a simple html for this:</p>

<pre><code>&lt;!DOCTYPE html PUBLIC 
"-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml" 
xml:lang="pl" lang="pl"&gt;
&lt;head&gt;
    &lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8" /&gt;
    &lt;script type="text/javascript" src="sortTable.js"&gt;&lt;/script&gt;
    &lt;link rel="stylesheet" type="text/css" href="x.css" /&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div id="content_box"&gt;

&lt;table class="sortable"  id="tabela1"&gt;
&lt;thead&gt;
    &lt;tr&gt;&lt;th&gt;name&lt;/th&gt;&lt;th class="number"&gt;age&lt;/th&gt;&lt;th&gt;city&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
    &lt;tr&gt; &lt;td&gt;Jan&lt;/td&gt; &lt;td&gt;21&lt;/td&gt; &lt;td&gt;Gdańsk&lt;/td&gt; &lt;/tr&gt;
    &lt;tr&gt; &lt;td&gt;Andrzej&lt;/td&gt; &lt;td&gt;17&lt;/td&gt; &lt;td&gt;Warszawa&lt;/td&gt; &lt;/tr&gt;
    &lt;tr&gt; &lt;td&gt;Paweł&lt;/td&gt; &lt;td&gt;112&lt;/td&gt; &lt;td&gt;toruń&lt;/td&gt; &lt;/tr&gt;
    &lt;tr&gt; &lt;td&gt;Mateusz&lt;/td&gt; &lt;td&gt;43&lt;/td&gt; &lt;td&gt;Łomża&lt;/td&gt; &lt;/tr&gt;
        &lt;tr&gt; &lt;td&gt;ADAM&lt;/td&gt; &lt;td&gt;21&lt;/td&gt; &lt;td&gt;Gdańsk&lt;/td&gt; &lt;/tr&gt;
    &lt;tr&gt; &lt;td&gt;ŻANETA&lt;/td&gt; &lt;td&gt;17&lt;/td&gt; &lt;td&gt;Warszawa&lt;/td&gt; &lt;/tr&gt;
    &lt;tr&gt; &lt;td&gt;Paweł&lt;/td&gt; &lt;td&gt;112&lt;/td&gt; &lt;td&gt;toruń&lt;/td&gt; &lt;/tr&gt;
    &lt;tr&gt; &lt;td&gt;LEON&lt;/td&gt; &lt;td&gt;43&lt;/td&gt; &lt;td&gt;Łomża&lt;/td&gt; &lt;/tr&gt;
        &lt;tr&gt; &lt;td&gt;Jan&lt;/td&gt; &lt;td&gt;21&lt;/td&gt; &lt;td&gt;Gdańsk&lt;/td&gt; &lt;/tr&gt;
    &lt;tr&gt; &lt;td&gt;Andrzej&lt;/td&gt; &lt;td&gt;17&lt;/td&gt; &lt;td&gt;Warszawa&lt;/td&gt; &lt;/tr&gt;
    &lt;tr&gt; &lt;td&gt;FRYDERYK&lt;/td&gt; &lt;td&gt;112&lt;/td&gt; &lt;td&gt;toruń&lt;/td&gt; &lt;/tr&gt;
    &lt;tr&gt; &lt;td&gt;Mateusz&lt;/td&gt; &lt;td&gt;43&lt;/td&gt; &lt;td&gt;Łomża&lt;/td&gt; &lt;/tr&gt;
        &lt;tr&gt; &lt;td&gt;Jan&lt;/td&gt; &lt;td&gt;21&lt;/td&gt; &lt;td&gt;Gdańsk&lt;/td&gt; &lt;/tr&gt;
    &lt;tr&gt; &lt;td&gt;BALBINA&lt;/td&gt; &lt;td&gt;17&lt;/td&gt; &lt;td&gt;Warszawa&lt;/td&gt; &lt;/tr&gt;
    &lt;tr&gt; &lt;td&gt;ADAM&lt;/td&gt; &lt;td&gt;112&lt;/td&gt; &lt;td&gt;toruń&lt;/td&gt; &lt;/tr&gt;
    &lt;tr&gt; &lt;td&gt;TERESA&lt;/td&gt; &lt;td&gt;43&lt;/td&gt; &lt;td&gt;Łomża&lt;/td&gt; &lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</code></pre>

<p>More detailed description:</p>

<p>LoadSetup - works (and adds sorting functionality)
When header is clicked it should do the sorting and it does on Chrome.
Than it goes like this: sortTable  >> bubbleSortTable >> cmp
in cmp(a,b,type,asc) a and b are 'undefined' in Firefox and IE and than the script somewhere breaks and nothing gets sorted.</p>
