Links

Hilarious Idiosyncrasies

Behold this gem.

('00'+(N.getMonth()+1).toString()).slice(-2);

I was trying to make a simple (ISO8601) date display show up on a web page and I learned some very fun things.

  • Javascript has no zerofill or sensible string formatting.

  • getMonth() function returns indexed from 0. So September comes back as 8!

  • Adding the date to a string silently makes the date number a string. Technically the toString() method is not needed here — but the parentheses are in this case.

JSON

Sometime, though rarely, it seems like a flat text file won’t do what you need; if you’re ever tempted to reach for XML, then JSON is probably appropriate. My Python notes cover dealing with JSON in Python programs.

JSON needs to use double quotes — it’s not optional like Python. For full details of just what comprises JSON formatting this is a good resource. Or check out https://jsonlint.com to see if your sample is valid.

But what if you’re just trying to sort out a mess on the command line? Then it’s good to use the program jq which does all JSON related things a command line person would ever want done.

With no fancy filters or other arguments, jq does a nice job of formatting and syntax highlighting JSON.

Of course it does a lot more than that! Here is an example of trying to find out the weather service’s grid values for a certain geographic location.

$ wget -qO- --header="${UA}" 'https://api.weather.gov/points/43.0318815,-78.883944' |\
> jq '.properties.gridX,.properties.gridY'
34
53

Just need to look at some big JSON file and want to use a pager and keep the nice syntax highlighting?

jq -C . < assets/indexes/1.16.json  | less -r

A nice overview of jq.

Here is a nice web interface to try jq syntax out live.

Redirect

Obviously a symlink is best, but sometimes you need for people to type a directory like http://xed.ch/r and see a PDF.

<!DOCTYPE html>
<html>
<meta http-equiv="location" content="URL=http://xed.ch/resume/resume.pdf" />
<head><title>One Cool Resume On The Way</title></head>
<body>
  <p>Attempting to redirect to: <b>http://xed.ch/resume/resume.pdf</b></p>
  <p>Looks like you sensibly have disabled JavaScript! You win the internet!</p>
  <p><a href="http://xed.ch/resume/resume.pdf">Click here</a> to do what must be done.</p>
  <script>window.location.href="http://xed.ch/resume/resume.pdf";</script>
</body> </html>

Miscellaneous

This is an interesting way to specify a URL. Just type this in the address bar of the browser.

javascript:location.href="http://www.xed.ch";

Time And Date

<head><script type="text/javascript">
function fmtime() {
  N= new Date(); H= N.getHours(); M= N.getMinutes(); S= N.getSeconds();
  UH= N.getUTCHours();
  Z= '00'; H= (Z+H).slice(-2); M= (Z+M).slice(-2); S= (Z+S).slice(-2);
  y= N.getFullYear();
  m= (Z+(N.getMonth()+1)).slice(-2);
  d= (Z+N.getDate()).slice(-2);
  o= H+':'+M+':'+S+'  ' +y+'-'+m+'-'+d +' (' +UH+M+'+0)'
  document.getElementById('clk').innerHTML=  o
  return fmtime;
}
</script></head>

<body onload="setInterval(fmtime(),1000);">
Current time:
<span id="clk" style="color:red"></span>
</body>

Note that this uses setInterval() rather than setTimeOut(). Some people use setTimeOut() and call it recursively. Apparently this is ok and not going to cause memory problems because of some weirdness with the event loop. Still, it smells bad to me. If you need another reason, the time out tries to really wait doing nothing for the specified interval. Ironically. So if the code after the interval takes a long time, the timeout still waits the specified amount of time. The setInterval() on the other hand sticks to a periodic schedule as best it can. If your interval is 1s and your computation takes .5s, the thing still fires every second.

This example also shows how to get a function to fire immediately and then after every interval. The trick is to call it during the setInterval() function and have that function return itself.

This example also shows how to handle zerofill padding format problems.

Automatically Refreshing A Page

