Sunday, December 21, 2008

Sortable Datagrid with Paginating Data


For this moment now I would like to discuss data grids show by browser which add by capability of data field sorting, can be an ascending or descending, beside that also add ability of data paginating, so as we want to expose a numerous of data in a browser, it don’t need scrolling anymore and replace by data paginating which divide the data into several page.

Step one is create a table tag in scope of html tag in php file which going to be expose on a browser, as an example we use 'tbl_siswa' as table on mysql database. And safe this file as 'sortable.php' and fill this file with this syntax like shown below:



<html>
<head>
<title>Editable Data Grid</title>
<script type="text/javascript" language="javascript">
<!—- Fill it with javascript -->
</script>
</head>
<body>
<form id="myForm" name="myForm" method="post">
<div class="area">
<br>
<table width="80%" cellpadding="0" cellspacing="0" border="0">
<tr><td align="right"><? //Fill it with paginating code ?></td></tr>
<tr><td align="right"> </td></tr>
</table>
<table width="80%" cellpadding="0" cellspacing="0" border="1" >
<tr>
<th width="0%"> </th>
<th width="24%" onclick="<!--Function sort-->">Nomor Induk</th>
<th width="24%" onclick="<!--Function sort-->">Nama Siswa</th>
<th width="50%" onclick="<!--Function sort-->">Alamat Lengkap</th>
</tr>
<? //Diisi kode looping data ?>
<tr>
<td> </td>
<td><? //Diisi kode php echo ?></td>
<td><? //Diisi kode php echo ?></td>
<td><? //Diisi kode php echo ?></td>
</tr>
<? //Diisi kode looping data ?>
</table>
</div>
</form>
</body>
</html>

Next thing to do is write code to query data in 'tbl_siswa' table, first we must create several variable to initialize and use it for sorting and paginating process, as follow is php code written in template file and place it in beginning of file before code like shown above, and the php code is like shown below:


<?
$fieldId = 1;
if (isset($_REQUEST['fieldId'])) {$fieldId = $_REQUEST['fieldId'];}

$lastSort = 'asc';
if (isset($_REQUEST['sort'])) {$lastSort = $_REQUEST['sort'];}

$link = mysql_connect('localhost', 'root', 'admin');
if (!$link) {die('Could not connect: ' . mysql_error());}

$link1 = mysql_select_db('latih');
if (!$link1) {die('Could not select database');}

if ($fieldId == '1') {
$field = 'no_induk';
} else if ($fieldId == '2') {
$field = 'nama';
} else if ($fieldId == '3') {
$field = 'alamat';
} else {
$field = 'no_induk';
}

$query0 = 'SELECT id, no_induk, nama, alamat FROM tbl_siswa ORDER BY '.$field.' '.$lastSort;
$resultRow = mysql_query($query0);
$num_rows = mysql_num_rows($resultRow);

$first_pages = 1; $data_content = 5;
$last_pages = ceil($num_rows / $data_content);

$increment = $first_pages;
if (isset($_REQUEST['increValue'])) {$increment = $_REQUEST['increValue'];}

// Is used limit offset mysql technique
$query1 = 'SELECT id, no_induk, nama, alamat FROM tbl_siswa ORDER BY '.$field.' '.$lastSort.' LIMIT '.$data_content.' OFFSET '.$increment;

$result = mysql_query($query0);
if (!$result) {die('Query failed: ' . mysql_error());}

// If used Array top and bottom edge technique and use it as
// temporary buffer, and split it as top and bottom edge
$idx = 0;
while ($line = mysql_fetch_array($result, MYSQL_ASSOC)) {
$showData[$idx]['no_induk'] = $line['no_induk'];
$showData[$idx]['nama'] = $line['nama'];
$showData[$idx]['alamat'] = $line['alamat'];
$idx++;
}

$firstEdge = ($data_content * $increment) - $data_content;
$lastEdge = ($data_content * $increment) - 1;
?>

After connection code follow by query code written in php, don’t forget to close the connection and place it in a bottom of that template file like shown below:


<?
mysql_free_result($result);
mysql_close($link);
?>

Don’t forget to write JavaScript code to activate sorting and paginating trigger, then place it all the JavaScript function into template file already setup before, but please remember to place it on place already mark with red color written, and if all the html template, JavaScript and php code combine will look like shown below:


