Sunday, December 31, 2006

Mimic python

After the article yesterday i decided to mimic the python behaviour for strings and arrays.
Below you find the function to get parts from a string or an array. I added a '1,5,4' limiter to get specific and/or loose parts.

function getStrArr($var,$limiter){
if(is_numeric($limiter)){
// get one value
if(strpos($limiter,'-') === false){
return (is_array($var))?$var[$limiter]:substr($var,$limiter,1);
// get last value(s)
}else{
return (is_array($var))? array_slice($var,$limiter) : substr($var,strlen($var)+$limiter) ;
}
}else{
if(strpos($limiter,',') === false){
if(strpos($limiter,':') == 0){
$lim = str_replace(':','',$limiter);
// get part from the begin
if(strpos($limiter,'-') === false){
return (is_array($var))?array_slice($var,0,$lim):substr($var,0,$lim);
// get part from the end
}else{
return (is_array($var))? array_slice($var,$lim) : substr($var,strlen($var)+$lim);
}
}else{
$temp = explode(':',$limiter);
if($temp[1] == ''){
// exclude part from begin
if(strpos($limiter,'-') === false){
return (is_array($var))?array_slice($var,$temp[0]):substr($var,$temp[0]);
// exclude part from the end
}else{
return (is_array($var))? array_slice($var,0,count($var)+$temp[0]) : substr($var,0,strlen($var)+$temp[0]);
}
}else{
// get self defined part
$min = $temp[1]-$temp[0];
return (is_array($var))? array_slice($var,$temp[0],$min) : substr($var,$temp[0],$min);
}
}
}else{
// get pieces
$temp = explode(',',$limiter);
if(is_array($var)){
$arr = array();
foreach($temp as $t){ $arr[] = $var[$t]; }
return $arr;
}else{
$str = '';
foreach($temp as $t){ $str .= substr($var,$t,1); }
return $str;
}
}
}
}

Saturday, December 30, 2006

Beginning python : string and array

I wanted to climb up the programmer hierarchy so i decided to look at some python tutorials, not that i'm near to be a good OO php programmer but i found out if you aim high you get better doing the things you think you understand.

There are already a few things that caught my attention. At first the webdevelopment seems to look awfully like perl. In a tutorial i found they just printed the the html but i think i will find better ways when i explore python further.

Beside the obvious differences like syntax i found it refreshing there were similar functions for strings and arrays, they are in a datatype group called sequences. I will switch from python to php to show similar output

# define string and array variable
string = 'test'
array = [1, 2, 3, 4]


// define string and array variable
$string = 'test';
$array = array(1, 2, 3, 4);


# get size
len(string)
len(array)


// get size
strlen($string);
count($array);


# get one value
string[2]
array[2]


// get one value
substr($string,2,1);
$array[2]


# get last value
string[-1]
array[-1]


// get last value
substr($string,strlen($string)-1);
$array[count($array)-1];


# get multiple values start in the beginning
string[:2] # display the first 2
array[:2]
string[2:] # display everything except the first 2
array[2:]


// get multiple values start in the beginning
substr($string,0,2); // display the first 2
array_slice($array,0,2);
substr($string,2); // display everything except the first 2
array_slice($array,2);


# get multiple values start in the end
string[:-2]
array[:-2]
string[-2:]
array[-2:]


// get multiple values start in the end
substr($string,strlen($string)-2);
array_slice($array,-2);
substr($string,0,strlen($string)-2);
array_slice($array,0,count($array)-2);


# get part of variable
string[1:3]
array[1:3]


// get part of variable
substr($string,1,2);
array_slice($array,1,2);


# add value
string + ' test'
array + 5


// add value
$string .= ' test';
$array[] = 5;


# copy variable with itself
2*string
2*array


// copy variable with itself
$string .= $string;
foreach($array as $value){ $array[] = $value; }

As you can see there is more php code necessary and it involves different functions as well. There is also a loop necessary in php to mimic the python code.
You can also see a difference getting a part of the variable in python and php. In python you limit the part by the value key and in php you limit the part by how many values you need.

Because strings and arrays are a basic in every language it has to be as easy as possible to work with them.

Monday, December 25, 2006

Mysql last inserted id

