Form validation made super easy with jQuery

We spend a lot of time coding both client and server-side form valdilation.

This is the routine I now always use for client-side validation, which has been refined over the years to become what I’d consider to be some pretty tight code, whilst providing good quality feedback to the user to help them complete forms quickly and with minimal confusion.

Hopefully you can learn a trick or two that you can use yourself, by looking at the code…

[code lang=”javascript”]
function errorBefore(error, $insertBefore) {
$(‘<p class="error">’ + error + ‘</p>’).insertBefore($insertBefore);
}

$(function () {

$("#my-form").submit(function (e) {

// remove any errors from previous form submission
$(‘.error’, $(this)).remove();

// get jQuery reference to form fields
var $name = $(‘#name’);
var $email = $(‘#email’);

// validate name input
if (!$name.val()) {
errorBefore(‘Please enter your name.’, $name);
}

// validate email input
if (!$email.val()) {
errorBefore(‘Please enter your email.’, $email);
}

// check for errors
if ($(‘.error’, $(this)).length) {

// find first error and focus on form field it relates to
$(‘.error’, $(this)).first().next(‘input, select, textarea’).focus();

// stop form submission
e.preventDefault();
}

});

});
[/code]

Reverse Geocoding for iOS using the t2a.co API

In this tutorial, we’ll be creating a simple iPhone app capable of reverse geocoding – the process of finding the nearest address from a set of location coordinates. In this case, our location coordinates represent the user’s current location and will be provided natively by the CoreLocation framework (more on this in a bit).

On route we’ll learn how to make requests to a web service using NSURLConnection and how to process the JSON response we get back from it, using SBJson (a JSON parsing framework) which is available at github.com/stig/json-framework.

Open Xcode (I’m using version 4.2 but instructions shouldn’t vary too much for earlier/later versions) and create a new Xcode project. Choose Single View Application as the template for your new project and name your product something appropriate. Leave the 3 checkboxes unchecked and click next and then create in the following dialog.

Grab the Frameworks etc

(Note: There are more detailed instructions on the respective github pages telling you how to successfully get the frameworks into Xcode if you get stuck with either of these steps).

Head over to github.com/stig/json-framework and download the latest .ZIP file. Open up the .ZIP and select all the files in the Classes folder then drag them into your project, creating a new group for them to keep things tidy.

We’re also going to use a lovely, easy to use, loading indicator which you can find at github.com/jdg/MBProgressHUD. Create another new group and drag the MBProgressHUD.h and MBProgressHUD.m files into it.

Lastly – We need to add the CoreLocation framework to our project. In the project navigator, select your project – Select your target and then the ‘Build Phases’ tab. Open the ‘Link Binaries with Libraries’ expander and click the ‘+’ button. Search for the CoreLocation framework and click ‘Add’.

The User Interface

Open up your .xib file and drag on a Label and a button, then open up your view controller’s header file and add an IBOutlet for your label and an IBAction for your button.

[sourcecode language=”objc”]

@interface ViewController : UIViewController {

UILabel *addressLabel;

}

@property (nonatomic, retain) IBOutlet UILabel *addressLabel;

-(IBAction) buttonClick;

@end

[/sourcecode]

Go back to the Interface Builder for your .xib file, right click the File’s Owner icon (the semi-transparent yellow box to the left of the editing area). Drag the addressLabel outlet onto your label and the buttonClick received action onto your button, selecting touch up inside as the type of interaction.

Back to the Header File

We need to add a few things in our header file before we can get on with coding the beefy bits of our application. Shortly but sweetly:

  • Import the CoreLocation and MBProgressHUD.h header files.
  • Have your view controller implement the CLLocationManagerDelegate delegate.
  • Add instance variables for responseData (NSMutableData), locationManager (CLLocationManager), currentLat (CLLocationDegrees), currentLon (CLLocationDegrees) and HUD (MBProgressHUD).

Your finished header file should look like this:

[sourcecode language=”objc”]

#import ;
#import ;
#import "MBProgressHUD.h"

@interface ViewController : UIViewController {

NSMutableData *responseData;

CLLocationManager *locationManager;

CLLocationDegrees currentLat;

CLLocationDegrees currentLon;

UILabel *addressLabel;

MBProgressHUD *HUD;

}

@property (nonatomic, retain) IBOutlet UILabel *addressLabel;

-(IBAction) buttonClick;

@end

[/sourcecode]

The Beef Of The Code

Include the SBJson.h header file in your implementation file, and synthesize the addressLabel property we created earlier.

SQL, NULL and the 42nd President

Virtually anyone who has written a SQL query will have encountered NULL column items. All of the text books repeat the same sermon:-

NULL is not equal to anything, not even itself.

..which of course means that if a field is not set (i.e. is NULL) it will be ignored by a query such as:-


select name,'good' from player where score >= 60
UNION ALL
select name,'poor' from player where score < 60 ;

At first glance the above query would appear to return all players, poor and good. If however a player’s score value is not set, the query will not return that player. If the query is modified thus:-

select name,'good' from player where score >= 60
UNION ALL
select name,'poor' from player where score < 60
UNION ALL
select name,'unknown' from player where score is NULL
;

..all players are returned. Note the use of IS NULL to ensure that rows with an undefined score are returned.

Name Rating
Jason good
Phineas poor
Medea unknown

However it is also in a sense correct to say:-

NULL is not not equal to anything

Confused?

Consider the following simple table, holding the name, year of coming to office, and current status of the President of the United Status (or POTUS):-


CREATE TABLE IF NOT EXISTS `potus` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255),
`year` SMALLINT,
`status` varchar(20),
PRIMARY KEY (`id`)
) ENGINE=innodb DEFAULT CHARSET=utf8;

