Category Archives: Code Snippets

Very simple PHP calendar

Many of the calendar scripts out there are un-necessarily complicated & weighty.

If you want a tiny calendar script that is easy to understand and can be adapted to a variety of purposes, here’s one we wrote for our Doozy CMS that might be a good starting point for you.

The PHP:

Usage: echo calendar(10, 2014); // month, year[, timezone] (enter the timezone using standard PHP timezone strings)

function calendar($m, $y, $timezone = 'Pacific/Auckland') { // set your default timezone here
  $date = new DateTime('now', new DateTimeZone($timezone));
  $today = array('d' => $date->format('d'), 'm' => $date->format('m'), 'y' => $date->format('Y'));
  $date->setDate($y, $m, 1);
    $calendar = '
    <table class="calendar"><tr class="month-heading"><th><a class="prev" href="?m='.$date->modify('-1 month')->format('n').'&amp;y='.$date->format('Y').'">&#9664;</a></th><th colspan="5" class="big">' . $date->modify('+1 month')->format('F Y') . '</th><th><a class="next" href="?m='.$date->modify('+1 month')->format('n').'&amp;y='.$date->format('Y').'">&#9654;</a></th></tr>
    <tr class="week-heading"><th>Sun</th><th>Mon</th><th>Tue</th><th>Wed</th><th>Thu</th><th>Fri</th><th>Sat</th></tr><tr>
    ';
    $month = array('this_month_start_dow' => $date->modify('-1 month')->format('w'), 'this_month_days' => $date->format('t'), 'prev_month_days' => $date->modify('-1 month')->format('t'));
  $days_arr = array();
  $day_ctr = -1;

  // previous month
  if ($month['this_month_start_dow'] > 0) {
    for ($i = $month['this_month_start_dow'] - 1; $i >= 0; $i--) {
      $day_ctr += 1;
      $class = ($day_ctr % 7 == 0 || $day_ctr % 7 == 6) ? 'weekend-day other-month' : 'other-month'; // Sat/Sun
      $days_arr[] = '<td class="' . $class . '">' . ($month['prev_month_days'] - $i) . '</td>';
    }
  }

  // current month
  for ($i = 1; $i <= $month['this_month_days']; $i++) {
    $day_ctr += 1;
    $class = ($day_ctr % 7 == 0 || $day_ctr % 7 == 6) ? 'weekend-day' : ''; // Sat/Sun
    $class .= ($i == $today['d'] && $m == $today['m'] && $y == $today['y']) ? ' today' : ''; // today
    $days_arr[] = '<td class="' . $class . '">' . $i . '</td>';
  }

  // next month
  if (count($days_arr) % 7 != 0) {
    for ($i = 1; $i <= count($days_arr) % 7; $i++) {
      $day_ctr += 1;
      $class = ($day_ctr % 7 == 0 || $day_ctr % 7 == 6) ? 'weekend-day other-month' : 'other-month'; // Sat/Sun
      $days_arr[] = '<td class="' . $class . '">' . $i . '</td>';
    }
  }

  // create the grid
  foreach ($days_arr as $k => $day) {
    $calendar .= (($k) % 7 == 0 ? '</tr><tr>' : '') . $day;
  }

  $calendar .= '</tr></table>';
  return $calendar;
}

Add a bit of CSS

