I made a mobile game!! Introducing Space Beer Cave

Space Beer Cave

I’m very late posting about this and any readers of my blog (mainly those who I am regularly connected with) will likely already be aware, but I made a game!

In my day job, I’ve been working extensively with the Phaser framework to build a mobile slot game. With my new found knowledge aquired through the game, I wanted to see if it was possible to make a game for Android and iOS in a day. It turns out I could (mostly).

I had a very basic concept for the game. I wanted base the game around mechanics of Flappy Bird ie a basic 1 tap control. This is a proven format for simplicity and enjoyment. I also wanted a retro 8-bit feel with a sci-fi theme. Being a fan of sideways scrollers (and beer) the idea of Space Beer Cave was born.

I started the development of the game on a Sunday, with the laptop on my knees at around 10am in bed, moving to my dining table around lunchtime to continue.

Long story short, after about 10hrs of development (though I’d guess about 40% of this time was spent sourcing and creating the graphics and sound effects) my game was complete and running how I wanted it in my browser and device simulators. Which just left the unknown task of getting it wrapped as an app.

Phaser’s forums are full of talk of Ludei’s Cocoon.js as a common way of packaging HTML5 games and apps into Android and iOS compatible apps so, the following weekend, I set about to make my game an Android app. Though a relatively simple process (and I’m still not exactly sure how I manage to achieve it with SSLing, Zip Aligning and other steps) it took me about 6hrs before I had a .pkg that I could submit to the Play Store. You can download the game to your Android device here.

I’m still to package the game for iOS so iPhone and iPad users will have to wait a while (my excuse at the time was that there wasn’t enough space on my MBA’s 128Gb SSD, though since resetting the machine, I no longer have that excuse).

Performance isn’t as great as I would like it to be. The main culprit for this is the physics applied to the ceiling and floor of the cave. Each of the individual blocks has physics applied to them, where I could get away with just the outer blocks. This is a lot of extra and unnecessary calculating that needs to be done on every update cycle. I will get round to sorting that at some stage 😉

Launching iOS and Android simulators with Node.js

I wanted a script to open iOS and Android device simulators and open their browsers to a URL (my karma.js test URL) so wrote one in node.js, using child_process to execute bash commands to get the job done.

It’s far from perfect and will probably explode if you don’t have devices already installed, but it’s more than suitable for my needs. This is a post for self reference more than anything.

It:

  • Gets the list of all available iOS devices and picks the fourth one in the list (position 3 in the array generated from the text output) (at the time of writing, on my system this is the iPhone 5)
  • Executes the command to load the selected iOS emulator
  • Gets the list of all available Android AVDs (Android Virtual Devices) and selects the first one (unlike iOS devices through xcode, AVDs have to be manually installed in Android Studio so it can be a pain if you don’t have more than 1 set up)
  • Executes the command to load the AVD
  • Starts a loop to check if the AVD has loaded yet – it does this by checking the AVD’s bootanim property. If this is ‘stopped’ we know the device has loaded (I couldn’t find a better way of detecting device load. If anyone has one, please let me know)
  • Once the Android emulator has loaded – we can assume the iOS emulator has also loaded as the AVD always takes much longer to load – we execute the command to unlock the screen on the AVD.
  • We execute the commands to launch the browser to our required URL.
var process 		= require('child_process'),
	url 			= "http://192.168.10.126:9876",
	iosdevice, bootChecker;
 
process.exec('xcrun simctl list', function(error, stdout, stderr){
	var splitRows = stdout.split("\n");
	iosdevice = splitRows[3].split(" (")[0];
	launchIOSDevice();
});
 
process.exec('~/Library/Android/sdk/tools/android list avd', function(error, stdout, stderr){
	var splitRows = stdout.split('\n'),
		deviceObj = {};
	// console.log(splitRows);
	splitRows.forEach(function(row){
		var splitRow = row.split(':');
		deviceObj[splitRow[0].replace(/\s/g, '')] = splitRow[1];
	});
	console.log(deviceObj.Name.replace(/\s/g, ''));
 
	process.exec('~/Library/Android/sdk/tools/emulator -avd ' + deviceObj.Name.replace(/\s/g, ''));
 
	isAndroidEmulatorBooted(function(response){
		if (!response){
			kickOffBootChecker();
		} else {
			unlockAndLoadURL();
		}
	});
 
});
 
function launchIOSDevice(){
	console.log('xcrun instruments -w "'+iosdevice+'"');
	process.exec('xcrun instruments -w "'+iosdevice+'"', function(error, stdout, stderr){})
}
 
function kickOffBootChecker() {
	bootChecker = setInterval(function(){
		isAndroidEmulatorBooted(function(response){});
	},1000);
}
 