We then populate the table with the holders of that particular job over the past century:-


insert into potus (name,year,status) VALUES
('Barack Obama', 2009,'current');

insert into potus (name,year,status) VALUES
('George W Bush', 2001,'former');

insert into potus (name,year) VALUES
('Bill Clinton', 1993);

insert into potus (name,year,status) VALUES
('George H Bush', 1989,'former');

insert into potus (name,year,status) VALUES
('Ronald Reagan', 1981,'deceased');

insert into potus (name,year,status) VALUES
('Jimmy Carter', 1977,'former');

insert into potus (name,year,status) VALUES
('Gerald Ford', 1974,'deceased');

insert into potus (name,year,status) VALUES
('Richard Nixon', 1969,'deceased');

insert into potus (name,year,status) VALUES
('Lyndon Johnson', 1963,'deceased');

insert into potus (name,year,status) VALUES
('John Kennedy', 1961,'deceased');

insert into potus (name,year,status) VALUES
('Dwight Eisenhower', 1953,'deceased');

insert into potus (name,year,status) VALUES
('Harry S Truman', 1945,'deceased');

insert into potus (name,year,status) VALUES
('Franklin Roosevelt',1933,'deceased');

insert into potus (name,year,status) VALUES
('Herbert Hoover', 1929,'deceased');

insert into potus (name,year,status) VALUES
('Calvin Coolidge', 1923,'deceased');

insert into potus (name,year,status) VALUES
('Warren Harding', 1921,'deceased');

insert into potus (name,year,status) VALUES
('Woodrow Wilson', 1913,'deceased');

Keen observers will note that an error was made when inserting the 42nd President, a Mr Clinton; his current status was not inserted into the table, and is thus NULL.

The following query thus, as you would expect, fails to return Mr Clinton, given that his status is not equal to ‘current’ or ‘former’:-


select name from potus where status IN ('current','former');

However you may think that this query, to return all presidents who are not deceased, would return Mr Clinton:-


select name, year from potus
where status !='deceased'
order by year desc
;

… but it does not. Mr Clinton’s status is NULL, and so it is not not equal to ‘deceased’.
NULL will not work with any regular comparitor (equals, not equals, less than etc).