This will reload the page every 2 seconds.

<body onload="javascript:setTimeout(&quot;location.reload(true);&quot;,2000);">

How Big Is the Window or Screen

Note this is not recommended for serious purposes without way more research due to browser inconsistencies etc. This is just a quick tip that helped me get some information about my browser’s situation.

<html>
<body onload="update_size()" onresize="update_size()">
<script>
function update_size() {
    // Screen dimensions 1920x1280, that kind of thing.
    var dispw = window.screen.availWidth;
    var disph = window.screen.availHeight;
    // Visible document size.
    var width = window.innerWidth
                 || document.documentElement.clientWidth
                 || document.body.clientWidth;
    var height = window.innerHeight
                 || document.documentElement.clientHeight
                 || document.body.clientHeight;
    document.getElementById("showw").innerHTML = width.toString();
    document.getElementById("showh").innerHTML = height.toString();
    document.getElementById("showsw").innerHTML = dispw.toString();
    document.getElementById("showsh").innerHTML = disph.toString();
}
</script>
Screen dimensions: <span id="showsw">NA</span>, <span id="showsh">NA</span> <br>
Document dimensions: <span id="showw">NA</span>, <span id="showh">NA</span>
</body>
</html>

Toggle Two Things

I created this to allow the user to toggle between displaying two SVG charts so that the differences between them could be more apparent.

<html>
<body>
<head><title>Toggle Test</title></head>

<script type="text/javascript">
  top.n= 0
  function toggle_div() {
    n++; n%=2;
    if (n) {
      document.getElementById('one').style.display='none';
      document.getElementById('two').style.display='block';
    }
    else {
      document.getElementById('one').style.display='block';
      document.getElementById('two').style.display='none';
    }
  }
</script>

<span style="background-color:#cecece;"
    onclick="toggle_div();">Click me to toggle.</span>
<div id="two" style="display:none;">TWO</div>
<div id="one">ONE</div>

</body>
</html>

This is embeddable so you can try it out right here.

Click me to toggle.
ONE

Radio Selection

<script type="text/javascript">
  function radio_select(I) {
    var items= document.getElementsByClassName("item");
    var x; for (x = 0; x<items.length; x++) { items[x].style.display = "none"; }
    document.getElementById(I).style.display='block';
  }
</script>

<div class="item" id="A" style="display:block;"> <p><b>Algeria</b></p> </div>
<div class="item" id="B" style="display:none;"> <p><b>Bulgaria</b></p> </div>
<div class="item" id="C" style="display:none;"> <p><b>Cambodia</b></p> </div>
<div class="item" id="D" style="display:none;"> <p><b>Dominican Republic</b></p> </div>
<div class="item" id="E" style="display:none;"> <p><b>Egypt</b></p> </div>
<div class="item" id="F" style="display:none;"> <p><b>France</b></p> </div>
<div class="item" id="G" style="display:none;"> <p><b>The Gambia</b></p> </div>

Click search term to select.
<table border="on">
<tr>
<td><span style="background-color:#ce7777;" onclick="radio_select('A');">Algeria</span></td>
<td><span style="background-color:#ce7777;" onclick="radio_select('B');">Bulgaria</span></td>
<td><span style="background-color:#ce7777;" onclick="radio_select('C');">Cambodia</span></td>
<td><span style="background-color:#ce7777;" onclick="radio_select('D');">Dominican Republic</span></td>
<td><span style="background-color:#ce7777;" onclick="radio_select('E');">Egypt</span></td>
<td><span style="background-color:#ce7777;" onclick="radio_select('F');">France</span></td>
<td><span style="background-color:#ce7777;" onclick="radio_select('G');">The Gambia</span></td>
</tr>
</table>

This is embeddable so you can try it out right here.

Algeria

Click search term to select.
Algeria Bulgaria Cambodia Dominican Republic Egypt France The Gambia