<style>
  .calendar {width:220px;background:#fdfdfd;font:14px arial; color:#644; border:1px solid #dcdcdc; border-collapse:collapse;}
  .month-heading {text-align:center; height:28px; line-height:28px; background:#b53934; color: #fff;}
  .big {font-size:120%;}
  .week-heading {font-size:11px; height:20px; line-height:20px; background:#e6e7ec; text-align:center;}
  td {width:14.2857%;text-align:right;padding:4px!important; border:1px solid #dcdcdc;}
  .other-month {color: #dcdcdc;}
  .weekend-day {background:#fafafa;}
  .today {background:#a6daf0;}
</style>

And there you have it – an easy to use, flexible and customisable calendar. Using the above css should result in something that looks like this:

calendar

Many other options can be easily added, for example in our Doozy CMS events module we include clickable links on days that have events along with an optional summary of events for the selected month below the calendar.

Hope it’s of use to you…

Fixed Decimal Places With Last Digit Rounding Down

As a programmer or designer, sometimes you need to set a fixed number of decimal places on dynamically generated numbers.

Take the example of dividing a page element into six equal columns and let’s round the column width as a precentage to four decimal places. Pretty easy – the width of each column is 100 / 6 = 16.6667%. You can then assign the width to each of the columns with the CSS declaration of ‘width : 16.6667%;’

Houston, we have a problem.

According to my trusty Casio fx-82, 16.6667 x 6 = 100.0002. This will result in a broken layout as the total width of all the columns is greater than 100%.

You could fix this with overflow-x : hidden;, but this is a hack and may have other repercussions, and in my view it’s usually better to attack the cause of the problem, not try and hide the symptom.

Here’s a simple way to fix the problem – always round down the final digit instead of allowing it to round up like in the case of this example. In this example, 6 x 16.6666% = 99.9996% which will appear as 100% for all intents and purposes and will not break your layout.

The following javascript snippet shows an easy way to do this (using four decimal places):

var percentage_array = [];
var num = 6;
for (i = 1; i <= num; i++){
  percentage_array.push((Math.floor(100/num * i * 10000)/10000).toFixed(4)); // truncates to 4 decimal places with the last place always rounded down instead of possibly up
}
// do useful stuff with your 16.6666 values...

Very Simple jQuery UI Resizable Columns Technique

There are plenty of plugins that allow you to resize table columns while maintaining the same overall table width, however sometimes it would be useful to be able to do this with block elements such as divs, sections and so on.

The following is a stripped down version of what we use for creating page layouts in our Doozy CMS – this snippet is only intended as a very simple example and isn’t responsive, is pixel based and doesn’t use HTML 5 semantic elements. It requires jQuery and jQuery UI (resizable) so you’ll need to include those libraries to make it work.

Using this technique, you can:

  • Have any number of resizable columns in the containing element
  • Specify minimum and maximum column widths
  • Make columns snap to predefined widths when resizing

A little CSS…

  .container {width:960px; margin:100px auto;}
  .column {height:300px; float:left; margin:0;}
  .column-1 {background: #f8f8f6; width: 640px;}
  .column-2 {background: #e8e7e2; width: 320px}

 A bit of HTML…

<div class="container">
  <div class="column column-1"></div>
  <div class="column column-2"></div>
</div>

And some very simple jQuery to finish off.

var tot_width;
var min_width = 160;
jQuery('.container .column:not(:last-child)').resizable({
  grid : 80,
  minWidth : min_width,
  handles : 'e',
  start : function(){
    tot_width = jQuery(this).width() + jQuery(this).next().width();
    jQuery(this).resizable('option', 'maxWidth', (tot_width - min_width));
  },
  resize : function(){
    jQuery(this).next().width(tot_width - jQuery(this).width());
  }
});

And there you have it. Toss in a some PHP and a bit of ajax and this can be very useful indeed…

jQuery UI draggable into multiple sortables with remove

jQuery UI is a useful if somewhat large library and we use it in some of our backend stuff where page load times aren’t quite so important.

One of it’s cool features is the ability to have one or more sortable containers that can have items dropped onto them either from an external draggable element or from another connected sortable container.

But have you ever tried to remove an item from one of a group of connected sortable containers?

This should be a piece of cake to do but unfortunately the sortable over and out events don’t play nicely together at all when you have multiple connected sortable containers. Go and try it for yourself, then come back to see a quick and easy way to do it.

A simple trick I’ve found to solve this problem is to make your sortable containers droppable also, and to use the droppable over and out events. You’ll need the approriate references to the jQuery and jQuery UI libraries & CSS of course.

A few additional lines of code to make the containers droppable will now allow you to:

  • drag and drop external draggable items onto any of the sortable containers
  • drag and drop items between any of the sortable containers
  • completely remove items from all of the sortable containers by dragging and dropping them away from a sortable container (ie anywhere else on the page)

The following code is stripped down to the essentials (although you may or may not need the draggable clone helper depending on your application) and shows how to do this:

var remove_me = false;

$('.your_external_draggable_element').draggable({
  connectToSortable: ".your_sortable_container",
  helper: "clone",
});

$('.your_sortable_container').droppable({
  over: function(){
    remove_me = false;
  },
  out: function(){
    remove_me = true;
  }
}).sortable({
  tolerance: "pointer",
  connectWith: '.your_sortable_container',
  stop: function(event, ui){
    if (remove_me){
      ui.item.remove();
    }
  },
});

Do you know of any simpler or better ways? If so, let us know in the comments…

Very simple CSS/HTML/jQuery numeric spinner control

Here’s a simple numeric spinner control that you might find useful. This is a stripped down verson of a control we created for our soon to be released Doozy CMS. The appearance can easily be altered in the CSS – we’ve used this size & look in many of our other controls for consistency.

In the interests of simplicity, there’s no hover effects, input validation or min/max limits in place in this example but it’s trivial to implement these & I’ll leave it to you to do so.

It uses jQuery simply because we use it for many other features in our applications so you’ll need to include it in any pages that use this control (or change the code to use plain javascript). The jQuery ‘on’ method is used so we can add controls dynamically but isn’t necessary for manually coded controls.

Features

  • Easily customisable
  • Very lightweight
  • Numbers can be manually typed in or incremented / decremented by using the arrow keys on the keyboard or by clicking the up / down buttons

The Finished Control

spinner control

Here’s the code used in this particular example:

The CSS

.spinner {display:inline-block; position:relative; border:1px solid #dcdcdc; border-radius:4px; overflow:hidden;}
.spinner-input {width:46px; margin-right:23px; border:none; padding:0 3px; height:23px; line-height:23px; border-right:1px solid #dcdcdc;}
.spinner-button {text-decoration:none; position:absolute; right:0; background: #efefef; height:11px; line-height:11px; width:23px;}
.spinner-up {top:0;}
.spinner-down{bottom:0; border-top:1px solid #dcdcdc;}

The HTML

<div class="spinner">
  <input class="spinner-input" type="text" />
  <a class="spinner-button spinner-up" href="#">▴</a>
  <a class="spinner-button spinner-down" href="#">▾</a>
</div>

The jQuery

$(document).on('keydown', '.spinner-input', function(e){
  if (e.which == 38) { // up-arrow
    $(this).val((parseInt($(this).val()) + 1)); // parseInt used as we want to increment, not concatenate
  } else if (e.which == 40) { // down-arrow
    $(this).val((parseInt($(this).val()) - 1));
  }
});
		
$(document).on('click', '.spinner-button', function(){
  var target = $(this).siblings(':first');
  if ($(this).hasClass('spinner-up')){
    $(target).val((parseInt($(target).val()) + 1));
  }else{
    $(target).val((parseInt($(target).val()) - 1));
  }
  return false;
});

Loading jQuery and other libraries from Google’s CDN with local fallback

It is generally preferable to load commonly used  libraries such as jQuery from the Google CDN as it is likely that the client browser will already have a cached copy from that source, thus reducing page load time and bandwidth. Even if there isn’t a cached copy, the library will load faster from Google’s servers than from the website’s server.

The code snippets below attempt to load a minified version of jQuery from Google Hosted Libraries, and if this fails for any reason, will fall back to loading it from the website’s server. Version 2.1.0 is used in this example but the majority of released versions are available on the CDN. Version information can be obtained at https://developers.google.com/speed/libraries/devguide#jquery.

LIBRARIES_URL / libraries_url is the absolute url to your libraries directory including a following slash and is assumed to have been previously defined in PHP in the first example, or as a javascript variable in the second.

PHP:

echo '
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<script>window.jQuery || document.write(\'<script src="' . LIBRARIES_URL . 'jquery/jquery-2.1.0.min.js">\x3C/script>\')</script>
';

HTML/Javascript:

<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<script>window.jQuery || document.write(\'<script src="' + libraries_url + 'jquery/jquery-1.7.2.min.js">\x3C/script>\')</script>

Libraries currently hosted by Google include:

  • AngularJ
  • Dojo
  • Ext Core
  • jQuery
  • jQuery Mobile
  • jQuery UI
  • MooTools
  • Prototype
  • script_aculo_us
  • SWFObject
  • three.js
  • Web Font Loader

More information can be obtained at https://developers.google.com/speed/libraries/devguide.

CSS Reset

Our current implementation, based on Eric Meyer’s reset at http://meyerweb.com/eric/tools/css/reset/

/* *** Reset *** */
html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}

/* HTML 5 Elements */
article, aside, details, figcaption, figure, footer, header, hgroup, main, menu, nav, section, summary {
display: block;
}

audio, canvas, video {
display: inline-block;
}

audio:not([controls]) {
display: none;
height: 0;
}