function isAndroidEmulatorBooted(callback){
	process.exec('~/Library/Android/sdk/platform-tools/adb shell getprop init.svc.bootanim', function(error, stdout, stderr){
 
		if (stdout.toString().indexOf("stopped")>-1){
			clearInterval(bootChecker);
			unlockAndLoadURL();
			return callback(true);
		} else {
			console.log('loading Android emulator ...');
			return callback(false);
		}
	});
}
 
function unlockAndLoadURL(){
	//unlock the device
	console.log('unlocking the android emulator');
	process.exec('~/Library/Android/sdk/platform-tools/adb shell input keyevent 82');
 
	//gotourl
	console.log('launching the url on android');
	process.exec('~/Library/Android/sdk/platform-tools/adb shell am start -a android.intent.action.VIEW -d ' + url);
 
	console.log('android emulator takes longer to load so we can be sure the ios emu has loaded. launch url there too');
	process.exec('xcrun simctl openurl "'+iosdevice+'" ' + url);
}

Running Karma on iOS and Android Simulators with Appium

At my day job I’ve been tasked with improving our webapp testing strategy. This need came about after a bug was introduced in one of our webapps and not picked up by our current testing process. The bug was related to inconsistencies in the implementation of the Javascript date API between iOS Safari and Android Chrome browsers.

We currently employ a (pretty loose) TDD workflow for our Backbone webapps. Writing our specs with Jasmine and using Grunt as our task runner. This is all integrated into our Jenkins CI. The Jasmin specs are all run though an instance of Phantom in Jenkins via the (one of many) grunt task(s) when we push our code up and release though Jenkins. The build either passes or fails.

From investigating all the various options and frameworks, all signs pointed to Karma. Karma would give us:

  • Seamless integration into our current work flow
  • Immediate feedback – you write a test for a new piece of functionality, hit save and it immediately tells you it’s failed. Write the functionality, hit save and it tells you right away if it passes your test.
  • Testing on multiple real devices

It was a fairly painless process to set Karma up using the official docs and get my tests running on the browsers on my dev environment (Safari, Chrome, Canary, Firefox, Phantom) and there are plenty of resources online for this so I won’t go into this here. What I did have issues with, especially with the lack of resources online, was running my specs on mobile devices.

I came across an iOS launcher plugin that had looked promising to get me going with iOS Safari but it’s not been touched by the developer in a couple of years and after a bit of experimentation discovered that doesn’t appear to work with node versions > 0.10. At the time of writing, I’m working with 0.12.

More research led me to Selenium, a browser automator. From there, I came across Appium which uses the same WebDriver protocol as Selenium but also enables you to automate mobile browsers. Download the Appium desktop app here

To interact with Appium, there is the Karma webdriver launcher (npm install karma-webdriver-launcher).

The idea is pretty simple (but the config is a little fiddly):

  • Make sure you have xcode with iOS simulator installed and the Android Development Studio with at least 1 AVD (android virtual device) set up.
  • Fire up the Appium desktop app to start an Appium server on the machine with the virtual devices (a mac for iOS testing and windows/linux/mac for Android testing). This can be the same machine as you run your Karma instance or a machine accessible by it.
  • Configure your karma.conf.js file to let it know where your virtual devices are
  • Run your tests and Karma will pipe the tests out to the Appium server with the WebDriver API. Appium will then fire up the emulators and run the tests in the specified browsers.

karma.conf.js

Karma will launch the browers to localhost:9876 (or whatever other port you set it to) so if running your Karma instance on a different machine to your test machine, you will want to let your emulated browsers where to go to run the tests. Obviously localhost on the test machine is of no use if localhost there doesn’t have your Karma instance. You can simply do this by specifying the hostname in your karma.conf.js. ie:

hostname: '192.168.10.126',

You will need to declare your custom launchers for your emulators too. In my case, this looks like this:

customLaunchers: {
    'iOS-Safari' : {
        base: 'WebDriver',
        platformName: "iOS",
        deviceName: 'iPhone 5',
        config: webdriverConfig,
        browserName: 'Safari',
    },
    'Android' : {
        base: 'WebDriver',
        platformName: "Android",
        deviceName: 'Android',
        config: webdriverConfig,
        browserName: 'Browser',
    }
},

webdriverConfig just contains the IP and port of the Appium server. In my case:

var webdriverConfig = {
    hostname: '192.168.10.126',
    port: 4723
}

Here is my complete karma.conf.js:

// Karma configuration
// Generated on Thu Aug 06 2015 11:58:03 GMT+0100 (BST)
var webdriverConfig = {
    hostname: '192.168.10.126',
    port: 4723
}
module.exports = function(config) {
 
  config.set({
 
    // base path that will be used to resolve all patterns (eg. files, exclude)
    basePath: '',
 
    browserNoActivityTimeout: 1000000,
 
    // frameworks to use
    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
    frameworks: ['jasmine', 'requirejs'],
 
    // list of files / patterns to load in the browser
    files: [
      'test/test-main.js',
      {pattern: 'environment-config.js', included: false},
      {pattern: 'environment-config.json', included: false},
      {pattern: 'js/**/*.*', included: false},
      {pattern: 'test/jasmine/spec/**/*.spec.js', included: false},
    ],
 
    junitReporter: {
        outputDir: 'reports/karma',
        outputFile: undefined,
        suite: ''
    },
 
    // list of files to exclude
    exclude: [
    ],
 
    // preprocess matching files before serving them to the browser
    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
    preprocessors: {
    },
 
    // test results reporter to use
    // possible values: 'dots', 'progress'
    // available reporters: https://npmjs.org/browse/keyword/karma-reporter
    reporters: ['progress', 'junit'],
 
    // web server port
    port: 9876,
 
    hostname: '192.168.10.126', //points to accessible Karma server
 
    // enable / disable colors in the output (reporters and logs)
    colors: true,
 
    // level of logging
    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
    logLevel: config.LOG_INFO,
 
    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: true,
 
    // start these browsers
    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
    browsers: ['iOS-Safari', 'Chrome'],
 
    customLaunchers: {
        'iOS-Safari' : {
            base: 'WebDriver',
            platformName: "iOS",
            deviceName: 'iPhone 5',
            config: webdriverConfig,
            browserName: 'Safari',
        },
        'Android' : {
            base: 'WebDriver',
            platformName: "Android",
            deviceName: 'Android',
            config: webdriverConfig,
            browserName: 'Browser',
        }
    },
 
    // Continuous Integration mode
    // if true, Karma captures browsers, runs the tests and exits
    singleRun: true
 
  })
}

Appium Android Config

Screen Shot 2015-08-20 at 16.34.33

 

You can get the device name and platform version of your installed AVDs with the command:

~/Library/Android/sdk/tools/android list avd

 

This will give you something that looks like this:

Screen Shot 2015-08-20 at 16.39.37

Nothing changed in advanced settings except you must put in your Android SDK path so Appium knows where to find the SDK.Screen Shot 2015-08-20 at 16.34.50

Appium iOS Config

Screen Shot 2015-08-20 at 16.34.58

Appium General Config

The server address here is the address and port of the Appium instance (note in my example, Appium and Karma are running on the same machine under different ports but as mentioned above, you can have the Appium server running on an entirely different machine as long as it is accessible by the Karma service)

Screen Shot 2015-08-20 at 16.35.05

Next steps

I’ve not yet solved the running of iOS and Android tests simultaneously on the same machine but I am currently trying to solve this by setting up a Linux VM on the test machine to run the Android simulator so I can pipe to 2 machines effectively and test on both at the same time.

Also to tackle is running the tests on Chrome on the Android simulator. Currently I’m only testing on the “stock” browser. Desktop Chrome tests will most likely cover me in every single instance, though for completeness I want to get this solved.

How to get in to web development

Quite often when telling people what I do for a living, the other person will take interest and ask me how to get into web development. I’ve also responded to a few forum posts with advice for fledgling developers looking for their first step on the web development ladder so decided to put together an advice for anyone looking to get started with this career.

I’m writing this post assuming that you are competent with a computer and will outline what I suggest you learn and some other steps to take to get yourself your first job as a web developer.

Tools

If you already have access to a computer (and let’s face it, these days, who doesn’t?) you don’t need to spend a penny.

  • You’re going to need a computer. Either a mac, PC or Linux machine. There is huge debate all over the internet of mac vs PC vs Linux, but at the end of the day, either is more than good enough for web development. I use a 13″ Macbook Air for private projects and home use and I use a PC running Windows 7 at my full time job. So it really does come down to your personal preference or what you already own. In my opinion Macs look nicer so I’m happy to pay the “Apple tax” for their products because I spend so much time looking at them.
  • A web browser. In fact, you need to get your hands on as many different brower/version/OS combinations as you can. You will find very early on that different browsers handle HTML, CSS and even JavaScript in their own way and you need to make sure what you build works everywhere. Chrome, Internet Explorer (this is the one that will give you the most issues), Safari, Firefox.
  • A text editor. There are hundreds of different editors out there, many of them Free. When I started as a dev in 2000, I used Dreamweaver. At the time it was the big “buzz word” programme for web development and I’d not heard of anything else. Dreamweaver was my go to editor up until about 18 months ago when I started investigating other light weight options. I’ve tried Notepad++, Coda, Netbeans, TextMate, but have settled on Sublime 2 as I like the features, search is faster than any of the others and it’s nice being able to use the same editor on Mac and PC. It also looks pretty.
  • A dev environment. I use MAMP Pro on my Mac for my dev environment. It’s just quicker and easier to set up, run and configure than it is to set up the native environment that ships with OSX – they also do a free, non-pro, version which will do you fine to begin with. On windows, there is WAMP (I can’t vouch for WAMP however as I’ve not used it before. At my job, we have a centralised dev server that we do all our dev on)