In a few articles on mysql the function LAST_INSERT_ID() is used to extract the last inserted id but i experienced a problem with it. When i insert multiple rows in one query the LAST_INSERT_ID displays the first inserted id and not the last.

INSERT INTO table (field1,field2) VALUES (value1,value2),(value3,value4)

The function is also restricted to the table field that has an AUTO_INCREMENT value. To avoid the problem and make it more flexible i created a maxFieldOfTable function.

function maxFieldOfTable($table,$field = 'id'){
$result = mysql_query('SELECT MAX('.$field.') FROM '.$table);
return (!$result)? mysql_error():mysql_result($result,0);
}

Sunday, December 24, 2006

Simple php/javascript in place editing

This last few weeks i learned more about things i consider basic so that's why i want to give some working examples of it.

The first thing i want to get some attention to is the button tag. I read an article in the forgotten html tags series about the button tag. In the article the design advantages where emphasised but there are programming advantages too. The biggest advantage is the separation of the value and the title.

<input type="submit" name="button" value="Title" />
<button type="submit" name="button" value="1">Title</button>

When you have an input tag the posted value is the value that you have to display on the button. With the button tag you can put any value you want to post in the value attribute.

When i made forms where a row of data needed to be changed i used a radiobox with the id of the row which needed to be checked before you could click a button. With the button tag it's possible to only have to click on the button.

Php code



Now that we got that behind us lets look at the php code of the in place editing

foreach($data as $row){
$text = $row['field1'];
$buttonvalue = $row['id'];
$buttonname = 'update';
$buttontitle = 'Update';
if((isset($_POST['update']) && $_POST['update'] == $buttonvalue) ||
(isset($_POST['updateok']) && $check == 0 && $_POST['updateok'] == $buttonvalue)){
$text = '<input type="text" name="text" id="text" value="'.$text.'" />';
$buttonname = 'updateok';
$buttontitle = 'OK';
}
?><tr><td><?php echo $text; ?></td><td><button type="submit" name="<?php echo $buttonname; ?>" class="<?php echo $buttonname; ?>" value="<?php echo $buttonvalue; ?>"><?php echo $buttontitle; ?></button></td></tr><?php
}

This is the code needed to display the form input to change the text. The data variable is a result from a query that is caught in an array. To make the text changeable i rely on the button name and the value send when the button with the update class is clicked. The update code is located in a separate file because of the javascript functionality.

if(isset($_POST['updateok'])){
// mysql : update table set field1='$_POST['text']' where id= $_POST['updateok'];
$check = (mysql_affected_rows() == 1)? 1:0;
if(isset($_POST['js'])){ echo $check; }
}

As you could see in the first code fragment there is a second statement when the text has to be form input and that's when it wasn't possible to update the text. Most of the time that is due to a temporary programming blindness- not correct table, set a character to much or to little, ... - but it can be useful to report problems once the site is live. The only thing i needed to add to make it work in javascript is the output of the check variable.

Javascript



This was the easy part. Now we are going to climb steep coding hills. I use the jQuery library to make the javascript coding easier. The javascript code can be split up in two parts; the changing of the text to form input and the updating of the text. The changing of the text can also be split up in two parts. The first part is the check for changeable text and close it if there is a changeable text found.

if($('button.updateok').size() == 1){
$('button.updateok').html('Update').attr({class:'update'});
var text = $('#text').attr('value');
$('#text').parent().html(text);
}

People who are familiar with jQuery see a few simple lines but i will write it out.
If a button tag with the class updateok is found the innerhtml of the button will be changed to Update and the class will be changed to update. The variable text catches the value attribute from the element with the id text, this variable will be placed in the innerhtml of the parent tag that contains the element with the id text.
The second part is changing from the text to form input.

$(this).html('OK').attr({class:'updateok'});
var text = $(this).parent().prev('td').html();
$(this).parent().prev('td').html('<input type="text" name="text" id="text" value="'+text+'" />');

The code is similar so i won't write it out. The only thing that has changed is the this variable. I can work with it because the code is called in the function that is responsible to intercept the click event. You will see it later.
Now we are ready for the updating code

