July 15, 2010

DataGrid Control V2

I’ve been working on a series of “Control Objects” to include in my usual projects, and I thought I’d post one of the completed ones up here. Basically it mimcs the use of the DataGrid control in Visual Studio but in a way I find a lot easier and more in-tune with PHP. After creating the DataGrid, you define a “source”. The Source is essentially a multi-dimensional array that you could assign with a simple

while($r[] = mysql_fetch_array($resource)){}

you would then pass $r as the source to the DataGrid. You have the ability to set some options (like specifying specific style sheets, JS libraries for AJAX editing or defining and renaming visible columns) and then a single build(); command will output the table. Of course, you can also build(true); to return the table incase you’re using some sort of theme system.

$data = array(
  array('id'=>0,'f_name'=>'Angelo','l_name'=>'Rodrigues'), 
  array('id'=>1,'f_name'=>'Darth','l_name'=>'Vader'),
  array('id'=>2,'f_name'=>'Luke','l_name'=>'Skywalker'),
  array('id'=>3,'f_name'=>'Han','l_name'=>'Solo'),
);
 
$DataGrid = new DataGrid(); 
$DataGrid->configure(
  array(
    'primary_key' => 'id', 
    'sortable' => true, 
    'striped' => true,
    'even_row' => null, 
    'odd_row' => 'striped'
    )
);
 
// This not only defines display fields, but the order as well 
$fields = array( 
  'f_name' => 'First Name',
  'l_name' => 'Last Name',
);
$DataGrid->setDisplayFields($fields);
$headers = $DataGrid->Headers();
echo $headers['css']; 
echo $headers['js']['object'];
echo $headers['js']['function'];
 
 
$DataGrid->source($data); 
$DataGrid->build();

The code can be further simplified by using a new class called ControlObjectManager (or COM for short). COM can be used to instantiate multiple Controls at once and even assign shortcuts to commonly used Controls. For example, if you need DataGrids a lot, you can initiate them via a simple call like $COM->init(array('dg')) and as long as you set up that dg means DataGrid in the configuration for COM, you’re good to go.

I’ll post up some more on the COM when it’s done, but for now, here’s a link to the latest iteration of DataGrid v2.

View on Pastebin – Just note that this is the debug version of the script, so there are tons of comments and explanations.

The original DataGrid actually tied in to MySql directly and required the MySqlAdapter control to even function. This latest iteration removes all ties to any database instead focusing on a simple multi-dimensional array of data. As well it drops the code-base down quite a bit and condenses a lot of functionality. For example: originally you would have had to set the display columns and then order them, but by compressing them into a single function it not only makes MORE sense, but is easier to read.

July 7, 2010

Search array for Substring

Occasionally you’ll need to create some sort of auto-complete field. While you could power this entirely via AJAX requests on a per-character basis, with limited resources, you may want to look at this alternative.

Essentially you’ll create a javascript array containing allowed values. Whenever a user types in some characters, we can use some regex coupled with a quick iteration to see if whatever the user entered is valid. If it is, we can easily return the matched values.

The function below is written in straight JavaScript. I monitor my keypress events via jQuery, but any way you want to do it is fine. Just make sure you call arrayFind() with the string you want to find and the array you want to search in.

function arrayFind(needle,haystack) {
var matchList = [];
var regex = new RegExp(needle,'gi');
for(i in haystack) {
	if(haystack[i].match(regex)) {
		matchList[matchList.length] = haystack[i];
	}
}
return matchList;
}

If you didn’t need to use a variable for the regex you could eliminate that line and just use /searchterm/gi for a global case-insensitive search of the array. Since we are however, we need to make use of the RegExp object.

June 25, 2010

Model – View – Controller

The Model-View-Controller (MVC) paradigm of programming is one that is often misused by most developers because it is simply the least understood. When reading tutorials on MVC principles most developers will launch right into the code, which is easy to follow for the purpose of the tutorial. But when those same users try and do it themselves, they find out that it’s a lot harder than it seems. This post aims to correct that by explaining the principles behind the MVC framework and the pro’s and con’s of using it.

In web development, every page will have it’s own Model, View and Controller. This is to ensure that only the information you are requesting is loaded. A lot of those new to the MVC approach will attempt to create a master controller which will then delegate this information to each Model as requested. In MVC, this approach doesn’t quite work. By creating separate entities for each requested page you will find that not only is it easier to maintain and update, but that MVC isn’t that hard to understand at all.