Skills

Firstly, I should say that it can be quite intimidating when trying to skill yourself up for web development when you look at all there is to learn. There are literally thousands of different technologies and frameworks that you can learn. Even to this day, looking through job boards there are jobs requiring technologies that I’ve never even heard of. I’ll try and steer you to the major ones, the ones that I’ve chosen or been required to devote my time to as these are the skills that have got me a decent job and as much freelance work as I choose to take on the side.

Also worth noting is that you don’t need to know these things inside out. Even with the technologies I use most often and dedicate the majority of my time to, rarely will half an hour go past where I don’t turn to Google or Stack Overflow for some help or a reminder. There is so much to learn, it’s impossible to know and remember everything. The more you learn, you more you discover there is to learn. That is what keeps this job interesting.

When you are learning these skills, make sure you learn by doing, not just by reading. The information will sink in and you will have something physical to show potential employers/clients. It can help if you have a project in mind so you’ve an end goal to work to. If you don’t have one, here’s one for you. Develop a contact directory, in which you can add, edit, delete and search for contacts.

The first thing you should learn is HTML (Hyper Text Markup Language). HTML is what you mark up your content with so the browser understands it and can present it in the appropriate manner. If you right click on any web page and select “view source”, you will see the HTML behind a page. Learn how to create basic layouts with headings, text, links and images. A great resource for learning HTML is W3Schools and this is where I always point people who are new to the field.

Once you have a good understanding of HTML – as mentioned above, you don’t need to know it inside out – you should learn CSS. CSS (Cascading Style Sheets) define how your content is presented. That is your fonts, font sizes, colours, alignment, position, etc. Again, for learning CSS I’d point you to W3Schools. Another good CSS resource is Chris Coyier’s CSS tricks. Chris is pretty much considered the “man” when it comes to CSS and a search for just about anything CSS related will find him right at the top, though for an absolute beginner, the content on his site may seem a little advanced.

Once you’ve a good understanding of HTML and CSS, and it may take you only a few months, I’d recommend you put yourself out there and start applying for work. Seriously! Get onto the online job boards and search for “Junior Web Developer”. There are loads of positions. For those roles, companies are just looking for someone with the basics who is able to display initiative and a willingness to learn. The development agency I work for is constantly advertising for junior devs and we can’t find them anywhere. There is a huge skills shortage in our industry. As a proactive junior dev, you’d be a great asset to a company. For a relatively low investment, they can have their low level work such as minor updates taken care of. Freeing up the experienced devs for heavier work. In the process, you’ll be in web development 40hrs a week surrounded by experienced devs and your learning will sky rocket. Within a couple of years, you’ll be commanding good money.

I’m not guaranteeing you will find work straight away, it may take a while but you’ll be in a position to be employed.

Now you have HTML and CSS, the forest opens up slightly with a few more routes. You will need PHP/.net/Ruby and JavaScript/jQuery. Which you decide to learn first depends on if you are more interested in Front End Development (that is, what is displayed and goes on in the browser) or Back end Development (what goes on on the server and databases).

They are not mutually exclusive and even if you decide to specialise in the Front or Back end, the skills from the other are still necessary to have an understanding of. Once you have an understanding of one, the other will come to you much easier.

Keep applying for work!

For the front end you will want to learn Javascript/jQuery. There are other scripting languages and other libraries but none are as established as these 2 and in all my years as a dev, I’ve never encountered the others.

Javascript is a scripting language that allows you to interact with the browser and the content of the web page.

jQuery is a JavaScript library. You write simple jQuery commands (you actually write these in JavaScript) which it then takes and executes the complicated JavaScript behind the scenes. jQuery is a lot more simple (especially now you have CSS under your belt) than learning raw JavaScript so I’d suggest just jumping right into jQuery. While you are learning jQuery, unbeknownst to you, you will also be learning JavaScript so when you do decide to launch an assault on JavaScript, you will have already laid the groundwork. For jQuery, I’d again recommend W3Schools. I came across a website a few years back which I was hoping to locate again to link to in this post but couldn’t find it. I did however stumble across this: http://ejohn.org/apps/workshop/intro/#0 which looks a really good, simple and straightforward resource. You should also read the docs at jquery.com