The query produces:-

Name Year
Barack Obama 2009
George W Bush 2001
George H Bush 1989
Jimmy Carter 1977

The following query returns any live presidents, plus any whose health is undefined:-


select name,year from potus where
(status !='deceased' or status is NULL)
order by year desc
;

Name Year
Barack Obama 2009
George W Bush 2001
Bill Clinton 1993
George H Bush 1989
Jimmy Carter 1977

No more undefined index using PHP’s $_GET and $_POST

It’s very annoying having to check whether $_GET['somevalue'] is set before checking its value – but if you don’t, your code is going to throw a a lot of Notice: Undefined index warnings and that’s never good.

I’ve written a quick class to make every PHP developer’s life a bit easier. It’s based on CodeIgniter‘s $this->input class. You can use it as follows and never have to worry about whether the index exists or not… It will just get set to NULL if it doesn’t.

[code lang=”php”]
class Input {
function get($name) {
return isset($_GET[$name]) ? $_GET[$name] : null;
}

function post($name) {
return isset($_POST[$name]) ? $_POST[$name] : null;
}

function get_post($name) {
return $this->get($name) ? $this->get($name) : $this->post($name);
}
}
$input = new Input;

$page = $input->get(‘page’); // // look in $_GET
$page = $input->post(‘page’); // // look in $_POST
$page = $input->get_post(‘page’); // look in both $_GET and $_POST

[/code]

MD5 C++ Class

Introduction

The MD5 algorithm produces a 128 bit hash of a byte array (often text).

Don’t Use MD5

MD5 is now considered a “broken” hash and should now no longer be used in high security situations.

OK, If You Must Use MD5…

If you still wish to use MD5, for example to hash user passwords, always add a salt before hashing, to prevent a dictionary attack.

The MD5 class was derived from various C++ examples. The class is thread safe (an instance must be created for each thread) and uses no memory allocation.

In the MD5.h file, note the definition of an unsigned 32 bit integer; you may need to modify this.

typedef unsigned int MD5_UINT32;

There are 6 public functions, all named Compute, in two groups:-

  • to return the MD5 hash as an ASCII (8 bit) string
  • to return the MD5 hash as a wide (UTF-16) string

For each type above there is a Compute function that accepts a “wide” (UTF-16) string; there is an optional parameter to specify if the string should be converted to UTF-8 before hashing. If the string is known to be 8-bit (Unicode 0xff or less), set this to the default “false”.

Use the CMD5 class (files MD5.cpp and MD5.h). The CMD5 class also uses the CUnicode class (file Unicode.h) which has a single static public function.

To use, create an instance of CMD5. Do not share that instance with other threads. Creation of the instance on the stack is recommended. Each public method returns an “unsafe” pointer to either an ASCII or UTF-16 string which is contained in the class instance and is only safe to be used whilst the class remains in scope, or before it is deleted or re-used.

The classes may be downloaded here (6.1Kb zip).

The code below demonstrates the use of all 6 public functions.

[sourcecode language=”cpp”]

#include "md5.h"

//create an instance of MD5 on the stack
//which we will re-use for each example
CMD5 mx;

unsigned char test_array[5] = { 1, 2, 3, 5, 7 };

const wchar_t* res1 = mx.Compute("test string");
//
// res1 is safe to use until mx is re-used
// normally this would be copied to a safe location
// or used immediately
//

// version using ‘wide’ source string. Specify whether to
// convert the string to utf-8
// (needed if any characters above u+ff are present)
const wchar_t* res2 = mx.Compute(L"test string", false);
// version using byte array
const wchar_t* res3 = mx.Compute(test_array,5);

//methods returning 8 bit string MD5
const char* res4 = mx.Compute_8("test string");
const char* res5 = mx.Compute_8(L"test string", false);
const char* res6 = mx.Compute_8(test_array, 5);

[/sourcecode]