Photo Corners

A   S C R A P B O O K   O F   S O L U T I O N S   F O R   T H E   P H O T O G R A P H E R

Enhancing the enjoyment of taking pictures with news that matters, features that entertain and images that delight. Published frequently.

Site Tweak: Polls Share This on LinkedIn   Share This on Google   Tweet This   Forward This

29 September 2015

We just hate to bother you. Really. So we just don't. How's that for a solution? Yeah, we thought you'd like it. No "but."

Nevertheless (which, you have to admit, is a bit grander than any "but" you've ever suffered), we realize that sometimes you may want to fling some quick feedback our way without sending an email and getting tangled in a charming, enlightening and amusing exchange.

A Sample Poll

Do you always avoid voting in online polls?

Decline to State

NB: Results will be displayed after you vote.

Sample Poll. A working example of our new poll feature. Give it try!

Actually, the real motivation for our latest site tweak was something a lot less altruistic.

We had taken some photos and processed them several ways, each with a slight deficiency, and wondered which one would be least annoying. After all, we just hate to bother you.

That called for a vote. Which called for a poll. Our first (in which you can still vote).


Not just any poll, though. We had some user interface specifications:

  • Three exclusive options. Pick just one of them.
  • Just one click to vote, not two (a vote and a Submit button)
  • No redrawing of the whole page (embed the poll in the page)
  • Immediately report the updated results without any more clicking
  • Nice but simple (and synced) graphic layout

And we had some technical specifications:

  • Retain a record of the votes without getting all databasey
  • Only one vote per customer (more or less)
  • Report just percentages (which is all we were interested in)
  • Play nice on mobile devices as well as the desktop

Each of those requirements had consequences that narrowed our technology choices down a bit. But we remained free to pick a language or approach.


That's simply because we built our content management system on a lower level than, say, WordPress or Drupal. We don't have to live within their national boundaries speaking their language. We don't even have to live within jQuery's boundaries.

The basic design for our poll was this:

  • Establish a div for the poll and its data
  • Display the ballot in the div when the page is loaded
  • Use a form with radio buttons to make a single choice
  • Watch for a click on any radio button with JavaScript
  • Send the choice to a short CGI program for processing
  • Process and store the data in the short CGI program (which evolved through the night)
  • Immediately redraw the ballot with the results

To prepare ourselves to dive into this project, we stretched out on the couch and watched A Month by the Lake, a 1995 romantic comedy starring Vanessa Redgrave, Edward Fox and Uma Thurman. Directed by John Irvin, it's based on the novel by H.E. Bates. And great fun.

There's nothing like taking your mind off a problem before trying to solve it. Because, you know, things tend to look different when you see them a second time.


But before we rolled off the couch, we realized what we needed would be some asynchronous JavaScript to define the ballot area as a div and write to it, which we could put in the page header. It would also have to send the form data from the ballot to our CGI script.

This is pretty standard stuff, available from your favorite code resource. We just had to find it. It's always right under the Return key.

Then we needed a CGI script.

We thought about writing this in Perl but decided to write it in PHP. We really didn't think we had to trouble with AngularJS to do this. PHP did just fine.

So two simple pieces of code and we'd have a model poll we could use whenever a vote would be required.


We've established a certain graphic style for Photo Corners so it was easy to say what the poll should look like.

The key to the layout was to anchor the ballot options/graph labels in exactly the same spot.

It should have a tint of our highlight teal color as a background and would need the teal color as a border to help draw attention to it. We gave it a rather thick border. To distinguish it from similar graphics on the site (our sponsored links, for example), we rounded the corners. Which is also a bit more inviting.

We dropped a headline in and then thought about the text.

The initial display would require three options with radio buttons. But it would immediately be redrawn with a bar graph of the results. The bar graph would consist of the same labels as the ballot, a teal bar and a numeric percentage.

The key to the layout was to anchor the ballot options/graph labels in exactly the same spot. So after you click on a radio button, it disappears and the bar graph appears immediately on the other side of the label, showing you the results. (And, we thought later, rewriting the headline.)

You could do that with CSS or tables. To keep things simple, we used tables.

We had to figure out how to present the numeric percentage. We thought about adding another column to our table, but that would be fairly far from the label and bar. So we simply wrote it over the bar in white.

That had a drawback (the bar might not be long enough to reveal the reversed type completely) but we thought it was worth it.

To draw the bars, we used a div with our teal highlight color as the background color, setting the width property based on the votes. The CGI script would calculate that.


We wrote two variations of our CGI script. The working version on the page we wrote this for only allows you to vote once (but you can see the results any time). A second version, on this page, lets you vote as many times as you want (because it's just a demo) and tells you how many times you voted.

The first job of either CGI script was to read the vote passed to it by the form.

At the same time, an environment variable with your IP address is available, associating your vote with you so the vote isn't some unattached number floating around. It's a vote.

The script compares your IP address to all the previous IP addresses that have voted to make sure you haven't voted before it counts this vote.

We thought about letting you vote for more than one option in the working CGI, but in the end we felt that was like giving you extra votes compared to someone who only votes for one (and whose vote we can't multiple to level the field).

You aren't penalized for trying though. If you reload the page and try to vote again, you simply see the results with a note that you've already voted. Since this is tied to your IP address, going to a different device to vote again won't fly either.

Of course, to find out what the results are you do have to vote. Not much of a price to pay, we think.

Knowing whether you've already voted or not helps determine what the CGI script does. If you haven't recorded a vote, it adds your vote to the total (which it has recorded elsewhere) and records it.

Then it formats the bar graph and sends it back to the page for display. Instantly.


A few days after we published the original story with the working CGI, we simplified the code a bit. And we pulled the JavaScript out of the header into an include file to make it easier to use more than once (we know where it is now).

Meanwhile, can reader surveys be far behind? Well, we do hate to bother you.

BackBack to Photo Corners