Keep applying for work!

For the back end, you have a few more options. I listed PHP, .net and Ruby. While I understand Ruby is on the rise, I’ve never encountered a situation where I’ve had to touch it. This may not be the case for the job market in your area so do a bit of research on the job boards to see what companies are looking for. This leaves PHP and .net.

The development agency I work for started out in Classic ASP which is now pretty obsolete. When we decided we needed to update our technologies a number of years back we weighed up PHP vs .net and settled on PHP for a number of reasons; It’s openness, it’s free, the strong community behind PHP and open source and also because it would have been a smoother transition from Classic ASP. As an added benefit, when I think of .net developers I think of a shirt and tie and I’m more of a jeans and t-shirt kind of developer :)

That’s not to say that PHP is better than .net though. I know some .net developers that are making great money and are involved in exciting projects, but my experience and personal preference is in PHP. I can only list good reference sites for PHP as I’ve not a lot of experience with .net. So again, W3Schools. I also watched a series of videos on Lynda.com a number of years back when I was first learning PHP that I found hugely beneficial (the company I was working for at the time had a paid subscription).

Keep applying for work!

Along with PHP/.net/Ruby, you’ll need to learn how to manipulate a database so you’ll want to teach yourself MySQL (Structured Query Language). There are tutorials all over the web and if W3Schools has been working for you so far, stick with them, if not, a simple Google search will put you in the right direction.

Keep applying for work!

Once you have all of the above under your belt, I’d recommend getting your hands dirty with some of the MVC frameworks out there. MVC (Model View Controller) frameworks have been around for years and they are really taking off. Because of the way the front end (View) is separated from the back end (Controller and Model), it allows for easily maintainable code and makes it easy to farm off the front end to the front end developers, allowing them to work on the project without interfering with the back end.

There are numerous frameworks out there. I regularly use Code Igniter and Laravel and occasionally Silverstripe which was my first foray into the world of MVC. The docs and forums for these frameworks are your best place to get acquainted with the frameworks. Also (mentioned below) Stack Overflow is an amazing resource for everything web development. Out of the 3, right now I’d suggest Code Igniter. While it is a little behind Laravel in terms of features, there is a much bigger community behind it which is a huge bonus when you will have a lot of questions. Laravel’s following is quickly on the rise though and it is a relatively simple transition from Code Igniter to Laravel.

Keep applying for work!

Source control will also come in handy. SVN (Subversion) and GIT are the obvious ones. If you are to pick between the 2 I’d say go for GIT. SVN is fairly dated and where it hasn’t already been,  is being replaced by developers with GIT. Source control is one area I personally need to shape up on. I’m fairly comfortable with SVN but definitely need to spend some time learning GIT.

Other info

When you get called for an interview, go smart. That means a shirt and tie at least. You’ll likely end up being able to wear jeans to a web dev job but turning up to an interview like that makes you look lazy and like you don’t care about the job. Set a good impression.

Take your laptop so you can show your work and your learning journey.

In an interview, if you don’t know the answer to a question, say so. They don’t expect you to know everything, they just want to suss out what stage you are at with your learning.

You’ll likely be on a short probation when you first start your job. Keep setting a good impression. Don’t be the guy (or girl) that turns up on the dot and then leaves on the dot. That guy exists in every single office and everyone thinks bad of them for it. I have a friend (not a developer) who is that guy. He can’t understand why I’ll be at work at least half an hour before I’m contracted to start and at least 15 minutes after I’m contracted to finish. He regularly tells me “They’re not paying you for that extra time. You should be out the door dead on 5.30. That’s your right”. Yes, it is my right but it doesn’t set the best possible impression. I may be working extra for no immediate financial gain, but come pay review time, the boss is going to be well aware of my time keeping and will no doubt reflect this in his decision.

More tips for developing your skills and getting work

Keep a blog of your progress. Did you struggle with something and work it out? Blog about it. Not only will writing about it help you remember, but you’ll have something else to show prospective employers, it’s a great way to interact with other developers. You may even get job offers come through to you. I only started blogging around a year ago and have had a number of people contact me with employment opportunities.

Get an account on Stack Overflow. If you’re stuck with something, post a question. Also spend some time trying to help those with issues you know the answer to. You’ll quickly build a reputation and you can tie it to a Stack Overflow Careers profile which is another way to get in touch with prospective employers and for them to find and contact you.