var id = $(this).attr('value');
var textt = $(this).parent().prev('td').children('#text')[0];
var text = $(textt).attr('value');
var self = this;
$.ajax({
type: 'POST',
url: 'update.php',
data: 'updateok='+id+'&text='+text+'&js=1',
success: function(msg){
if(msg == 1){
$(self).html('Update').attr({class:'update'});
$(self).parent().prev('td').html(text);
}else{
alert('Problem changing field.');
}
}
});

The first part of the code is lifting the necessary values off the page to put then in the server request. The text value is found by starting from the button (this), going up the dom tree (parent), find the previous tablecell (prev('td')) and look in the tablcell for the first element with the id text (children('#text')[0]). This is caught in a temporary variable that is used to extract the value. The variable self is used in the callback of the request. The request has a this variable of his own.

The request itself happens inside the ajax function. The hash of the function takes care of the different parts. The succes key of the hash is called when the server returns an ok message. To get the returned values from the server you have to catch it in a function argument (msg) and because i echoed the check php variable all i had to do is look for the 1 value. If it's 1 then the text and the button change again.

If you have read so far you deserve to see the full javascript code.

$(function(){
$('button.update').click(function(){
if($(this).attr('class') == 'updateok'){
var id = $(this).attr('value');
var textt = $(this).parent().prev('td').children('#text')[0];
var text = $(textt).attr('value');
var self = this;
$.ajax({
type: 'POST',
url: 'update.php',
data: 'updateok='+id+'&text='+text+'&js=1',
success: function(msg){
if(msg == 1){
$(self).html('Update').attr({class:'update'});
$(self).parent().prev('td').html(text);
}else{
alert('Problem changing field.');
}
}
});
}else{
if($('button.updateok').size() == 1){
$('button.updateok').html('Update').attr({class:'update'});
var text = $('#text').attr('value');
$('#text').parent().html(text);
}
$(this).html('OK').attr({class:'updateok'});
var text = $(this).parent().prev('td').html();
$(this).parent().prev('td').html('<input type="text" name="text" id="text" value="'+text+'" />');
}
return false;
});
});

The first line is called when the document is loaded. The second line is the click event interceptor function. The third line is a check if the button has the updateok class. This may seem odd because in the click function you look for the button with the update class but because the first line is only called when the page has loaded it keeps seeing the original state. Only after the click event it finds the javascript manipulated elements and their attributes.
In the end the return false statement is added so that the normal behaviour of the button is cancelled.

Conlusion



Now you have two layers of functionality that react the same and do the same with a minimal amount of code. For javascript i used more code than in php because the posting of the form in php takes work out of my hands. This code isn't finished because there is no input control but that can be added easily.

An example can be found at : Simple php/javascript in place editing

Saturday, December 16, 2006

Programmers logic

In the years i'm programming webforms i always had the instinctive idea i should penalize the user of the forms with an error message and redirecting the user back to the form. I know now that is a wrong line of thinking.

It is wrong because of two reasons
- Users need to fill in some of the fields again
- The need to program the error messages and return of entered data

In the era usability is not a buzz word but a rule to live by it's plain wrong to let the user input data again when it's not necessary.

A scenario : we have three radioboxes; good, bad, neutral. Connected to the bad radiobox are three checkboxes; very, very, very (I didn't think a lot about this).

My normal behavior would be to check if one of the checkboxes was checked. If one is look if the bad radiobox was checked. If it isn't back to the form clearing the checkboxes and radioboxes and an error message on top. This is brutal behavior. At least i could check the bad radiobox and let the checkbox stay checked but then it would be rude to redirect to the form because the only thing i do then is saying how stupid the user is.

Adding error code is another thing. It is annoying because most of the time it is basically the same code. It's the design of the site or the demand of the client that forces you to write the code in a not generic way. Because it is a user input there is always a possibility of a form of an hack attack so you have to check that too before returning the value.

Taking the scenario from above you can add a css class to the label or a message next to the label or a border around the check- and radioboxes, ... .

The best way to deal with the given scenario is to check if a checkbox is checked. If it is set the radiobox value to the bad value and let the user think they did everything good.

You can't do that with every inputfield you have. You have to balance the user/programmer decisions about the input. If some data is necessary to continue you have to set up errors but otherwise make the form filling labor as smooth as possible.

The new beginning of my programming blog

I've been neglecting this blog for a while so i'm starting again and what starts a boring blog better than humor