The Big Picture
The easiest way to understand MVC is to step back and look at the whole picture in terms of real-life. In this example, our Controller is going to be the Librarian, the Model is going to be the Library Catalogue and the View is going to be a Book. A user will come up to the Librarian and say “Hey, do you have Book XYZ?” The Librarian of course has no idea. It’s not their job to know where each Book is, but simply to know where to find the information that you are requesting. Regardless of what you are requesting the Librarian will look through a Library Catalogue, but they may look in different kinds of Catalogues. For example, if you say “Hey, do you have the Horror Book XYZ?” they can ignore every other category except Horror. Likewise if you say “Hey, do you have the Romance Book XYZ?” they can ignore every other category except Romance.

The Pieces of the Puzzle – The Controller
The Controller the is the primary building block of an MVC system. Everything you build is managed by the Controller (it Controls see? Programmers love these little word games). The Controller figures out what the user is trying to do and accordingly it goes through the appropriate Model and returns those results to the appropriate View. You can think of the Controller as a messenger. Basically when the user visits a page they are saying “I would like to see the [Gallery] page”. The Gallery Controller will see this and go right over to the GalleryModel and say “The user has requested this information”. It then waits for GalleryModel to respond, and then it takes those results and runs over to GalleryView and goes “Pretty this up”. It then shows you the prettied-up version.

The Model
The Model is also known as your Data Manipulation layer. This should contain functions that interface with the database. Insertion, Updating and Deletion should all occur here, with the results of each passed back to the caller. This centralizes all your DB calls to a single file for a single controller. In this way you know that modifying your “Gallery” table means only modifying your GalleryModel and GalleryView. It doesn’t seem like a big issue to inter-twine your database manipulation and controller at this stage simply because it isn’t. Of course you can integrate your Model directly with the Controller, but by segmenting these you can ensure a much easier re-use of code. Think about it this way – a gallery model can be copied and modified a little to turn it into a blog model. Since the Model doesn’t care about what to DO with the fields, you just need to update what fields it SHOULD be dealing with.

The View
The View is the easiest piece to explain. It simply acts as a display mechanism. It accepts some values from the Controller, mixes it with HTML and spits the result back to the controller. Think of it is a node-based theme engine. For example, you could have a function in your GalleryView that just accepted the URL of a thumbnail and added some HTML which, when styled, made it resemble a Polariod. At a later point in time, if you want to change this, modifying this single function will ensure that everything is changed uniformly.

The Big Picture – Now with the right words
So now we can revisit our Librarian and ask for a new book. We ask the LibraryController for “Horror book XYZ”. The LibraryController invokes the LibraryModel and executes the findBook() function passing it the genre (horror) and book name (XYZ). The LibraryModel executes a quick Database Query to figure out the results. Just so happens there are 5 books in that genre that contain XYZ (XYZ, WXYZ, AXYZ, XYZZ, XXYZ). It passes the result set BACK to LibraryController. LibraryControlled takes the result set and invokes LibraryView, calling the formatBookList() function using the result set as the argument. formatBookList() adds some HTML mockup to each entry and makes everything look good and then passes the HTML back to LibraryController. LibraryController shows you the result.

Variations
Some descriptions of MVC will modify it so that the Controller ignores the view and instead the Model is what passes the data to the View. Either way still conforms with MVC standards, which really just involve separting everything.

Advanced Concepts


Routers
When dealing with server-side languages on the web we have to remember that things don’t work the same as in a desktop environment. Event-driven programming may work fine for C# and Java, but doesn’t work the same way for PHP. In PHP, our equivalent fo Event-driven programming would be URL-based programming. An “event” as far as PHP is concerned, is the user trying to visit a page. This page should trigger some kind of action. In most MVC frameworks (all I would think), you get something called a “Router”. This Router class is essentially a way of registering URLS to certain Controllers. For example visiting www.example.com/gallery/view/48 would cause the Router (or page that invokes the Router) to invoke the GalleryController and make a call to the view() function passing it 48 as an argument. In this way they abstract away explicitly invoking galleryies and can have a single index.php page which invokes the Router and makes the calls as necessary.

Multiple Inheritance
While PHP doesn’t allow for Multiple inheritance (ie GalleryController extends c1, c2, c3) it does allow for cascading inheritance (GalleryController extends c3; c3 extends c2; c2 extends c1; and now GalleryController can do everything c1, c2 and c3 can). Because of this we can actually speed up our Model/Controller creation by extending a singple base Model or Controller class. These classes would ideally have common functions that all Models or Controllers could potentially need at some point. One example would be to force all Models to inherit from BaseModel which could be a custom created Database Manipulation functions that all Models would need.