Get on twitter and start using it. I’ve only joined the twitter in the last 18 months or so and have to admit that this is one of my flaws. I should be more active. If you want to interact with me on twitter, you can find me @fraserhartdev

Talk your code over with other developers. Seek out tidier and more efficient ways of achieving your end goal. If you don’t know any other developers and have some questions, fire me an email ([email protected]), I’ll be glad to give you some pointers.

If you have any questions at all about anything below. Please ask below or get in touch via email. Good luck in your new careers!

Artisan in Laravel – Getting Started – How to install a Bundle

I’ve been working with Laravel for a couple of months and have seen Artisan pop up here and there while viewing various docs. I was aware that Artisan is a command line interface for Laravel but had never, until today, come across a situation where I’d have to use it.

I needed to install the feeder bundle to a site I was working on. I could have just downloaded the bundle from GitHub and installed in manually but thought this was an opportune time to get my hands wet with Artisan. I struggled to find any complete beginner docs on how to actually get into Artisan. It turned out to be offensively simple so after a few minutes I’d worked it out:

SSH into your server and navigate to your site’s root directory (via terminal or an SSH client like putty) containing the ‘artisan’ file …

ssh [email protected]
cd /path/to/site

…from there you can access Artisan.

To see a list of available Artisan commands and to check you are in the right place, enter

php artisan help:commands

This will list off the available commands

Now to install your bundle, you need to use the install command, specifying the bundle you wish to install.

php artisan bundle:install bundlename

This will install the bundle and if successful you will get a message like so:

Fetching [bundlename]...done! Bundle installed.

Video.js issues on iPad & iPhone (iOS) – Troubleshooting

I’ve played with video.js to embed HTML5 video a little in the last year but not in any depth. The last time I used it I came across a few hurdles. And today, I was trying to embed a video supplied by a high profile client. For the most part, it went without a hitch but I had issue with the HTML5 video playing on a first generation iPad with iOS 5.x and my iPhone 4 running iOS 6.x (and possibly more iOS devices that I was unable to test in). It was fine in all versions of IE I tested (down to 7), Chrome (mac & PC), Firefox (mac & PC), an android phone and a latest gen iPad that I was able to get my hands on.

The client sent an HD 1080p mpeg across which I converted to .mp4 using Handbrake. From previous experience, I knew that I also had to convert this to .webm format so that it would play in Firefox – I believe there are some licensing issues with Firefox using the H.264 codec in .mp4 which gives us the requirement for the .webm format. I used online-convert.com to convert the .mp4 into .webm.

Once I had my videos in the desired formats, I embedded the video like so:

<video id="my_video_1" class="video-js vjs-default-skin" controls autoplay preload="none" width="1050" height="588" poster="/img/posterframe.jpg"
     data-setup="{}">
        <source src="/video/Video.mp4" type='video/mp4'>
        <source src="/video/Video.webm" type='video/webm'>
    </video>

This lead me to the above situation with it working pretty much everywhere with the exception of the old iPad and my phone.

After trawling the forums and stack overflow, I was no closer an answer so I tried everything I could think of including different encoding via handbrake, different video formats, different video players, messing with the video tag… Finally, I tried reducing the video res from 1080p to 480p and finally managed to get it working – turns out old iOS devices don’t like HD video.

Web Developer Job Vacancy in Sevenoaks

The company I work for is expanding and taking on more and more work. As a result we have vacancies for web developers in Sevenoaks, Kent. Just 20 minutes from London.

If you have any level of experience (Junior to Senior) and are looking for a great place to take your career to the next level, send your CV with covering letter and examples of your work to [email protected] (no agencies please).

Skills we need (at any level) include:

  • HTML5
  • CSS3
  • PHP
  • Laravel
  • Code Igniter
  • Javascript
  • jQuery
  • Classic ASP

We’re a friendly bunch and play squash together once a week and are not against the idea of a game of worms.

You’d also get to work with me.

AJAX Contact Form Tutorial with PHP and jQuery

A quick and easy AJAX Contact Form Tutorial using PHP and jQuery. I decided to put this together as I’ve received comments from a number of people who like the AJAX contact form on my main site.

VIEW THE DEMO (note, in the demo, I have commented out the line which actually fires the email) | DOWNLOAD THE FILES

As a base line, we will take the standard PHP contact form example on W3schools. We’ll throw in some jQuery and CSS and modify it slightly to make it to work with AJAX. This is what we will start with:

<html>
<body>
 
<?php
if (isset($_REQUEST['email']))
//if "email" is filled out, send email
  {
  //send email
  $email = $_REQUEST['email'] ;
  $subject = $_REQUEST['subject'] ;
  $message = $_REQUEST['message'] ;
  mail("s[email protected]", $subject,
  $message, "From:" . $email);
  echo "Thank you for using our mail form";
  }
