Category Archives: Coding Techniques

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…

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;
});

Very quick & dirty way to password protect PHP page content

I definitely don’t recommend using this technique for hiding anything at all sensitive, but if you have a situation where you want certain content to be available or presented in a certain way to people who have a password but not the general public, this one line of code will do the trick:

<?php
$hidden_stuff = 'This could be text, data obtained from a database or whatever else you like or simply used to format the page in a certain way...';

echo (strpos($_SERVER['QUERY_STRING'], 'sneakypassword') !== false ? '<p>' . $hidden_stuff . '</p>' : '<p>Stuff that anybody can see.</p>');

People who are allowed to view the hidden content don’t need to log in – all they need to do is add the password to the URL as a querystring.

eg: http://yoursite.com/pagewithhiddenstuff.php?sneakypassword

There are plenty of good reasons not to do this:

  • The password is visible in the URL so can be seen by others nearby
  • It is more susceptable to brute force password attacks than a posted password
  • The password will be bookmarked if the page is
  • The password will be cached or logged if the page is

On the other hand, it can have it’s uses. I personally use this exact technique for dummy lorem ipsum text generation for website testing. I have a page that generates random words in a format suitable for pasting straight into a visual text editor, if I add a ?p to the url, it wraps the paragraphs in <p> elements, if I add ?ul or ?ol it outputs it as an unordered or ordered list.

I may post the code for this in a future post.

 

Need to reduce your HTML file size?

If you need to reduce the file size of HTML documents there are a number of element tags that can be removed under certain conditions.

While each tag doesn’t add much to the file size, the total size of all un-necessary tags could add up to a significant amount so omitting them could be worth considering if you’re trying to reduce file sizes to their absolute minimums.

The elements that can have tags omitted are in the following table and detailed info is available at https://html.spec.whatwg.org/multipage/syntax.html#syntax-tag-omission.

Element Tag Can be omitted if
html start the first thing inside the html element is not a comment
html end the html element is not immediately followed by a comment
head start the element is empty or if the first thing inside the head element is an element
head end the head element is not immediately followed by a space character or a comment
body start the element is empty, or if the first thing inside the body element is not a space character or a comment, except if the first thing inside the body element is a meta, link, script, style, or template element
body end the body element is not immediately followed by a comment
li end the li element is immediately followed by another li element or if there is no more content in the parent element
dt end the dt element is immediately followed by another dt element or a dd element
dd end the dd element is immediately followed by another dd element or a dt element, or if there is no more content in the parent element
p end the p element is immediately followed by an address, article, aside, blockquote, div, dl, fieldset, footer, form, h1, h2, h3, h4, h5, h6, header, hgroup, hr, main, menu, nav, ol, p, pre, section, table, or ul, element, or if there is no more content in the parent element and the parent element is not an a element
rt end the rt element is immediately followed by an rt or rp element, or if there is no more content in the parent element
rp end the rp element is immediately followed by an rt or rp element, or if there is no more content in the parent element
optgroup end the optgroup element is immediately followed by another optgroup element, or if there is no more content in the parent element
option end the option element is immediately followed by another option element, or if it is immediately followed by an optgroup element, or if there is no more content in the parent element
colgroup start The colgroup element is not empty, and if the first thing inside the colgroup element is a col element, and if the element is not immediately preceded by another colgroup element whose end tag has been omitted.
colgroup end the colgroup element is not immediately followed by a space character or a comment
caption end the caption element is not immediately followed by a space character or a comment
thead end the thead element is immediately followed by a tbody or tfoot element
tbody start The tbody element is not empty, and if the first thing inside the tbody element is a tr element, and if the element is not immediately preceded by a tbody, thead, or tfoot element whose end tag has been omitted.
tbody end the tbody element is immediately followed by a tbody or tfoot element, or if there is no more content in the parent element
tfoot end the tfoot element is immediately followed by a tbody element, or if there is no more content in the parent element
tr end the tr element is immediately followed by another tr element, or if there is no more content in the parent element
td end the td element is immediately followed by a td or th element, or if there is no more content in the parent element
th end the th element is immediately followed by a td or th element, or if there is no more content in the parent element