Impressive Webs http://www.impressivewebs.com Web Design Articles & Tutorials. To make the web impressive. Fri, 31 Oct 2014 20:05:35 +0000 en-US hourly 1 http://wordpress.org/?v=4.0 Background Reveal Scroll In Pure CSS http://www.impressivewebs.com/background-reveal-scroll-in-pure-css/ http://www.impressivewebs.com/background-reveal-scroll-in-pure-css/#comments Fri, 31 Oct 2014 20:05:35 +0000 http://www.impressivewebs.com/?p=13856

No related posts.

]]>
http://www.impressivewebs.com/background-reveal-scroll-in-pure-css/feed/ 0
Getting Nowhere with CSS Best Practices (Slides) http://www.impressivewebs.com/getting-nowhere-with-css-best-practices-slides/ http://www.impressivewebs.com/getting-nowhere-with-css-best-practices-slides/#comments Thu, 30 Oct 2014 21:37:15 +0000 http://www.impressivewebs.com/?p=13852

Related posts:

  1. My Talk and Slides from jQueryTO

]]>
http://www.impressivewebs.com/getting-nowhere-with-css-best-practices-slides/feed/ 0
HTTP 203: CSS Triggers (Video) http://www.impressivewebs.com/http-203-css-triggers-video/ http://www.impressivewebs.com/http-203-css-triggers-video/#comments Thu, 30 Oct 2014 21:33:26 +0000 http://www.impressivewebs.com/?p=13850

No related posts.

]]>
http://www.impressivewebs.com/http-203-css-triggers-video/feed/ 0
Axiomatic CSS and Lobotomized Owls http://www.impressivewebs.com/axiomatic-css-and-lobotomized-owls/ http://www.impressivewebs.com/axiomatic-css-and-lobotomized-owls/#comments Wed, 22 Oct 2014 15:33:00 +0000 http://www.impressivewebs.com/?p=13821

No related posts.

]]>
http://www.impressivewebs.com/axiomatic-css-and-lobotomized-owls/feed/ 0
Displaying Your MailChimp Subscriber Count with PHP and MailChimp’s API http://www.impressivewebs.com/displaying-mailchimp-subscriber-count-php-mailchimp-api/ http://www.impressivewebs.com/displaying-mailchimp-subscriber-count-php-mailchimp-api/#comments Wed, 22 Oct 2014 12:14:41 +0000 http://www.impressivewebs.com/?p=13809 MailChimp logoAs many of you probably know, I’ve been writing a weekly newsletter called Web Tools Weekly for over a year now. Most issues begin with a brief JavaScript tutorial, after which I include a curated list of tools primarily focused on front-end development. I’ve released a new issue every week, without a break, since July 2013 and I use MailChimp to produce the mailing (disclosure: previous link has my affiliate ID attached, which means we both get $30 towards MailChimp if you become a paying customer).

The subscriber count has grown to almost 10,000 as of this writing, and that number is growing by about 70 each week. For the past couple of months, I’ve been displaying the subscriber count on the home page, and manually editing it every once in a while.

]]>
MailChimp logoAs many of you probably know, I’ve been writing a weekly newsletter called Web Tools Weekly for over a year now. Most issues begin with a brief JavaScript tutorial, after which I include a curated list of tools primarily focused on front-end development. I’ve released a new issue every week, without a break, since July 2013 and I use MailChimp to produce the mailing (disclosure: previous link has my affiliate ID attached, which means we both get $30 towards MailChimp if you become a paying customer).

The subscriber count has grown to almost 10,000 as of this writing, and that number is growing by about 70 each week. For the past couple of months, I’ve been displaying the subscriber count on the home page, and manually editing it every once in a while.

Web Tools Weekly subscriber count

Clearly, that’s not an ideal method for doing this sort of thing – especially when MailChimp offers an API that lets you tap into your numbers and do all sorts of other stuff programmatically.

So I did some research on how to get the subscriber count to display automatically on the Web Tools Weekly home page and here’s what I came up with.

MailChimp API by Drew McLellan

The only back-end language I know how to work with on my own is PHP (and I use the phrase “know how to work with” very loosely!). Taking a quick look at MailChimp’s API docs shows that they have listed various API abstraction tools, including some for PHP.

This led me to try out Drew McLellan’s MailChimp API (Drew is the 24 ways guy, in case you’re trying to figure out why you know that name).

Drew’s script is great because it’s simple. It gives you an easy interface into the data available, then you can just mess around with it from there to get what you want.

After including the source file from Drew’s script, I modified it slightly to use my own custom namespace (i.e. I changed “Drewm” to “WTW”) and then I used his example in the docs to instantiate the main object:

include "vendor/MailChimp.php";
$MailChimp = new \WTW\MailChimp('[api key]');
$mc = $MailChimp->call('lists/list');

In that first line, you would replace “[api key]” with your actual API key from MailChimp. You can use this guide from MailChimp to create your key and include it when using Drew’s (or anyone else’s) script.

