Sunday, 27 May 2012

UI Stepping Stones

Recently I've been planning a User Interface for a Human Resources application. As a bit of personal interest, I had to deal with my first child last year and build my motivation back up afterwards, and now I'm returning to it. It's a side project I've been doing for a while in PHP that is form-based, using Smarty templates and jQuery. I admit I have a bit of work to do to make things look good with CSS and the new CSS3. I love the descendants selectors! How to make things look neat and eye-catching...

The form fields are getting populated a lot of the time via "barebones" SQL queries. (In the future I hope to transform these into better Doctrine ORM statements!) Many of the form input fields are required to be filled out in sequential order, e.g. if fields A and B are not filled out, field C will need to be disabled somehow, because it is unable to be filled out yet. I juggled in my head a few ideas, like should I hide the disallowed fields, or make them read-only? The number of my fields was also growing on the form, and I needed to split them up somehow. (How many users get bored if they see more than 8-10 things to fill out on one webpage?)

In the end I went with the hiding/showing idea, and decided to split the many input fields into a number of form steps. Only one step view will be visible at a time. What this really means is that there are two steps, and two other extra places to add information: Edit Narrative and Attached Files. The Edit Narrative option features a rich text editor (fancy!). The Attached Files area will let users upload CV files for job applications.
Step 1 (above)

The challenges I'm going to face are:
  • turning my plain select-options box into an AJAX text search box. This will be fun! As you type it will hopefully bounce back the results of database queries.
  • migrating the project to a convenient web framework later. I'm looking at Symfony.
  • putting it on the github repository site. Yes, an actual project by me on github.

I've attached a few screenshots to show my first draft.



Step 2 partially filled (above)

Step 2 completed (above)



Tuesday, 22 May 2012

Drupal Revisited

I've been having an interesting week or so outside work, getting back into the Drupal Content Management System which is written in PHP. My last real experience with it was years ago, Drupal version 6.x. I was doing volunteer work for a local community centre, who wanted a website for which they could edit content themselves without having to do any programming.

Of course, setting up a basic Drupal site and changing a few things is easy. Where I ran into trouble was the need to customise things like banners for different pages, file uploads and image placement. I had a lot to learn with the CCK (Content Construction Kit) and the Views module. Then I started studying for an I.T course and ran out of time, eventually having the give up on this volunteer work.

In the years since then, I've learnt a lot of .NET, Javascript, Python and PHP. I'm also properly familiar with Apache virtual hosts now. Now I'm better prepared to tackle the newish Drupal version 7, especially the PHP side of things. I've also been checking tables in PHPMyAdmin as I go, to see what Drupal is doing to the database.

I've been able to sign up for a developer account at drupal.org, then clone a copy from their git repository. It's been great reading through the Drupal source. I've also received a few emails for security flaw notifications. Thanks, Drupal guys!

Some things I've noticed which are different about Drupal 7:
  • the CCK is now mostly incorporated into Drupal core
  • CKEditor with the WYSIWYG configuration module seems to offer a good rich text editor
  • hooks and APIs
  • the Admin menu at the top (I like this anyway in v.6)
  • the overall impression is that Drupal is now not so primitive, the modules are better and there is more documentation online.

My challenges now are to tackle the Views module (which I was never fully able to get to before), check out the hooks, and make a custom template or theme.

I always write down a bunch of notes as I do anything new, so here's a snippet of the most recent thing I did:

NOTES
-----
Download modules from: http://drupal.org/project/Modules
Token
PathAuto
Chaos Tools - Chaos Tools, Stylizer, Views content panes
Views
WYSIWYG

Download standalone CKEditor for Drupal from http://ckeditor.com/download. Unzip
mkdir sites/all/libraries
mkdir sites/all/libraries/ckeditor
-paste folder containing ckeditor.js into sites/all/libraries/ckeditor
-Go to Configuration > Wysiwyg profiles
----

Till next time!



Tuesday, 8 May 2012

Something old, something new, something borrowed...


I'm dedicating this post to some new and borrowed things I've been looking at recently. I found myself in a bit of a rut lately, using some of the same old techniques over and over again, instead of looking at the better, more efficient methods that are out there.

Something old:
One thing I've tried to overcome is a bad habit of using Javascript alerts to tell me what's going on with variable values in web pages. Mainly just because it's convenient. Instead, now I'm using Firebug (the debugger add-on for the Firefox browser) and the console.log command regularly to check values. I'm also getting better at using the Script tab in there for stepping through functions and loops, etc. I can't believe I haven't been using these for so long, it only took a few short moments to realise the folly of my ways. (I had known about these features for a long time, but foolishly ignored them.)

Something new:
In Python, another thing I've been deploying more and more has been filters and list comprehensions. As well as being great space-savers in your code, they seem to run in programs more quickly too. Here's one I wrote to process a dict, retrieving the first key who value matches an if condition. The dict "users_to_find" has a value, "v", somewhere that matches what is in my row[2] tuple.

user_name = [k for k, v in users_to_find.items() if v == row[2]][0]

Goodbye YA boring "for/if/break" loop! :-D

Something borrowed:
The last thing I'll mention is a little script I'm having to make which will retrieve old historical data from a MySQL database. Previously, the project that stored the data was using the heavyweight Python SQLAlchemy ORM library. Obviously, my small script doesn't need overkill in this fashion, so I'm borrowing the basic MySQLdb library to do this instead.

My experience moving from a sophisticated ORM to a simpler database interface module has been interesting. My queries in SQLAlchemy had involved much use of backrefs, retrieving from lists stored in objects, and joins. Now, just to get one value from one table linked to two others, I'm having to build SQL command strings like this:

sql_cmd = """select code from service
join service_sale
on service_sale.service_id = service.res_id
join sale
on sale.res_id = service_sale.sale_id
where sale.res_id = 693764;"""

What's going to make it clunky and complicated is that I have a few more "where" conditions to add on top of there, and also have to retrieve all the fields from the sale table. And in a moment of insanity earlier I had put an associative table, "service_sale", between two other tables. There's nothing like a good challenge. I guess I might have finished my mission (retrieving historical data from the old project) faster if I had just stuck with the old ORM queries. But it's great getting your hands dirty with barebones SQL now and again.