<?
$fieldId = 1;
if (isset($_REQUEST['fieldId'])) {$fieldId = $_REQUEST['fieldId'];}

$lastSort = 'asc';
if (isset($_REQUEST['sort'])) {$lastSort = $_REQUEST['sort'];}

$link = mysql_connect('localhost', 'root', 'admin');
if (!$link) {die('Could not connect: ' . mysql_error());}

$link1 = mysql_select_db('latih');
if (!$link1) {die('Could not select database');}

if ($fieldId == '1') {
$field = 'no_induk';
} else if ($fieldId == '2') {
$field = 'nama';
} else if ($fieldId == '3') {
$field = 'alamat';
} else {
$field = 'no_induk';
}

$query0 = 'SELECT id, no_induk, nama, alamat FROM tbl_siswa ORDER BY '.$field.' '.$lastSort;
$resultRow = mysql_query($query0);
$num_rows = mysql_num_rows($resultRow);

$first_pages = 1;
$data_content = 5;
$last_pages = ceil($num_rows / $data_content);

$increment = $first_pages;
if (isset($_REQUEST['increValue'])) {$increment = $_REQUEST['increValue'];}

// Start of limit offset mysql technique
$query1 = 'SELECT id, no_induk, nama, alamat FROM tbl_siswa ORDER BY '.$field.' '.$lastSort.' LIMIT '.$data_content.' OFFSET '.$increment;
$result = mysql_query($query1);
if (!$result) {die('Query failed: ' . mysql_error());}

// End of limit offset mysql technique

// Start of array top and bottom edge technique
$result = mysql_query($query0);
if (!$result) {die('Query failed: ' . mysql_error());}
$idx = 0;
while ($line = mysql_fetch_array($result, MYSQL_ASSOC)) {
$showData[$idx]['no_induk'] = $line['no_induk'];
$showData[$idx]['nama'] = $line['nama'];
$showData[$idx]['alamat'] = $line['alamat'];
$idx++;
}

$firstEdge = ($data_content * $increment) - $data_content;
$lastEdge = ($data_content * $increment) - 1;

// End of array top and bottom edge technique and use it as
// temporary buffer, and split it as top and bottom edge
?>
<html>
<head>
<title>Editable Data Grid</title>
<script type="text/javascript" language="javascript">
function sortableField(par1,par2,par3) {
if (par2 == "asc") {
var lastSort = "desc";
} else if (par2 == "desc") {
var lastSort = "asc";
} else {
var lastSort = "asc";
}
document.myForm.action = "sortable.php?fieldId="+par1+"&sort="+lastSort+"&increValue="+par3;
document.myForm.submit();
}

function prev(par1,par2,par3) {
if (parseInt(par3) != 1) {
par3 = par3 - 1;
}
document.myForm.action = "sortable.php?fieldId="+par1+"&sort="+par2+"&increValue="+par3;
document.myForm.submit();
}

function next(par1,par2,par3) {
var lastPage = parseInt('');
if (parseInt(par3) != lastPage) {
par3 = par3 + 1;
}
document.myForm.action = "sortable.php?fieldId="+par1+"&sort="+par2+"&increValue="+par3;
document.myForm.submit();
}
</script>
</head>
<body>
<form id="myForm" name="myForm" method="post">
<div class="area"><br>
<table width="80%" cellpadding="0" cellspacing="0" border="0">
<tr>
<td align="right">
<?
if ($increment == $first_pages) {
echo ' prev ';
} else { ?>
<a href="#" onclick="prev(<? echo $fieldId; ?>, '<? echo $lastSort; ?>',<? echo $increment; ?>);"> prev</a>
<?}

echo $increment." of ".$last_pages;

if ($increment == $last_pages) {
echo ' next ';
} else { ?>
<a href="#" onclick="next(<? echo $fieldId; ?>, '<? echo $lastSort; ?>',<? echo $increment; ?>);"> next</a>
<? } ?>
</td>
</tr>
<tr><td align="right"> </td></tr>
</table>
<table width="80%" cellpadding="0" cellspacing="0" border="1" >
<tr>
<th width="0%">> </th>
<th width="24%" onclick="sortableField(1, '<? echo $lastSort; ?>',<? echo $increment; ?>);">Nomor Induk</th>
<th width="24%" onclick="sortableField(2, '<? echo $lastSort; ?>',<? echo $increment; ?>);">Nama Siswa</th>
<th width="50%" onclick="sortableField(3, '<? echo $lastSort; ?>',<? echo $increment; ?>);">Alamat Lengkap</th>
</tr>