else
//if "email" is not filled out, display the form
  {
  echo "<form method='post' action='mailform.php'>
  Email: <input name='email' type='text'><br>
  Subject: <input name='subject' type='text'><br>
  Message:<br>
  <textarea name='message' rows='15' cols='40'>
  </textarea><br>
  <input type='submit'>
  </form>";
  }
?>
 
</body>
</html>

The first thing you will want to do is to separate the code which actually sends the email from the display of the form so you will have two files:

index.php

<html>
<head>
  <title>AJAX Contact Form with PHP and jQuery</title>
</head>
<body>
  <form method='post' action='mailform.php'>
    Email: <input name='email' type='text'><br>
    Subject: <input name='subject' type='text'><br>
    Message:<br>
    <textarea name='message' rows='15' cols='40'></textarea><br>
    <input type='submit'>
  </form>
</body>
</html>

mailform.php

<?php
if (isset($_REQUEST['email']))
//if "email" is filled out, send email
{
	//send email
	$email = $_REQUEST['email'] ;
	$subject = $_REQUEST['subject'] ;
	$message = $_REQUEST['message'] ;
	mail("[email protected]", $subject, $message, "From:" . $email);
	echo "Thank you for using our mail form";
}
?>

We will be using jQuery.ajax() to post the form data through to the send script which requires no further modifications (you can also use jQuery.post() as a slightly simpler way of doing this but I always opt for ajax() as it offers a greater amount of control if needed). But first we need to add a loading indicator and a success message. Both of which will be initially hidden via the CSS. With jQuery, we will show and hide these at the appropriate stage of the process:

index.php

<html>
<head>
  <title>AJAX Contact Form with PHP and jQuery</title>
  <style>
    #loading, #success{display: none}
  </style>
</head>
 
<body>
  <form method='post' action='mailform.php'>
    Email: <input name='email' type='text'><br>
    Subject: <input name='subject' type='text'><br>
    Message:<br>
    <textarea name='message' rows='15' cols='40'></textarea><br>
    <input type='submit'>
  </form>
  <div id="loading">
    Sending your message....
  </div>
  <div id="success">
  </div>
</body>
</html>

Now the jQuery. With the jQuery we will:

  1. Prevent the default form action
  2. Hide the form
  3. Display the “loading” message
  4. Post the form to the send script
  5. Wait for a successful response
  6. Hide the “loading” message
  7. Display the “success” message
$(function(){
      $('form').submit(function(e){
        var thisForm = $(this);
        //Prevent the default form action
        e.preventDefault();
        //Hide the form
        $(this).fadeOut(function(){
          //Display the "loading" message
          $("#loading").fadeIn(function(){
            //Post the form to the send script
            $.ajax({
              type: 'POST',
              url: thisForm.attr("action"),
              data: thisForm.serialize(),
              //Wait for a successful response
              success: function(data){
                //Hide the "loading" message
                $("#loading").fadeOut(function(){
                  //Display the "success" message
                  $("#success").text(data).fadeIn();
                });
              }
            });
          });
        });
      })
    });

Here is the complete code:

<html>
<head>
  <title>AJAX Contact Form with PHP and jQuery</title>
  <style>
    #loading, #success{display: none}
  </style>
  <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
  <script>
    $(function(){
      $('form').submit(function(e){
        var thisForm = $(this);
        //Prevent the default form action
        e.preventDefault();
        //Hide the form
        $(this).fadeOut(function(){
          //Display the "loading" message
          $("#loading").fadeIn(function(){
            //Post the form to the send script
            $.ajax({
              type: 'POST',
              url: thisForm.attr("action"),
              data: thisForm.serialize(),
              //Wait for a successful response
              success: function(data){
                //Hide the "loading" message
                $("#loading").fadeOut(function(){
                  //Display the "success" message
                  $("#success").text(data).fadeIn();
                });
              }
            });
          });
        });
      })
    });
  </script>
</head>
 
<body>
  <form method='post' action='mailform.php'>
    Email: <input name='email' type='text'><br>
    Subject: <input name='subject' type='text'><br>
    Message:<br>
    <textarea name='message' rows='15' cols='40'></textarea><br>
    <input type='submit'>
  </form>
  <div id="loading">
    Sending your message....
  </div>
  <div id="success">
  </div>
</body>
</html>

Obviously, there is no validation or styling on the form, it is simply a quick demo on how to make a working contact form using AJAX with PHP and jQuery. If you’d like me to expand on this and incorporate validation and some nice styling, let me know in the comments below and I will write another post to take this contact form a stage further.