It is possible to have the choice be set randomly every time the page is reloaded. For example maybe you want to have many different search engines used randomly from a single search box. To do this, rename the ids above something like i0, i1, i2, etc. and then add this.

<body onload="radio_select('i'+Math.floor(Math.random()*document.getElementsByClassName('item').length))">

HTML5

HTML 5 Sliders

HTML 5 is fully of fancy new features. One that caught my eye for a particular project I was working on is the new <input> attribute range. This basically allows slider bars to be an input method for HTML forms. That’s almost never useful (which is why I suspect I rarely see this in the wild) but when it is, it is very nice that it’s built in these days. Here’s the official docs.

Here’s an example I made that shows off a minimal use which updates the page, i.e. no form submission necessary for being useful.

<html> <body onload="document.getElementById('SValue').innerHTML=128">
    0 <input type="range" max="255"
    onchange="document.getElementById('SValue').innerHTML=this.value" /> 255
    Value: <b id="SValue" >JavaScript Disabled!</b> <br/>
    0 <input type="range" id="S1" max="300" value="5"
    onchange="document.getElementById('S2Value').setAttribute('width',this.value)" />
    300 <br/>
    <svg> <rect id="S2Value" x="0" y="0" width="5" height="10"/> </svg>
</body> </html>
0 255 Value: 128
0 300

HTML 5 Canvas Tag

The canvas feature of HTML5 really changed the potential of Javascript for me. Being able to arbitrarily put points on the screen changed Javascript, for me, from a clumsy form box validation system to a much more interesting tool capable of really anything.

Today the problem with the canvas tag is that there is these days often an even better solution, SVG. Javascript also can control that. There are a lot of similarities as far as the Javascript goes. The main difference seems to be performance in certain contexts. If you don’t need the browser (as opposed to your Javascript code) to keep track of entities, then canvas is a much quicker way to render vectors to bitmap. However, if you want to have the browsers keep track of things so that you can, for example, style an element with a style sheet, then SVG is the best method. More details about this decision can be found here.

An Example Of The canvas Tag
<p>
<canvas id="canvas" width="838" height="220"> </canvas>

<script>
  var canvasContext =
     document.getElementById("canvas").getContext("2d");
  canvasContext.fillStyle = 'rgba(225, 225, 225, 1)';
  canvasContext.fillRect(0, 0, 838, 220);
  canvasContext.fillStyle = 'rgba(125, 12, 200, 0.7)';
  canvasContext.fillRect(250, 25, 150, 100);

  canvasContext.beginPath();
  canvasContext.arc(450, 110, 100, Math.PI * 1/2, Math.PI * 3/2);
  canvasContext.lineWidth = 15;
  canvasContext.lineCap = 'round';
  canvasContext.strokeStyle = 'rgba(25, 212, 200, 0.7)';
  canvasContext.stroke();

  canvasContext.beginPath();
  canvasContext.arc(350, 110, 100, Math.PI , Math.PI *4);
  canvasContext.lineWidth = 15;
  canvasContext.lineCap = 'butt';
  canvasContext.strokeStyle = 'rgba(202, 2, 202, 0.7)';
  canvasContext.stroke();
</script>
</p>

Output Of canvas Tag Example

Auto Complete

It’s all the rage to have a web utility that has some kind of form box that just can’t wait until you’re done typing. It has to automatically suggest a list of possibilities which remain, based on the constraint of what you’ve typed so far. This functionality is pretty well implemented in jQuery and there’s no need to reinvent the specific JavaScript code. However, using this effectively can be somewhat tricky. Most web resources seem to focus on a language, which for search engine purposes I will not mention, that is infamous for being a disaster with respect to web security. There are alternatives! The autocomplete function of jQuery can operate in many ways and the mode where it requests an external link to give it hints can be crafted in any way you like. I’m going to show how to use autocomplete with straight Python with no frameworks or exotic dependencies whatsoever.

