Bootstrap navigation tabs without using anchors

Well, almost – but the required effect is achieved.

The problem with using anchors in a dynamic web page is that you don’t always want to show the corresponding href in the browser’s status bar when the user hovers over the anchor link.

Twitters Bootstrap navigation tabs are designed to work with anchor elements. I wanted to use these tabs without showing the corresponding anchor links in the browser’s status bar.

solution is as follows (the assumption is that bootstrap.css is included of course):

Add this to your CSS file:

.link {
        cursor:pointer;
        color:blue;
}

And create the tabs as follows:

<ul class="nav nav-tabs">

  <li id="tab1" class="active">
        <a>
        <span class="link" onClick="firstTab()">
        First Tab
        </span>
        </a>
  </li>

  <li id="tab2">
        <a>
        <span class="link" onClick="secondTab()">
        Second Tab
        </span>
        </a>
  </li>

</ul>

Just add the corresponding DIVs and make them hidden or shown accordingly in the event that a tab is clicked.

Per Nick’s request, here’s a small self contained example for one way of accomplishing the above:

<!DOCTYPE html>
<head>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
    <script>
        function firstTab() {
           putTabText("<br/> Hi, I'm the content of <b>Tab1</b>");            
        }

        function secondTab() {
           putTabText("<br/> ... and I'm the content of <b>Tab2</b>");            
        }
        
        function putTabText(str) {
            document.getElementById('idContent').innerHTML = str;
        }
    </script>