Once I had the object instantiated, I had no idea what the actual API consists of. So after some fiddling with PHP’s var_dump and print_r, I was able to come up with the following line of PHP to produce the number of subscribers:

$curr_sub_count = $mc[data][0][stats][member_count];

Once I have that, I can display the $curr_sub_count variable anywhere on the page, and this would show an updated subcriber count that I don’t need to manually change every week.

Limiting Calls to the API

At this point, the main problem with this code is the fact that I’m connecting to the API on every page load. MailChimp’s API has some limitations that might cause problems if the Web Tools Weekly website got a traffic spike.

All that I need to do is access the API once per day, record that value somewhere, and then use it in the page as needed. So I Googled around a bit and found this StackOverflow thread. The top-rated answer (not the one that’s checkmarked) produced the following code:

$lastRunLog = 'vendor/lastrun.log';
$subfile = 'vendor/subcount.log';
$lastRun = file_get_contents($lastRunLog);

if (time() - $lastRun >= 86400) {
    // its been more than a day so we can connect to the API
    $MailChimp = new \WTW\MailChimp('[api key]');
    $mc = $MailChimp->call('lists/list');
    $curr_sub_count = $mc[data][0][stats][member_count];
    // update lastrun.log with current time
    file_put_contents($lastRunLog, time());
    file_put_contents($subfile, $curr_sub_count);
} else {
    $curr_sub_count = file_get_contents($subfile);
}

Here’s a summary of what’s happening in that script:

  • The first two lines are referencing log files that I’ve placed on the server inside of a folder called “vendor”. The lastrun.log holds the time the API was last accessed, in a Unix time stamp.
  • The second log file is called subcount.log. This is where I record the subscriber count.
  • Next I grab the contents of the log, then I check to see if it’s been 24 hours since the last time the API was accessed. The number 86400 is used because that’s exactly 24 hours in Unix time, as explained in this thread.
  • If it has been 24 hours since the last API call, we run a new API call to get the new subscriber count, record the current time into lastrun.log, and update the count in subcount.log.
  • If it’s been less than 24 hours, the “else” branch is used, and we simply get the count from the subcount.log file without doing an API call.

In the HTML for the Web Tools Weekly home page, I have a line that looks like this:

<p class="sub">Join <?php echo number_format($curr_sub_count); ?> subscribers!</p>

This uses PHP’s number_format() function to make the count appear with a comma (i.e. “9,478” instead of “9478”).

And that’s it. With this chunk of code in place, I’m ensuring the API is not being unnecessarily queried. If the subscriber count changes only slightly, or not at all, in any given hour, then clearly there’s no need to connect to the API each time the page is visited. Even once a day is probably unnecessary with only about 10 new subscribers per day, but I think this is a more reasonable approach.

Other Techniques?

If you have any suggestions for any of the code above or if you have used MailChimp’s API for something similar, but using a different method, I’d love to hear your thoughts.

]]>
http://www.impressivewebs.com/displaying-mailchimp-subscriber-count-php-mailchimp-api/feed/ 3
onchange vs. oninput for Range Sliders http://www.impressivewebs.com/onchange-vs-oninput-for-range-sliders/ http://www.impressivewebs.com/onchange-vs-oninput-for-range-sliders/#comments Tue, 14 Oct 2014 10:00:02 +0000 http://www.impressivewebs.com/?p=13766 Free range eggsA common UI pattern for a range slider is to allow the user to move the slider and display the value of it somewhere on the page, changing the displayed value as the user moves the slider.

I think the expected behaviour in such a case is that the value should display instantly, as the user is moving the slider, rather than the page waiting for the slider to finish moving before the displayed value is updated. I suppose there could be cases where you prefer a delay over instant results, but I think the expected behaviour is to display the results instantly.

As you’ll see in the videos below and in your own testing, the behaviour of the input event compared to the change event is not exactly the same in different browsers when applied to a range slider.

]]>
A common UI pattern for a range slider is to allow the user to move the slider and display the value of it somewhere on the page, changing the displayed value as the user moves the slider.

I think the expected behaviour in such a case is that the value should display instantly, as the user is moving the slider, rather than the page waiting for the slider to finish moving before the displayed value is updated. I suppose there could be cases where you prefer a delay over instant results, but I think the expected behaviour is to display the results instantly.

As you’ll see in the videos below and in your own testing, the behaviour of the input event compared to the change event is not exactly the same in different browsers when applied to a range slider.

Let’s look at how these events behave in the different browsers. The code I’ll be using is embedded in the JS Bin example below:

JS Bin

Swap change with input to see the differences I’ll be discussing. The results described are observed on OSX and Windows 7.

Note: Opera is equivalent to Chrome in these tests because it now has the same rendering engine.

oninput in Chrome

Observations:

  • Works as expected, the input event fires immediately when the slider is adjusted, which is demonstrated by the value changing on the page instantly.
  • Focusing and adjusting the slider with the keyboard has the same result.

onchange in Chrome

