|
|||||
|
For all the job hunters out there in Canada, a list of the latest job postings from several sources. See the full list at my Jobs!! page
The list is updated VERY frequently, so feel free to either refresh the page often or subscribe at http://feeds.feedburner.com/usestrictjobs Hey folks! I'd like to announce that I've debuted on suite101.com. My first article there was how to optimize your job hunting using RSS feeds. In this article, I provide an explanation of Ajax with a historical introduction. If you are eager to start seeing the code, please scroll down.
What’s Ajax?
Ajax stands for Asynchronous Javascript And XML. It’s a way to call back-end scripts asynchronously – that is, without impacting user experience/flow. Basically, you don't even see the cursor become an hourglass or whatever other "waiting/processing" icon your system uses. It's not a language, but a technique. As for back-end scripts, you can use whatever you feel more comfortable with: PHP, Perl, Java, JSP, Shell, C, etc. The way to choose which technology to use as back-end is not outside the scope of this article.
Historical approach for calling back-end apps
Throughout web-development history, the very first way used to achieve back-end processing followed by front-end display was to create a form and set the back-end script as the action to that form. Upon submission, the form fields would be sent to the back-end script as a series of special environment variables, which would then be handled by the programmed logic. The back-end output would be displayed on the screen (either the same page/frame or a different page/frame, depending on the target attribute of the form). The catch 22 of this approach is that if you want to present another form after processing, that form must be produced by the back-end script, which leads to maintenance mayhem – to add or remove a field, you have to do so in both the original HTML and in the HTML of the back-end script. I recently decided to rewrite an application that I created for an English school where I used to work, and this time I want to do it right. I chose to write it in PHP with Object Orientation in mind, and use PDO+MySQL for the DAO portion. The reason for using PDO is that it's the closest thing to the DBI that I found for PHP - and the reason for PHP is that it's just plain simpler than using pure Perl, and I don't have the time to learn Catalyst or some other Perl Web framework. Anyway, here's what I'm doing for the PDO portion. First I created a
<?php
class Db{
public $dbh = null;
public function Db($db_type,$db_host,$db_user,
$db_pass,$db_base,$tbl_prefix){
if ($db_type == 'mysql') { // in case I want to add oracle in the future
$mysql_DSN = "mysql:host=".$db_host.";dbname=".$this->db_base;
try {
$this->dbh = new PDO($mysql_DSN, $db_user, $db_pass,
array(PDO::ATTR_PERSISTENT => true, PDO::ERRMODE_WARNING => true,
PDO::ATTR_ERRMODE => true));
}
catch(PDOException $e){
$rc[msg] = $e->getMessage();
die($rc[msg] . " " . __LINE__);
}
return $this->dbh;
}
}
}
?>
Secondly, I created the DAO classes which extend the DB. They are responsible for
<?php
class StudentsDao extends Db {
public $sth = array();
// Constructor
public function StudentsDao($db_type=NULL,$db_host=NULL,$db_user=NULL,
$db_pass=NULL,$db_base=NULL,$tbl_prefix=NULL) { // These params are to be passed to Db class
// Connect to DB
$this->Db($db_type,$db_host,$db_user,
$db_pass,$db_base,$tbl_prefix);
// Prepares queries
$this->sth = $this->prepare($tbl_prefix); // Look at prepare() further down
} // end of function StudentsDao
// Function that prepares queries
public function prepare() {
$sth = null; // will hold our temporary array
// get all students
$string = sprintf('select * from %s.%sstudents where id = ?',DB_BASE,TBL_PREFIX); // I have these constants defined in the main page
$sth['getStudentById'] = $this->dbh->prepare($string);
// update Student by Id
$string = sprintf('update %s.%sstudents
set field1 = ?, field2 = ?, field3 = ?
where id = ?',DB_BASE,TBL_PREFIX); // Note that this table has 3 control fields (id, sys_creation_date, and sys_update_date) prior to field1, field2, and field3 - I don't want them to be touched
$sth['updStudentById'] = $this->dbh->prepare($string);
return $sth;
} // end of prepare()
// Here we have the handlers for the queries prepared above.
// Fetches all students
public function getStudentById($id) {
$s = $this->sth['getStudents'];
$s->execute(array($id)) || die(print_r($s->errorInfo,1));
$result = $s->fetchAll(PDO::FETCH_ASSOC);
if (sizeof($result) == 0) {
// no data found
$out[err_cd] = 1;
}
else {
// data was found
$out[err_cd] = 0;
$out[data] = $result;
}
return $out;
}
// Updates student by Id - this is a tricky one
public function updateStudentById($data,$id){ // $data can have data regarding one or more fields
// Populate current fields
$fields = $this->getStudentById($id); // get current values
// Remove unwanted fields
$fields = array_slice($fields[data][0],3); // remove the 3 initial control fields
// Replace with new fields
foreach($data as $k=>$v){
$fields[strtolower($k)] = $v;
}
$fields['id'] = $id;
$s = $this->sth['updStudentById'];
$s->execute(array_values($fields)) || die(print_r($s->errorInfo,1));
$count = $s->rowCount();
if ($count == 1) {
$out[err_cd] = 0;
}
else {
$out[err_cd] = -1;
}
$out[err_msg] = $this->status[$out[err_cd]];
return $out;
}
?>
In the example above, you will probably frown on the fact that I'm calling I wanted to be able to pass the function an associative array containing only the fields I want to update - be it only My original idea was to basically, to emulate something like this:
That would set Here's the question part: The technique shown in the example will basically pull all values from the record and populate them in the Here's a quickie for you Ajax coders who need a function to parse your form fields into a URL query string. It handles input fields (text, hidden, whatever), radio and checkbox elements, and single/multiple select menus. Just make sure that all your form fields have IDs.
function build_post_string(frm) {
var poststr;
var poststr_array = [];
if (!frm.id) {
// assume it's a string. get the form object
frm = document.getElementById(frm);
}
for (i=0;i<frm.elements.length;i++){
var elem = frm.elements[i];
if (!elem.id) {
// skip any fields that don't have IDs
continue;
}
if (elem.type == 'radio' || elem.type == 'checkbox') {
// only grab radio buttons and checkboxes that are checked
if (!elem.checked) {
continue;
}
}
// get select values
if (elem.nodeName.match(/SELECT/i) && elem.multiple) {
//var sel = elem;
var sel_array = new Array();
for (var o=0;o<elem.options.length;o++) {
if (elem.options[o].selected) {
sel_array[sel_array.length] = elem.id+"="+elem.options[o].value;
}
}
var sel_str = sel_array.join('&');
// build key/value pairs for SELECTs
poststr_array[poststr_array.length] = sel_str;
}
else if (elem.nodeName.match(/SELECT/i)) {
poststr_array[poststr_array.length] = elem.id+'='+elem.options[elem.selectedIndex].value;
}
else {
// build key/value pairs for everything else
poststr_array[poststr_array.length] = elem.id+"="+elem.value;
}
}
// build poststr
poststr = poststr_array.join("&");
return poststr;
}
A couple of weeks ago I finally got a new laptop at work - which meant of course that I had to reinstall everything. Although we use Windows XP, there's one app that I have to run through Linux. The solution was Sun's VirtualBox running Ubuntu 9.04. When I tried to run the app, I realized that I still needed to install DBI and DBD::Oracle - which brings me to this article. Nothing better than a reinstall to generate article material DBD::Oracle is usually a pain to install if you haven't already done it a gazillion times. After that, it's just an annoying itch. In this article I'll cover installing DBD::Oracle using Oracle Instant Client, Ubuntu 9.04, and Perl 5.10. Since we're using the Instant Client, you'll need some Oracle DB you can connect to in order to do the testing. You can choose to skip testing altogether, but you might be into a surprise later. Continue reading... The cool thing about blogging software is that it shows the blogger all sorts of interesting information, such as the number of visitors, or the search string that led them to the blog. I see lots of interesting search strings, but I keep wondering if the users actually found what they were looking for. That said, please be kind and leave a message telling me if you found what you wanted, and if you didn't, please say what it was and I'll try to cover that in my posts. You can leave your message either as a comment here, or send me an email through the contact form. Thanks!! I've added a Tech Jobs page to the main pages section (right under the header) for those who are looking for jobs. Update: Added craigslist.com search for Perl jobs in Canada Update: The Feed fetcher now works with craigslist.com worldwide. You can also use search keys for feeds that accept them. Update (6/13/09): monster.com added with 192 countries (!!). Since some sources accept keywords and others don't, the form will now tell you so. Also, modified the form to allow blank keywords for some sources. The issue is that craigslist uses a totally separate query for blank keywords, and right now the fetcher doesn't handle alternate query strings per source. Total Sources: 4. Total feeds: 708. Good luck job-hunting! Vinny. Seriously - **DON'T!** (did I stress that enough?) Not unless you've tested it well on a non-production machine. It's been known to break themes and plugins. My Advertising Manager plugin is still broken as of this writing, and there's no automatic downgrading. If you were hasty like me and ended up getting in trouble with the blasted 2.8 version, check this link on some steps to perform the downgrade. Update: Changed subroutine to comply with Perl Best Practices Update2: Removed the prototype from the subroutine. I've always had a problem with recursion. Not with the general theory that a function will call itself, etc - no, that's easy. The hard part was when I had to deal with complex data structures in Perl (an array- or hashref containing a hash of arrays of hashes, a gazillion levels deep). Well, I guess anyone would have a hard time with that kind of data. Anyway, in this post I don't intend to get all complicated explaining all the kinds of recursions out there. If you want that, check this article at wikipedia. What I do want to do is help all of those who are in the situation I was in, by explaining in the simplest way possible how to deal with this scenario. Continue reading... |
|||||
|
Copyright © 2010 use strict ;#) - All Rights Reserved |
|||||