</head>
<html>
    <style>
        .link {
        cursor:pointer;
        color:blue;
    </style>
    <body onLoad='firstTab()'>
        <div class="container">
            <ul class="nav nav-tabs">
            
              <li id="tab1" class="active">
                    <a>
                    <span class="link" onClick="firstTab()">
                    First Tab
                    </span>
                    </a>
              </li>
            
              <li id="tab2">
                    <a>
                    <span class="link" onClick="secondTab()">
                    Second Tab
                    </span>
                    </a>
              </li>
            </ul>  
          <div id='idContent'></div>
        </div>      
    </body>
</html>

Thought of the day – don’t confuse the fight for the battle

Every now and then I formulate to myself some thoughts and current conclusions regarding things in general – be it life philosophy and everything that is derived from it. I’m going to start and write these down just to have them placed somewhere either for others to contemplate or for my future self to laugh at 🙂

So, the first is about a thought regarding when to give something up. The rules are:

  1. Never ever give up the battle.
  2. Know when its time to give up the fight.
  3. Don’t confuse the fight for the battle.

How do you know what is a fight and what is a battle – that’s the million dollar question, but I believe there’s a very good indicator: if the signs show that it is unwinnable, then it is a fight and not a battle – time to give it up.

Compiling OpenResty (nginx) on OS/X

When building OpenResty (the excellent Lua add-on for nginx) on OS/X I got the following error:

Undefined symbols for architecture x86_64:
  "_pcre_free_study", referenced from:
      _ngx_pcre_free_studies in ngx_regex.o
      _ngx_http_lua_ngx_re_match in ngx_http_lua_regex.o
      _ngx_http_lua_ngx_re_gmatch in ngx_http_lua_regex.o
      _ngx_http_lua_ngx_re_sub_helper in ngx_http_lua_regex.o
      _ngx_http_lua_ngx_re_gmatch_cleanup in ngx_http_lua_regex.o
      _ngx_http_lua_ngx_re_gmatch_gc in ngx_http_lua_regex.o
      _ngx_http_lua_ngx_re_gmatch_iterator in ngx_http_lua_regex.o
      ...
ld: symbol(s) not found for architecture x86_64

To cut a long story short, download the latest version of pcre (PCRE – Perl Compatible Regular Expressions) from ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/, extract it to a directory, say /Users/me/pcre-8.21/ and then from the ngx-openresty source directory run configure with:

./configure --with-luajit --with-pcre=/Users/me/pcre-8.21/

all will be well…

—– update from Sept 2013:

I realised that perhaps a better way to install PCRE would be to install homebrew on your Mac and then just:

brew install pcre

however, you will need to know where homebrew installed pcre as you will need to add that parameter when running configure. There are several ways of locating a file on the Mac (I’ll refer to the command line only. The grep is since I know it is installed somewhere in /usr/local):

  • mdfind (uses spotlight), for example:
mdfind pcre | grep usr/local
  • a combination of
sudo /usr/libexec/locate.updatedb

and then

locate pcre | grep usr/local
  • or just plain old find:
find /usr/local -name pcre -print

in my case the location was /usr/local/Cellar/pcre/8.33/ so the configure parameters were:

./configure --with-luajit 
            --with-cc-opt="-I/usr/local/Cellar/pcre/8.33/include" 
            --with-ld-opt="-L/usr/local/Cellar/pcre/8.33/lib"

Quick guide to Google closure compiler tool

Google’s closure compiler is an impressive tool that parses JavaScript code and make various optimizations on it, including minimizing its size.

This post will provide what is needed to effectively utilize it in minimum time.

Step 1 – verify consistant property access methods in your code

The first thing you should do is make sure you have a consistent way of accessing object properties in your code – i.e don’t have one place in the code setting a property of some object, for example like this:

obj["hello"]="there"

or

return { "hello":"there" }

while in another place in your code you access it via the dot notation, e.g:

myobj = obj.hello

The reason this will cause problems is because the closure compiler will not rename strings but will rename the access fields in the dotted notation – which will of course cause problems in this case.

Step 2 – list the files that can be clumped together in one compilation

The more files that can be compiled together with Google Closure compiler, the less you will have to deal with defining external functions and variables (i.e, those that are used by the compiled code but are defined in external/uncompiled code) or exporting variables and functions (those that you don’t want the compiler to rename since they are used by external/non-compiled code.

Step 3 – list internal functions and variables that non-compiled code needs to access

Go through your code and list the functions and variables that you don’t want to be renamed by the Closure compiler since they have to be accessed by Javascript code that will not be compiled (You also need this if you have strings in the compiled code that are evaluated at runtime as function calls since strings are not changed by the compiler).

So, for example, say you have the following in the code you want to compile:

document.mydiv.innerHTML="<a href='#' onClick='myFunc1()'>Click</a>";
function myFunc1()
{
    alert("link was clicked");
}

function myFunc2()
{
    alert( "my API function was called" );
}

You will need to export MyFunc1 (because it is called from within a string) and MyFunc2 (because it is called from outside the compiled code).

The way to export functions so that they can be accessed after they are renamed by the compiler is to do the following trick – just add to your code:

window["myFunc1"]=myFunc1;
window["myFunc2"]=myFunc2;
window["myObj"]={};
window["myObj"][myMethod"] = myObj.myMethod;

This way, the compiler will rename myFunc1 and myFunc2 in the optimized code (and also myObj.myMethod), but the outside code will still be able to access them by their original name.

Step 4 – list external functions and variables that compiled code needs to access

You need to let the closure compiler know which function calls and variables should not be renamed since the original name is needed to be able to call the external function/variable.
For example if you need to access an external variable named g_mymap and an external function named myinit then create a file named externs1.js for example which contains the following:

var g_mymap;
function init( str ) {}

Step5 – Compile!

java -jar compiler.jar --compilation_level ADVANCED_OPTIMIZATIONS  
                       --js=../src/script1.js 
                       --js=../src/script2.js 
                       --js=../src/script3.js 
                       --js=../src/script4.js 
                       --externs ../src/externs1.js 
                       --js_output_file=../release/code.js

Note that in the above example script1.js to script4.js are the scripts who’s variables and functions will be renamed in the optimization process, externs1.js contains the list of external functions and variables that you wish to access from within the compiled code (and thus you don’t want to be renamed – see step 4) and code.js will be the minimized and optimized code produced by the Google Closure compiler.

More progress on JavaScript Scrabble

I’m excited at the speed of the computer’s moves. Almost all moves take less than a second on my MacBook Air (1.86 GHz Intel Core 2 Duo) – the times when a move requires about 3 seconds is when the computer analyses how to play a joker. Did I already mention this is pure JavaScript running on the browser ?

Its amazing how far JavaScript has come, from being considered a toy language for running some checks on form inputs to being recognized as the powerful (though sometimes quirky) language that powers the Internet today.

New features
New features

Fastest Scrabble Algorithm ?

After making a small change, I’ve managed to improve the algorithm so that the computer will make a move in under a second every turn. Considering this is all written in pure JavaScript and runs on the browser, I’m starting to wonder whether the algorithm I wrote is the fastest existing scrabble algorithm out there…

JavaScript Scrabble in Russian

The nice thing about having a blog site that no one knows about is that if you’re creating a project and you don’t want potential competitors to know what you are up to, you can freely shout all your new ideas and features to the void… 🙂

The English JavaScript is working nicely so I’ve added a Russian version too, just to see how fast I can add support for other languages. The answer: very fast. It will take less than an hour to add localization and play support for any new language (RTL excluded for now, but will be handled later).

An example below:

Support for Russian
Support for Russian

Another sleepless night

Making progress with the Scrabble clone. Also made changes so it will even work on IE6. There is still the 10% of polishing work that takes 90% of the time, but its fun so I’m not complaining. Its great to see that the number of words in the dictionary have no noticeable effect on the speed of the search.

Current look - still under construction
Current look – still under construction

Scrabble in pure JavaScript

It took me almost two weeks but I’m nearing completion of an implementation of a fast Scrabble game against the computer written in pure JavaScript. It is both fast (less than 3 seconds per move) and unbeatable.

Here you can see the browser (playing in Red) giving me a humility lesson (playing in Green)…

First Scrabble prototype
First Scrabble prototype