Standalone Electoral Poll Lookup using Javascript and Taffy DB

There are Advance Polls for the municipal elections in Charlottetown, Cornwall, Stratford and Summerside on October 23, 25 and 29; these are opportunities for electors who can’t vote on election day (November 1) to vote in advance.

On election day there are 125 polling stations located across the municipalities (find yours here); Advance Polls, however, are consolidated at central locations (Charlottetown Civic Centre, Cornwall Town Hall, Stratford Town Hall and Credit Union Place in Summerside) and because electors from different wards and polls will be converging on these locations for the Advance Polls, Elections PEI needs a quick way of routing the right elector to the right part of the room.

They’ve secured 4 laptops to use for this purpose, but none will be connected to the Internet, so they needed a standalone “ward and poll lookup” application.

Rather than trying to code some sort of native Windows application (foreign territory for us, fraught with the bad memories left over from our days as a Windows shop, and requiring me to develop inside a virtual Windows machine on my Mac), I reasoned that the best and most universal way to proceed would be to write something in 100% JavaScript so that it could run entirely in the browser, and have no external dependencies (on a server, on operating system, or on the Internet).

This turned out to be surprisingly easy, with the guts of the application boiling down to no more than a few dozen lines of code, greatly aided by Taffy DB, a self-described “a free and open source JavaScript library that acts as thin data layer,” which hides away all the databaseiness.

My first step was to take the data stored in MySQL tables about which civic addresses are in which wards and polls and create a Taffy DB-friendly representation, which looks like this:

var addresses = new TAFFY(
[
{no:"2",nm:"ABBEY DR",w:"8",p:"4"},
{no:"3",nm:"ABBEY DR",w:"8",p:"4"},
{no:"4",nm:"ABBEY DR",w:"8",p:"4"},
{no:"5",nm:"ABBEY DR",w:"8",p:"4"},
{no:"6",nm:"ABBEY DR",w:"8",p:"4"},
{no:"7",nm:"ABBEY DR",w:"8",p:"4"},
{no:"9",nm:"ABBEY DR",w:"8",p:"4"},
.
.
{no:"11",nm:"YOUNG ST",w:"4",p:"4"},
{no:"12",nm:"YOUNG ST",w:"4",p:"4"},
{no:"14",nm:"YOUNG ST",w:"4",p:"4"},
{no:"15",nm:"YOUNG ST",w:"4",p:"4"},
{no:"17",nm:"YOUNG ST",w:"4",p:"4"},
{no:"19",nm:"YOUNG ST",w:"4",p:"4"},
{no:"21",nm:"YOUNG ST",w:"4",p:"4"},
]
)

For every street address there’s a street number, a street name, a ward and a poll.

Next, I created a simple form in HTML, along with a table to hold the results:

<form id="search_form">
    <input type="text" size="5" name="street_no" id="street_no">
    <input type="text" size="15" name="street_nm" id="street_nm">
    <input type="button" id="search_button" value="Search">
</form>
<table id="results_table"></table>

I then scripted together the search, first by including the data, which I saved in a file called charlottetown.js and, second, by using some jQuery goodness to bind a click on the Search button with the actual search:

<script src="https://ruk.ca/jquery-1.4.2.min.js"></script>
<script src="https://ruk.ca/taffydb/taffy.js"></script>
<script src="https://ruk.ca/charlottetown.js"></script>

<script>
$(document).ready(function() {
     $("#search_button").bind('click', function() {
         findAddress();
     });
});
</script>

The heavy lifting of the search is done by that findAddress() function, which looks like this:

<script>
function findAddress() {
   
    search_nm = $("#street_nm").val();
    search_nm = search_nm.toUpperCase();

    results = (addresses.get(
              {
                  nm:{startswith:search_nm},
                  no:{is:$("#street_no").val()}
              }
              ));

    $.each(results, function(index, value) {
        $("#results_wrapper tr:last").after(
            "<tr><td>" + value.no + " " + value.nm + "</td>" +      
            "<td>" + value.w + "</td>" +
            "<td>" + value.p + "</td></tr>");
    });
}
</script>

Put all together, and wrapped in some CSS goodness, some error checking added, and some additional events bound to the search (like press enter in the “street name” field) and the end result looks like this:

Poll Lookup Screen Shot

Performance is fantastic: I created one script for each municipality, simply plugging in a different data file to each one; the largest was Charlottetown, with just over 12,000 addresses and search results are returned instantaneously.

I can put the scripts and data onto a memory key or CD and easily “install” it on each of the laptops with a simply copy. Other than ensuring that there’s a modern browser running on each one, that’s all that needs to be done.

If you vote at one of the Advance Polls, look out for the application in operation when you come in the front door.

Comments

Oliver's picture
Oliver on October 13, 2010 - 19:28 Permalink

I’d be interested to understand the chains of custody of the votes and the intermediate totals, along with who’s tallying them, how and with what vulnerabilities to meddling or corruption, if any, at each stage of the count along the way to the grand tally, and on what basis it’s to be certified. You’re talking about stuff that relates directly to such concerns, right? I can’t make as much sense of it as I’d like.

Peter Rukavina's picture
Peter Rukavina on October 13, 2010 - 20:00 Permalink

The script I created is only designed to route electors to the proper poll; it plays no role in the actual balloting after that point.


You’ll find some useful reference information regarding Provincial General Elections, which are similar in their conduct, at:


<ul>
<li>Polling Days and Polling Places</li>
<li>Ballot Count</li>
<li>Election Personnel</li>
</ul>

&#160

AG's picture
AG on September 4, 2014 - 16:12 Permalink

Hi:
Interesting idea!

Do you a zipped version of what you've described in this article?
I'd like to see how it behaves in my XAMPP / local Apache install.

Appreciate a reply.