<!-- If used limit offset mysql technique -->
<? while ($line = mysql_fetch_array($result, MYSQL_ASSOC)) {?>
<tr>
<td> </td>
<td><? echo $line['no_induk']; ?></td>
<td><? echo $line['nama']; ?></td>
<td><? echo $line['alamat']; ?></td>
</tr>
<? } ?>

<!-- If used array top and bottom edge technique -->
<? for ($i = 0; $i < count($showData); $i++) {
if ($i >= $firstEdge && $i <= $lastEdge) {?>
<tr>
<td> </td>
<td><? echo $showData[$i]['no_induk']; ?></td>
<td><? echo $showData[$i]['nama']; ?></td>
<td><? echo $showData[$i]['alamat']; ?></td>
</tr>
<? }
} ?>
</table>
</div>
</form>
</body>
</html>
<?
mysql_free_result($result);
mysql_close($link);
?>

From sample code above we can see two kind paginating technique written on purpose, each of technique have some advantage and lacked, if we use offset limit technique, then advantage we’ll got light weight of data loading, because paginating mechanism already handed by database server, but have a weakness on data that show on a browser always had a same limit weather on first page till end of page, for instance if we have 23 data record with limit 10, according to paging algorithm will produce 3 page with each page show 10 record except last page only show 3 record, but this couldn’t happen if used mysql limit offset technique, last page will always show 10 record, to fulfill term of limit 10 by take several record to page before last page than show it again on last page. This thing gave the effect of this program experience some error on it (probably true or false, correct me if I’m wrong..! ^__^ ).

Whereas if used array with top and bottom edge technique, then the result we going to see on browser will accord with expected algorithm, but it sacrifice of heavy weight data loading if it reach to thousand or event million of data. This cause by all record load from database on first step then filter it in php code. From this two technique within advantage and lacked, decision to used which technique is handover to developer. This image below is shown how looks like if these codes above see on a browser:

From figure above we can see paginating trigger can execute through clicked link “prev” or “next”, when browser in condition showing first page than link “prev” will disabled, and when condition showing last page then link “next” will disabled. Whereas for “ascending” and “descending” trigger from each fields, just click table header from each field then field already clicked will automatically sort. Unnecessary “asc” or “desc” properties for this sorting process cause that properties already set switch automatically every header clicked between “asc” and “desc”.

For your record this two technique name I made myself, I’m not searching yet in google for this issue weather this name exist or not (^__^V hehe.. peace). Perhaps only this knowledge I can share to all reader for this moment, if in this article contain some mistake, please don’t mind to correct me if I done some wrong or give me some advise and comment. To improve knowledge and share it to other.


Read More...

Monday, November 17, 2008

Having Game Dynamic Tabel Row with Javascript


On a world of web programming, we used to see insert, update, delete process to data in database, and so with select query into a view process using tag table and show the data’s by using script html and view it in a browser.

And now we try to research process of “Add New Row” and “Delete Row” about tag table in web-app by using javascript, why we should use javascript? Cause if we build a web sites or web application using javascript and gain some ability to process add new row or delete row in table tag without refresh, with the result that loading effort need to communicate with server might reducible, if edit process to table tag is done, and all the data’s going insert to database is correct than communication to database server could done by once insert data.

Now start to discuss step by step to get the process done, as a basic foundation we try to build it on php, foreknown this process could written on various web programming which is php, jsp, java or even .Net, but for now we only discuss it on php. Start with a file with any name *.php to shape a first page with a table on it and a link for further action, although action link to add row nor delete row. With this script shown below:




<html>
<head>
<title>Dynamic Table, Add / Delete Row</title>
</head>
<body>
<div class="area">
<div class="toolbar-clean">
<a href="javascript:addNewRow();"><span>New Row</span></a>
<a href="javascript:deleteRow();"><span>Delete Row</span></a>
</div>
<table width="80%" cellpadding="0" cellspacing="0" border="1" id="lineItemTable">
<tr>
<th width="0%"> </th>
<th width="2%" align="center">
<input type="checkbox" name="checkMaster" id="checkMaster" onClick="clickAll();"/>
</th>
<th width="24%">Nomor Induk</th>
<th width="24%">Nama Siswa</th>
<th width="50%">Alamat Lengkap</th>
</tr>
</table>
</div>
</body>
</html>

From script shown above will produce page like shown below:

After got the page like wanted, for the next step is to add javascript code into php file. This addition is to fulfill request link action “New Row” and “Delete Row” process than insert into html script tag, first we going to write function to add new row with function name “addNewRow” with all derivative function like shown below:


function addNewRow() {
var tbl = document.getElementById("lineItemTable");
var row = tbl.insertRow(tbl.rows.length);

var td0 = document.createElement("td");
var td1 = document.createElement("td");
var td2 = document.createElement("td");
var td3 = document.createElement("td");
var td4 = document.createElement("td");

td0.appendChild(generateIndex(row.rowIndex));
td1.appendChild(generateCheckBox(row.rowIndex));
td2.appendChild(generateNomorInduk(row.rowIndex));
td3.appendChild(generateNomorRegister(row.rowIndex));
td3.appendChild(generateNamaSiswa(row.rowIndex));
td4.appendChild(generateItemName(row.rowIndex));

row.appendChild(td0);
row.appendChild(td1);
row.appendChild(td2);
row.appendChild(td3);
row.appendChild(td4);
}

function generateIndex(index) {
var idx = document.createElement("input");
idx.type = "hidden";
idx.name = "index[ ]";
idx.id = "index["+index+"]";
idx.value = index;

return idx;
}

function generateCheckBox(index) {
var check = document.createElement("input");
check.type = "checkbox";
check.name = "check[ ]";
check.id = "check["+index+"]";

return check;
}

function generateNomorInduk(index) {
var idx = document.createElement("input");
idx.type = "text";
idx.name = "nomorInduk[ ]";
idx.id = "nomorInduk["+index+"]";
idx.size = "15";

return idx;
}

function generateNomorRegister(index) {
var idx = document.createElement("input");
idx.type = "hidden";
idx.name = "nomorRegister[ ]";
idx.id = "nomorRegister["+index+"]";

return idx;
}

function generateNamaSiswa(index) {
var idx = document.createElement("input");
idx.type = "text";
idx.name = "namaSiswa[ ]";
idx.id = "namaSiswa["+index+"]";
idx.size = "25";

return idx;
}

function generateItemName(index) {
var itemName = document.createElement("input");
itemName.type = "text";
itemName.name = "alamatSiswa[ ]";
itemName.id = "alamatSiswa["+index+"]";
itemName.size = "40";

return itemName;
}

From sample javascript code like show above, we can figure out process to produce new row which going to be generated, if “New Row” link clicked, generated column composition adapt with header composition, therefore when process been executed than page browser will show like figure below, and new row will continue add to the table if “New Row” link clicked continuously.

After got result like shown above, next step had to continue is adding new function to checked all checkbox in the table, so if we want to checked all the checkbox we don’t need to check one by one at the time, with this function we can check all at a time, this function written like this code below:


function clickAll() {
var checked = false;
if (document.getElementById("checkMaster").checked == true)
checked = true;

var tbl = document.getElementById("lineItemTable");
var rowLen = tbl.rows.length;
for (var idx = 1; idx < rowLen; idx++) {
var row = tbl.rows[idx];
var cell = row.cells[1];
var node = cell.lastChild;
node.checked = checked;
}
}

After the code insert into html script tag with new function “clickAll” as a name, then checkbox element placed on header can assume working properly. And if this checkbox clicked then we can see page like shown below. We can see the different between a second figure and third figure where the checkbox element clicked and not clicked.


And final step to insert function “deleteRow” which have a duty to delete row or picked row from table if necessary, this function can also to delete all row in the table with condition if all the checkbox element checked, javascript code written like shown below.