First you need your HTML:

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>A Tiny Test Of jQuery Autocomplete</title>
    <link rel="stylesheet" href="./jquery-ui.css" />
    <script src="./jquery-1.8.2.js"></script>
    <script src="./jquery-ui.js"></script>
    <script>
    $(function() { $( "#tags" ).autocomplete({ source:"./tinysuggester.py" }); });
    </script>
</head>

<body>
<p>Test autocomplete with a Unix command.</p>
<div class="ui-widget"><label for="tags">Search: </label><input id="tags" /></div>

<p>Look <a href="http://api.jqueryui.com/autocomplete/">here</a>
for specifications on jquery's autocomplete function. </p>
<p>These required resources can be installed locally to ensure stability.</p>
<ul>
<li><a
href="http://code.jquery.com/ui/1.9.0/themes/base/jquery-ui.css">
The jquery CSS</a></li>
<li><a href="http://code.jquery.com/jquery-1.8.2.js">
The JavaScript of jQuery itself</a></li>
<li><a href="http://code.jquery.com/ui/1.9.0/jquery-ui.js">
The JavaScript of jQuery's UI widgets</a></li>
<li><a href="./tinysuggester.py">
The suggester script</a></li>
</ul>
</body>
</html>

First note that you need the jQuery software. Its location is outlined in the bottom part of the HTML. Just download this and keep a local copy. You’ll need the general jQuery stuff, the jQuery User Interface module and the jQuery style sheet (CSS) to make it all work.

The second thing to note is that the part of this web page that is important to us happens in the last <script> tag. This is where the autocomplete function is deployed. The important thing to notice is the source reference. This is where the completion routine will take its list of suggestions from. It turns out that you can put a static list there ( formatted either {"hint1":"rhino", "hint2":"rhesus monkey"} or ["ash","alder","aspen"] - but don’t use single quotes!).

In our example, the JavaScript will be having the browser call another URL and take the contents of what is delivered and make that into the suggestion list. So, you need a web resource that can produce the desired list. Again, this could be static, but just living on the remote server. There’s not much point to this. What you’re really after is spontaneously generating a list based on a sensible heuristic applied to your data set.

The obvious examples are to suggest all words that are in your master list which start with the letters the user just typed. For smaller lists, you could look for all records which contain the typed letters anywhere in them. You could do either of those things but with a cut off limit so no more than 10 or 50 suggestions are ever returned. If your data set is very big and contains other hints, you could do a quick sort by relevance (maybe most popular) before sending only the first 10.

Here is an example implemented in Python which will prompt with Unix commands (just from /usr/bin) which begin with the letters the user has typed in. Note that when the user types some stuff, there are some (controllable) parameters that tell the jQuery routines how long to wait and how persistent to keep submitting autocomplete attempts. When a request is made, however, the URI that you specify in the source field will be called with an additional CGI style argument appended. If the URI is ./tinysuggester.py as in our example and the user types "ps2", the client will make a request that looks like ./tinysuggester.py?term=ps2. Here’s what you can do with that.

#!/usr/bin/python
import os

def getpossibles(t):
    MAX= 10       # Return no more than this many suggestions.
    ol= list()    # Output list.
    for f in os.listdir('/usr/bin'):
        if f.startswith(t):
            ol.append(f)
            MAX -= 1
        if not MAX:
            break
    return ol

# Handle the input which will look like this:
#  /path/suggester.py?term=ps2
term= os.environ["QUERY_STRING"].split('=')[1]

possibles= getpossibles(term)

content_type= 'Content-type: text/plain\n\n'
print content_type + str(possibles).replace("'",'"')

As you can see the complex part is in the function getpossibles. This is the real essence of what the autocomplete is supposed to do for your application which is why you must make your own. Here’s an example of another one that uses a static list and no limits.

def getpossibles(t):
    db= ["january", "february", "march", "april", "may", "june",
         "july", "august", "september", "october", "november", "december"]
    return [w for w in db if t in w]  # Return list of possibles.

You could (and often will need to) write one that makes a database look up and returns the query results.