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
No comments:
Post a Comment