function deleteRow() {
var tbl = document.getElementById("lineItemTable");
var error = false;

if (document.getElementById("checkMaster").checked == false)
error = true;

var tbl = document.getElementById("lineItemTable");
var rowLen = tbl.rows.length;
for (var idx = 1; idx < rowLen; idx++) {
var row = tbl.rows[idx];
var cell = row.cells[1];
var node = cell.lastChild;
if (node.checked == true) {
error = false;
break;
}
}

if (error == true) {
alert ("Checkbox tidak di cek, proses tidak dapat dilanjutkan");
return;
}

if (document.getElementById("checkMaster").checked == true) {
deleteAll();
document.getElementById("checkMaster").checked = false;
} else {
var table = document.createElement("table");
bufferRow(table);
deleteAll();
reIndex(table);
}
}

function deleteAll() {
var tbl = document.getElementById("lineItemTable");
var rowLen = tbl.rows.length - 1;
for (var idx = rowLen; idx > 0; idx--)
tbl.deleteRow(idx)
}

function bufferRow(table) {
var tbl = document.getElementById("lineItemTable");
var rowLen = tbl.rows.length;
for (var idx = 1; idx < rowLen; idx++) {
var row = tbl.rows[idx];
var cell = row.cells[1];
var node = cell.lastChild;
if (node.checked == false) {
var rowNew = table.insertRow(table.rows.length);

var td0 = document.createElement("td");
var td1 = document.createElement("td");
var td2 = document.createElement("td");
var td3 = document.createElement("td");
var td4 = document.createElement("td");

td0.appendChild(row.cells[0].lastChild);
td1.appendChild(row.cells[1].lastChild);
td2.appendChild(row.cells[2].lastChild);
td3.appendChild(row.cells[3].firstChild);
td3.appendChild(row.cells[3].lastChild);
td4.appendChild(row.cells[4].lastChild);

rowNew.appendChild(td0);
rowNew.appendChild(td1);
rowNew.appendChild(td2);
rowNew.appendChild(td3);
rowNew.appendChild(td4);
}
}
}

function reIndex(table) {
var tbl = document.getElementById("lineItemTable");
var rowLen = table.rows.length;
for (var idx=0;idx < rowLen;idx++) {
var row = table.rows[idx];
var rowTbl = tbl.insertRow(tbl.rows.length);

var td0 = document.createElement("td");
var td1 = document.createElement("td");
var td2 = document.createElement("td");
var td3 = document.createElement("td");
var td4 = document.createElement("td");

td0.appendChild(row.cells[0].lastChild);
td1.appendChild(row.cells[1].lastChild);
td2.appendChild(row.cells[2].lastChild);
td3.appendChild(row.cells[3].firstChild);
td3.appendChild(row.cells[3].lastChild);
td4.appendChild(row.cells[4].lastChild);

rowTbl.appendChild(td0);
rowTbl.appendChild(td1);
rowTbl.appendChild(td2);
rowTbl.appendChild(td3);
rowTbl.appendChild(td4);
}
}

As seen on javascript “deleteRow” function, we can figure validate process before delete command executed in line 4th until 22nd to checking neither checkbox element are checked or not, if at least just one checkbox are checked then this process can be executed, but if non of this element are checked then process will stop and continue with alert in browser like shown below:


Perhaps only this knowledge I can share to all reader for this moment, if in this article contain some mistake, please don’t mind to correct me if I done some wrong or give me some advise and comment. To improve knowledge and share it to other.


Read More...

Wednesday, November 5, 2008

ASCII code manipulate with Java Runtime

The idea of this article beginning when the company I worked now need some utility command to build connectivity between the application which is build in java platform connect to hardware. To gain connectivity to hardware tools we need command line in ASCII code as like this “alt+27, alt+112, alt+48, alt+62, alt+76, alt+80, alt+84, alt+49”, if we use this line syntax using command prompt M$ DOS, before the main command first we must write command “echo” + space followed by these ASCII code, after hit the enter button then command running and hopefully the hardware can response to that command line.

By using this ASCII code list as reference, than we get ASCII code that needed to accessing this hardware:



Be sides of ASCII code that often use in daily programming like in table above, there is another ASCII code is rare used in daily programming, this reference table below is shown ASCII code that represent symbol and line character:

After knowing ASCII code for hardware specification, and now time to figure out how to connect ASCII code to command line in Java, that is using Runtime command from “java.lang.Runtime”, with complete command write like this “Runtime.getRuntime().exec(‘this ASCII code written to be execute’);” with return value class Process from “java.lang.Process” than initialize into “p” object, from that object we can got this command “p.waitFor();” with aiming the system will wait until this command to hardware is come to end, as the following source code as an example how to use ASCII code to Runtime command. But don’t forget to write this line “cmd /c” before “echo” syntax if you try to execute it on windows, to call DOS command prompt.

StringBuffer strNew = new StringBuffer();
strNew.append(new Character((char)27));
strNew.append(new Character((char)112));
strNew.append(new Character((char)48));
strNew.append(new Character((char)62));
strNew.append(new Character((char)76));
strNew.append(new Character((char)80));
strNew.append(new Character((char)84));
strNew.append(new Character((char)49));

Process p = Runtime.getRuntime().exec("cmd /c echo "+strNew.toString());
p.waitFor();
Perhaps for this moment this knowledge that I can share to all reader, if in this article contain some mistake, please don’t mind to correct me if I done some wrong or give me some advise and comment.

Read More...

Hello Blogger

Hi..
This is my third blog, but i rather to write this blog in english, with purpose to sharpen my english skill, so if all among the reader find any mistake on my write, feel free to correct me.

Best Regard


Agien
Read More...

Monday, October 27, 2008

“Non-terminating decimal expansion” How could this occurred?

For some people already familiar with Java might used to hear or experience this event. With slightly experiment, I’ll try to calculate some numeric variable using BigDecimal as java type variable, if we’ll do some process with addition, alleviation, mulitiplication and division by using BigDecimal command method we can use these syntax “add()”, “substract()”, “multiply()” and “divide()” to complete, all these process could worked like expected, but these process could produce some error if we do some process with alleviation using command syntax “divide” which is produce return value with fraction or value with decimal place, and an error view that produce by these process if we used command syntax “printStackTrace” could be like this.

java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.
at java.math.BigDecimal.divide(BigDecimal.java:1514)





at java.lang.Thread.run(Thread.java:619)


Necessary to know if we used some framework in our project, any framework, than content of some dot in error view above will figure printStackTrace message relate on that framework. This thing could occurred in alleviation processed. We can use this calculate process syntax bellow as example source code:

public class SuatuClass {
static BigDecimal bilAwal = BigDecimal.valueOf(10);
static BigDecimal bilAkhir = BigDecimal.valueOf(15);
static BigDecimal hasilBagi = BigDecimal.valueOf(0);

public static void main(String[] args) {
divideOperation();
}

public static void divideOperation() {
hasilBagi = bilAwal.divide(bilAkhir);

System.out.println("Print Hasil Akhir "+ hasilBagi);
}
}

And now we’ll try focus our attention to a line of this source code “bilAwal.divide(bilAkhir);” if return value from calculation is a fraction than it’ll produce error view like printStackTrace above, and now, how to breaking the ice? “Gampang.. Ketik reg spasi manjur kirim ke……” Hehe.. Just kidding (Indonesian joke style), if we want result value produce by this process is an integer than a line of source code should change into like this “bilAwal.divide(bilAkhir ,RoundingMode.HALF_UP);” property HALF_UP will produce value which rounded up if fraction value behind decimal point is greater than 0.5, for better explanation we can see a table to figure some property and utility in a class RoundingMode below:


For a better clear view about utility and property of RoundingMode can see on this link: http://java.sun.com/j2se/1.5.0/docs/api/java/math/RoundingMode.html.

If we still want a fraction value behind decimal point than a command line syntax that shows above need some change to fulfill requirement with divide command like shown below “bilAwal.divide(bilAkhir, 3, RoundingMode.HALF_UP);” numeric value which place in the middle of three parameter has a function to determine amount of number behind a decimal point should place on result value, source code shown above if we like to place three digit number as fraction behind decimal point.

For a better clear view about utility and property of BigDecimal can see on this link: http://java.sun.com/j2se/1.5.0/docs/api/java/math/BigDecimal.html.

Perhaps for this moment this knowledge that I can share to all reader, if in this article contain some mistake, please don’t mind to correct me if I done some wrong or give me some advise and comment.


Read More...