Any questions? Feel free to ask.

Want to hear me talk? I co-host the web development podcast “Three Devs and a Maybe”. Check us out here

aspupload – File(s) not uploaded

This post is more for my reference as I still work on a number of classic ASP projects which use aspupload in my day job. When attempting to upload images via an upload form in the CMS a client was getting the error:

File(s) not uploaded.

After 2hrs of trial and error and attempting various fixes including IIS security settings and folder permissions, I was finally able to narrow it down to the form tag. I had omitted:

enctype="multipart/form-data"

This instructs the browser to send the entire file and not just the file input. The whole tag should look like:

<form method="post" enctype="multipart/form-data" action="s_uploader/inc_upload_page_image.asp?page_id=<% response.write(request.QueryString("page")) %>">

jQuery Fullscreen Background Slideshow

I recently worked on a project where there was the requirement to implement a full screen/window background slideshow. Rather than just pick one of the many plug-ins out there, I decided to put my jQuery to work and come up with my own solution. What I came up with is very simple.

You can SEE THE DEMO HERE and DOWNLOAD THE CODE HERE.

Firstly the HTML and CSS. We are not applying the backgrounds to the body of the page, we are faking this by putting them in a fixed position, 100% width and height div which will sit behind our content. The images that we put in the background div are also 100% height and width and absolutely positioned on top of each other. The images have a min-width so they are not able to get too small. If the window is resized smaller than the min width, they simply overflow.

<body>
	<div id="bg">
	        <img src="image3.jpg" />
	        <img src="image2.jpg" />
	        <img src="image1.jpg" />
	</div>
	<div class="mainContent"></div>
</body>
body{
	background:#333;
}
#bg{
	position:fixed; 
	top: -50%; 
	left: -50%; 
	width: 200%; 
	height: 200%; 
	z-index: -2;
}
#bg img{
	position:absolute; 
	top: 0; 
	left: 0; 
	right: 0; 
	bottom: 0; 
	margin: auto; 
	min-width: 70%; 
	min-height: 70%;
}
.mainContent{
	width:300px; 
	height:500px;
	position:fixed;
	right:0;
	top:50px;
	padding:25px;
	background:#fff;
	overflow:hidden;
}

If you take a look at your page now, your background (as the backgrounds are absolutely positioned, they sit on top of each other so you only see the top (last) one in the stack) fills the screen nicely and expands and contracts as you resize the window. All we need to do now is make the slideshow come together with jQuery.

To do this, we just fade out the top most image to reveal the one behind – repeat. When we get to the final image, we fade them all back in again and start over. Simple:

//get the number of images we have to cycle through
var numberOfBackgrounds = $('#bg img').length;
 
//keep track of the current background - we start with the last (top) one in the stack
var currentBG = numberOfBackgrounds;
 
//swap out backgrounds
setInterval(function(){
    if (currentBG == 1){
        //we have reached the last image so we fade them all back in and reset the counter
        $('#bg img').fadeIn(1200);
        currentBG = numberOfBackgrounds;
    }else{
        //fade out the current visible background to reveal the next in the stack
        $('#bg img:nth-child('+currentBG+')').fadeOut(1200);
        currentBG = currentBG - 1;
    }
},
4000);

And there you have a working fullscreen background slideshow.

We can, however improve on this slightly. In it’s current state, it does’t look too appealing while it is loading – You can see all the background images chugging away as they download – so a nice touch is to show a loading overlay until the first visible (last in the stack) image has finished downloading.

Head over to ajaxload.info and generate yourself a loading gif.

You need to insert another overlay div in the same way that you did the background one. This will just have a blank background and a loading gif. We simply show this and then fade it out when the first visible image has finished downloading.

Add the new div into your HTML after your background div:

<div id="bg">
    <img src="image3.jpg" />
    <img src="image2.jpg" />
    <img src="image1.jpg" />
</div>
<div id="bgloader"></div>
<div class="mainContent">
   ......
</div>

.. and update your styles:

#bg, #bgloader{
	position:fixed; 
	top: -50%; 
	left: -50%; 
	width: 200%; 
	height: 200%; 
	z-index: -2;
}
#bgloader{
	z-index: -1; 
	background:url(ajax-loader.gif) center center no-repeat #000
}

If you look at your project now, you will just see the loading overlay. All we need is the jQuery to fade this out when the visible image has loaded and we do this like so:

//to fade out the loader			    
$("#bg img:last-child").one('load', function() {
    $('#bgloader').fadeOut();
  }).each(function() {
    if(this.complete) $(this).load();
});

If you’ve any questions or comments, post them below and I will be glad to lend a hand where it’s needed.