Observations:

  • The change event does not fire immediately, demonstrated by the fact that the value on the page does not change until the slider stops moving.
  • Keyboard interaction, however, is the same as oninput, with the value on the page updating immediately.

oninput in Firefox

Observations:

  • Same results as oninput in Chrome; changes happen immediately.
  • Keyboard results the same, changes appear immediately.

onchange in Firefox

Observations:

  • Same results as Chrome; the value doesn’t change on the page until the slider stops moving.
  • When moving the slider with the keyboard, the value does not update until the slider is blurred, or unfocused. This is the only difference from the behaviour in Chrome.

oninput in IE11

Observations:

  • oninput is not recognized at all when used on a range slider. The same event, however, does fire when used on a text input.
  • Although oninput doesn’t fire, the value of the slider is displayed in a native tooltip, which doesn’t happen on the other browsers.
  • The keyboard likewise has no effect on the value and the native tooltip is not displayed.

onchange in IE11

Observations:

  • Works the same way as oninput in Chrome and Firefox; the value changes immediately while the slider is still moving.
  • Keyboard results are the same, the value updates immediately.

What’s the Correct Behaviour?

The WHATWG spec describes the expected behaviour as follows:

The input event fires whenever the user has modified the data of the control. The change event fires when the value is committed, if that makes sense for the control, or else when the control loses focus. In all cases, the input event comes before the corresponding change event (if any).

The same description is found in the W3C version of the spec.

For oninput, Chrome and Firefox have the correct behaviour with both mouse and keyboard interaction. But Firefox seems to have the most accurate behaviour for onchange.

As shown in the quote above, onchange should always fire after oninput, so the fact that Firefox waits for the range slider to lose focus before firing the event (for both mouse and keyboard) seems to be the correct behaviour. Chrome does not wait until the control is unfocused when using the keyboard, but it does so with the mouse.

IE11, of course, is completely wrong on two counts: It doesn’t recognize oninput when applied to a range slider and it responds to onchange as if it was oninput, firing the event immediately instead of waiting until the slider stops moving or loses focus.

As a side point here, the HTML4 spec seemed to define the behaviour a little more clearly:

The onchange event occurs when a control loses the input focus and its value has been modified since gaining focus.

Though when that was written, there was no such thing as type="range" for form inputs.

Sources and Bug Reports

There has been discussion on this behaviour in the bug trackers for the various browsers, and I believe the wording in the spec was updated to be less ambiguous — although I still feel that it’s not 100% clear if Firefox’s keyboard behaviour is the correct one.

Here are some relevant links in addition to the ones provided in the article above:

  • Firefox bug report – Closed as “invalid” since Firefox’s behaviour is correct.
  • IE11 bug report on missing input event, still unresolved.
  • Chrome bug report which I filed myself to see if the different keyboard behaviour can be corrected to agree with Firefox.
  • W3C bug report, which attempts to make the spec less ambiguous.
  • change event on MDN, which explains that “different browsers do not always agree whether a change event should be fired for certain types of interaction.”
]]>
http://www.impressivewebs.com/onchange-vs-oninput-for-range-sliders/feed/ 5
Spacing elements http://www.impressivewebs.com/spacing-elements/ http://www.impressivewebs.com/spacing-elements/#comments Wed, 08 Oct 2014 01:18:48 +0000 http://www.impressivewebs.com/?p=13743

Related posts:

  1. Quick Tip: Use HTML Comments to Indicate Pseudo-elements

]]>
http://www.impressivewebs.com/spacing-elements/feed/ 0
The Role of Utility Classes in Scalable CSS http://www.impressivewebs.com/the-role-of-utility-classes-in-scalable-css/ http://www.impressivewebs.com/the-role-of-utility-classes-in-scalable-css/#comments Mon, 29 Sep 2014 22:51:32 +0000 http://www.impressivewebs.com/?p=13683

No related posts.

]]>
http://www.impressivewebs.com/the-role-of-utility-classes-in-scalable-css/feed/ 0
Used and Abused – CSS Inheritance and Our Misuse of the Cascade http://www.impressivewebs.com/used-and-abused-css-inheritance-and-our-misuse-of-the-cascade/ http://www.impressivewebs.com/used-and-abused-css-inheritance-and-our-misuse-of-the-cascade/#comments Mon, 29 Sep 2014 22:33:51 +0000 http://www.impressivewebs.com/?p=13681

No related posts.

]]>
http://www.impressivewebs.com/used-and-abused-css-inheritance-and-our-misuse-of-the-cascade/feed/ 0
Refining The Way We Structure Our CSS At Trello http://www.impressivewebs.com/refining-the-way-we-structure-our-css-at-trello/ http://www.impressivewebs.com/refining-the-way-we-structure-our-css-at-trello/#comments Wed, 24 Sep 2014 17:13:39 +0000 http://www.impressivewebs.com/?p=13589

No related posts.

]]>
http://www.impressivewebs.com/refining-the-way-we-structure-our-css-at-trello/feed/ 0