วันอังคารที่ 11 ตุลาคม พ.ศ. 2554

curl proxy

<?php

$ch = curl_init("http://www.google.com");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_PROXY, "192.168.0.1");
curl_setopt($ch, CURLOPT_PROXYPORT, 808);
$x = curl_exec($ch);
curl_close($ch); 

echo $x;
?> 
ถ้าเล่นเน็ตต่อผ่าน proxy จะดึงข้อมูลจากเว็บอื่นโดยตรงไม่ได้ แต่ก็ทำได้โดยต่อผ่าน proxy เช่นเดียวกันครับ

วันพฤหัสบดีที่ 11 สิงหาคม พ.ศ. 2554

jquery plugin and ajax request

โดยปกติ page ที่ถูกเรียกด้วยวิธี ajax รูปแบบ html ไม่ควรมีโค้ด javascript ปนในนั้นครับ

ตัวอย่างที่ไม่ดีนะครับ ผิดเนื่องจากมี javascript ใน page1.php
และที่ผิดอย่างเห็นได้ชัดเลยคือมีการเรียก jquery.js สองครั้งประกาศตัวแปรฯลฯ function สองครั้ง
และ request ซ้ำอีกก็จะประกาศซ้ำเป็นหลายครั้งจะทำให้เกิดปัญหาครับ


// page1.php
<script src="jquery.js"></script>
<script src="jquery.datepicker.js"></script>
<script>
$(function(){
$('#d').datepicker();
});
</script>
<input id="d" type="text"/>

// index.php
<script src="jquery.js"></script>
<script>
$(function(){
$('#test').load('page1.php');
});
</script>
<div id="test"></div>

===================================================

ถ้าต้องการให้ทำงานไม่มีปัญหานะครับจะต้องใช้วิธี request page1.php ซึ่งมีแค่ html
และให้ไฟล์ผู้เรียก (index.php) ใช้คำสั่งควบคุมแทน


// page1.php

<input id="d" type="text">

// index.php
<script src="jquery.js"></script>
<script src="jquery.datepicker.js"></script>
<script>

$('#test').load('page1.php',function(){
$('#d').datepicker(); //หลังจากใส่ html page1.php ใน index.php แล้วเรียกคำสั่ง plugin อีกครั้ง
});
</script>
<div id="test"></div>

วันพุธที่ 8 มิถุนายน พ.ศ. 2554

เทคนิคที่สำคัญของ css

กฎของ css box medel:
- block เป็นรูปสี่เหลี่ยม ทุก element สามารถเป็น block
- ขนาดและตำแหน่งของ block คำนวณได้จาก width,height,padding,borders และ margins
- ถ้าไม่ได้ระบุความสูง block element จะสูงเท่ากับ content ภายในของมันบวกกับ padding ยกเว้นแต่ content ของมัน float
- ถ้าไม่ได้ระบุความกว้าง, กล่องที่ไม่ float จะขยายความกว้างเท่ากับความกว้างลบด้วย padding ของกล่องที่ครอบมันอยู่ชั้นแรก

สิ่งที่ควรจำให้ขึ้นใจเกี่ยวกับการทำงานกับ element ในรูปแบบ block
- ถ้า box มีขนาด width เท่ากับ 100% มันไม่ควรจะมี margin,padding หรือ borders ไม่ง้นมันจะเกินขนาดกล่องที่ครอบตัวมัน
- margin ในแนวตั้งสามารถจะทำให้เกิดปัญหาเกี่ยวกับขนาดถูกหุบลงซึ่งทำให้เกิดปัญหากับโครงสร้างของเว็บไซท์
- position แบบ relative แล absolute จะมีพฤติกรรมต่างกันขึ้นอยู่กับสภาพแวดล้อมรอบๆ
- กฎและหลักการนี้จะถูกต้องเมื่อหน้าซึ่งแสดง block อยู่ในรูปแบบมาตรฐาน
http://www.blogger.com/img/blank.gif
เพิ่มเติม
- float block จะไม่สามารถใช้ vertical-align อย่างเช่น middle

reference

http://www.nicollet.net/2010/02/reusable-css/ http://www.contentwithstyle.co.uk/content/modular-css/

http://www.charlescooke.me.uk/web/lab_notes/ie7_script.html
http://code.google.com/p/ie7-js/

the-principles-of-cross-browser-css-coding/


http://reference.sitepoint.com/css/collapsingmargins
15-techniques-and-tools-for-cross-browser-css-coding

http://www.noupe.com/design/101-css-techniques-of-all-time-part-1.html

http://www.nicollet.net/2010/02/reusable-css/

http://cssdesignpatterns.com/

http://www.alanayoub.com/modular-css/

http://coding.smashingmagazine.com/2008/08/13/top-10-css-table-designs/


http://onwebdev.blogspot.com/2011/01/css-design-patterns.html

http://net.tutsplus.com/tutorials/html-css-techniques/which-css-grid-framework-should-you-use-for-web-design/

http://coding.smashingmagazine.com/2007/09/21/css-frameworks-css-reset-design-from-scratch/

http://net.tutsplus.com/tutorials/html-css-techniques/10-principles-of-the-css-masters/

http://lesscss.org/

http://www.devwebpro.com/9-top-css-essential-skills-that-every-web-designer-should-learn/

http://www.tripwiremagazine.com/2009/06/7-new-essential-css-3-techniques-revealed.html

http://www.webdesignerdepot.com/2009/05/10-best-css-practices-to-improve-your-code/

http://www.evotech.net/blog/2007/04/css-best-practices/

http://coding.smashingmagazine.com/2007/05/10/70-expert-ideas-for-better-css-coding/

http://net.tutsplus.com/tutorials/html-css-techniques/30-css-best-practices-for-beginners/

http://www.instantshift.com/2010/03/15/47-css-tips-tricks-to-take-your-site-to-the-next-level/

http://sixrevisions.com/css/12-common-css-mistakes-web-developers-make/

http://www.learn-css-tutorial.com/CSS-Best-Practices.cfm

http://meyerweb.com/eric/tools/css/reset/

โปรแกรมช่วยเขียน CSS :  Rapid CSS Editor

วันพฤหัสบดีที่ 5 พฤษภาคม พ.ศ. 2554

php sorting head builder class by num


<?php
/**
* Sorting Head Builder For Dynamic Table
*
* @author Num
* @link http://web-programming-bookmark.blogspot.com
*/
class SortHead
{
protected $ccol = '';
protected $cdir = '';
protected $ncol = '';
protected $ndir = '';
protected $dfcol = '';
protected $dfdir = '';
protected $cols = array();
public $col = '';
public $dir = '';
public function __construct(array $cols,$cname,$dname,$dfcol,$dfdir){
$this->cols = $cols;
$this->dfcol = $dfcol;
$this->dfdir = $dfdir;
$this->ncol = $cname;
$this->ndir = $dname;
$this->ccol = $this->current_col();
$this->cdir = $this->current_dir($this->ccol,$dfdir);
$this->col = $this->ccol;
$this->dir = $this->cdir;
}
public function current_col(){
$ccol = empty($_GET[$this->ncol]) ? $this->dfcol : $_GET[$this->ncol];
$k = array_search($ccol,$this->cols,true);
return ($k === false) ?$this->dfcol :$this->cols[$k];
}
public function current_dir($col,$dfdir='desc'){
$odir = $dfdir == 'desc' ?'asc' :'desc';
if ($this->ccol == $col){
$dir = empty($_GET[$this->ndir]) ?$dfdir :$_GET[$this->ndir];
if ($dir != 'asc' && $dir != 'desc') $dir = 'desc';
$dir = $dir == 'desc' ?'desc' :'asc';
}else{
$dir = $dfdir;
}
return $dir;
}
public function next_dir($col,$dfdir='desc'){
$odir = $dfdir == 'desc' ?'asc' :'desc';
if ($this->ccol == $col){
$dir = empty($_GET[$this->ndir]) ?$dfdir :$_GET[$this->ndir];
if ($dir != 'asc' && $dir != 'desc') $dir = 'desc';
$dir = $dir == 'desc' ?'asc' :'desc';
}else{
$dir = $dfdir;
}
return $dir;
}
public function link($col,$dfdir='desc'){
$dir = $this->next_dir($col,$dfdir);
return '?'.$this->ncol.'='.$col.'&'.$this->ndir.'='.$dir;
}
public function dir($col,$dfdir='desc'){
return $this->current_dir($col,$dfdir);
}
}

$sh = new SortHead(array('name','title','id'),'st','sd','id','desc');

//safe for query
echo ', field=',$sh->col;
echo ', dir=',$sh->dir;
echo ', select * from tb order by '.$sh->col.' '.$sh->dir;

?>

<table border="1" cellpadding="10" cellspacing="0">
<tr>
<td>
<a href="<?php echo $sh->link('name','asc') ?>">name <?php echo $sh->dir('name','asc') ?></a>

</td>
<td>
<a href="<?php echo $sh->link('title') ?>">title <?php echo $sh->dir('title') ?></a>
</td>
<td>
<a href="<?php echo $sh->link('id') ?>">id <?php echo $sh->dir('id') ?></a>

</td>
</tr>
</table>

วันจันทร์ที่ 11 เมษายน พ.ศ. 2554

sql profiler

http://sites.google.com/site/sqlprofiler/

try catch

ภาษาโปรแกรมซึ่งค่อนข้างใหม่มักจะมีคำสั่ง try catch

คำสั่งนี้ถ้าจะเรียกตรงๆ อาจจะเรียกว่าคำสั่ง
try ... catch ....
ลองทำ .... ถ้าเจอปัญหาก็ให้ทำ .... ด้วย

คุณสมบัติของคำสั่งนี้ก็เพื่อดัก error แปลกๆ ที่ดักโดยใช้คำสั่งตรวจสอบเงื่อนไขธรรมดาได้ยากหรือไม่ได้เลย
และหาวิธีจัดการกับ error ครับเช่น

ในการเขียน embedded database query ในภาษาโปรแกรม
มักจะเกิด database integrity error อย่างเช่น key ซ้ำ, รูปแบบข้อมูลไม่ตรงกับ field ซึ่งคำสั่ง try catch ก็จะช่วยให้เราจัดการกับ error นี้ได้เหมาะสมเช่นถ้า key ซ้ำเราอาจจะสร้าง key ขึ้นมาใหม่และทำการ insert อีกครั้ง

parse error ข้อมูลรูปแบบไม่ถูกต้องเช่น string แปลงเป็นวันที่ไม่ได้ ฯลฯ
ถ้าเกิด error เราก็อาจจะกำหนดค่าของตัวแปรเป็นค่า default ที่เราตั้งขึ้น

divide by zero การคำนวณที่เกิดข้อผิดพลาดจะทำอย่างไรเมื่อเกิดปัญหานี้ บางครั้งตัวเลขที่มาคำนวณอาจมีหลายตัว
การดักการหารด้วยศูนย์จะต้องเขียนซับซ้อน การใช้ try catch จะทำได้สะดวกกว่า

try
{
$i = 1/$x;
}catch(Exception $e){
//จัดการกับ error ด้วยวิธีต่างๆ
$i = -1;
}

วันพฤหัสบดีที่ 10 มีนาคม พ.ศ. 2554

adodb class tutorial

adodb class เป็นคลาสที่ช่วยให้เขียนโปรแกรมติดต่อ database ง่ายขึ้นครับ
นอกจากนี้แล้วยังช่วย escape input เพื่อป้องกัน sql injection
และเป็น database layer ถ้าเขียนติดต่อ database ใน adodb ก็จะช่วยให้ย้ายไป database อื่นได้ง่ายขึ้นแก้ไขน้อยกว่าครับ

เริ่มต้นให้ download adodb มีหลายเวอร์ชั่นครับเลือกเอาเวอร์ชั่นที่ต้องการมาไฟล์ไฟล์เดียวครับ
http://sourceforge.net/projects/adodb/files/

<?php

//config
$conf = array();
$conf['username'] = 'root';
$conf['password'] = '12345';
$conf['host'] = 'localhost';
$conf['db'] = 'test';
$conf['driver'] = 'mysqli'; //เลือกเป็น mysqli เพื่อจะได้ใช้งาน transaction ใน adodb class ได้

//setup and connect to db
require 'adodb/adodb.inc.php'; //เปลี่ยน path ไปยังไฟล์ adodb.inc.php ให้ถูกต้อง
$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
$db = ADONewConnection($conf['driver']);
$db->Connect($conf['host'], $conf['username'], $conf['password'], $conf['db']);
$rs = $db->Execute('SET NAMES UTF8');

//create test data
$row = $db->GetRow("SHOW TABLES LIKE 'guestbook_test2'");
if (empty($row)){
$db->Execute(
'CREATE TABLE guestbook_test2 ('.
'id int(10) unsigned NOT NULL AUTO_INCREMENT,'.
'name varchar(20) NOT NULL,'.
'detail text NOT NULL,'.
'PRIMARY KEY (id)'.
')'
);
if ($db->ErrorNo()){
die($db->ErrorMsg());
}
echo 'create table successfully.<br>';
srand();
foreach(range(1,100) as $a){
$id = null; //insert id=null, update $id = id value
$name = md5(rand(1,10000));
$detail = sha1(rand(1,10000));
$db->Replace('guestbook_test2',compact('name','detail','id'),'id',true);
}
echo 'insert data successfully.<br>';
}

//pagination
$limit = 10;
$page = empty($_GET['page']) ? 1 : (int)$_GET['page'];

$rs = $db->PageExecute("SELECT * FROM guestbook_test2", $limit, $page);
$page_row_count = $rs->RowCount();
$row_count = $rs->MaxRecordCount();
$page_count = $rs->LastPageNo();
$rows = $rs->GetRows();
$rs->Close();

//test Execute and FetchRow
$select_id = 11;
$select_id2 = 15;
$rs = $db->Execute("SELECT * FROM guestbook_test2 WHERE id=? OR id=?", array($select_id,$select_id2));
$data = array();
while($row = $rs->FetchRow()){
$data[] = $row;
}

//test GetAssoc
$data2 = $db->GetAssoc("SELECT id,name FROM guestbook_test2 WHERE id BETWEEN ? AND ?",array(51,52));

//close connection
$db->Close();

?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=tis-620" />
<title>adodb tutorial</title>
</head>
<body>

<!-- records of this page -->
<?php foreach($rows as $row):?>
<?php echo $row['id'],': ',$row['detail'],' ...... by <b>',$row['name'],'</b>';?>
<hr />
<?php endforeach;?>

<!-- page links -->
<?php for($i=1; $i<=$page_count; $i++):?>
<a href="?page=<?php echo $i;?>"><?php echo $i;?></a>
<?php endfor;?>

<hr />
<!-- records of select_id1, select_id2 -->
<?php foreach($data as $row):?>
<?php echo $row['id'],': ',$row['detail'],' ...... by <b>',$row['name'],'</b>';?>
<hr />
<?php endforeach;?>

<!-- records of 51 to 52 -->
<?php foreach($data2 as $id=>$value):?>
<?php echo $id,': ',$value,'</b>';?>
<hr />
<?php endforeach;?>

</body>
</html>

วันพฤหัสบดีที่ 3 มีนาคม พ.ศ. 2554

mod_rewrite

แทรก directive ลงใน httpd.conf เพื่อเก็บ log เวลา mod_rewrite ทำงาน
(เพื่อตรวจสอบการเขียน mod_rewrite ให้ถูกต้อง)
แล้ว restart apache ถ้าไม่ขึ้นอาจเกิดจากยังไม่ได้ติดตั้ง mod_rewrite หรือ path ชี้ไปยังไฟล์ที่จะให้เขียน log
RewriteLog "C:/xampp/htdocs/sp/rewritelog.txt"
RewriteLogLevel 9

ตัวอย่างการเขียน
1) ไฟล์ที่ชื่อ t.php ไ่ม่ว่าอยู่ระดับหรือโฟลเดอร์ไหนก็ตาม
ให้เปลี่ยนเป็นการ reqeust ไฟล์ /sp/test/s.php
เช่น
RewriteRule t.php /sp/test/s.php
เมื่อเขียนคำสั่งตามนี้แล้วในไฟล์ .htaccess จะทำให้เมื่อ request url
http://localhost/t.php
http://localhost/test/t.php
จะเป็นการ request url
http://localhost/sp/test/s.php
โดยจะเป็นการ request แบบซ่อน path ที่แท้จริง
คือแสดงข้อมูลของ s.php ส่วน url ยังคงเป็น ของ t.php เช่นเดิม
ต่างจากการ redirect ซึ่งจะแสดง url ที่แท้จริงนั่นก็คือ s.php

2) ไฟล์และรูปแบบ request ใดๆ ยกเว้นไฟล์ที่ชื่อ s.php จะถูกแปลงเป็นการเรียก request /sp/test/s.php?page=ไฟล์และรูปแบบการ request ในครั้งแรก
เช่น
RewriteRule s.php$ - [L]
RewriteRule (.*) /sp/test/s.php?page=$1
เมื่อเขียนคำสั่งตามนี้แล้วในไฟล์ .htaccess จะทำให้เมื่อ request url
http://localhost/t.php
http://localhost/test/t.php

เราสามารถใช้ RewriteCond ช่วยให้ได้ผลเหมือนข้างบนได้
RewriteCond %{REQUEST_URI} !(s.php)
RewriteRule (.*) /sp/test/s.php?page=$1

seo-url-mod-rewrite-htaccess/

วันพฤหัสบดีที่ 17 กุมภาพันธ์ พ.ศ. 2554

jquery Stop Propagation

ลำดับการเกิด event จาก element หนึ่งๆ จะเริ่มต้นจาก elment ด้านใน หรือด้านนอก ในแต่ละ browser จะต่างกัน
แต่ jquery จะกำหนดให้ลำดับการเกิดแบบ Event bubbling นั่นคือเริ่มจากด้านในก่อน
(โดยทั่วไปนะแต่อาจมีเทคนิคพิเศษที่ทำให้ลำดับการเกิด event เปลี่ยน)
http://www.quirksmode.org/js/events_order.html
http://api.jquery.com/bind/



<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.0/jquery.js"></script>
<script type="text/javascript">
//<![CDATA[
$(function(){
$('#xxx').click(function(event){
alert('div event');
});
$('#xxx button').click(function(event){
alert('button event');
if (confirm('stop next event?'))
return false;
});
});
//]]>
</script>
</head>
<body>

<div id="xxx">
###<button>button in div</button>###
</div>

</body>
</html>


selector จะใช้สำหรับการเลือก element ครับ
แต่ถ้าจะจัดการกับ event ที่มี element ที่คาบเกี่ยวกัน (ซ้อนทับกัน)
แค่ selector ยังไม่พอครับ เพราะ event handler
ของตัวที่คลุมอยู่ก็กระทบกับตัวที่อยู่ข้างในมันด้วย จึงต้องใช้คำสั่ง stop propagation ควบคุมอีกทีหนึ่ง

การใช้คำสั่ง return false; ข้างบนี้จะเทียบได้กับ preventDefault(); และ stopPropagation(); พร้อมๆ กันครับ

stopPropagation()
preventDefault()

วันอังคารที่ 1 กุมภาพันธ์ พ.ศ. 2554

jQuery ช่วยส่งข้อมูลแบบ Cross Domain ง่ายนิดเดียว

การส่งค่า AJAX ไปยัง server side script ที่อยู่คนละโดเมนกับไฟล์ที่รีเควสท์ browser ต่างๆ จะไม่อนุญาติให้ทำเนื่องจากเหตุผลทางด้าน security
โดยทั่วไปจะแก้ปัญหาใช้วิธีรีเควสท์ AJAX ผ่านทาง Proxy แต่วิธีนี้ต้องใช้คำสั่งจำพวก
open remote file ถ้าใช้เว็บโฮสฟรีก็หมดสิทธิใช้คำสั่งพวกนี้เพราะมักจะถูกกันเอาไว้ไม่ให้ใช้

แต่มีอีกทางเลือกหนึ่งเป็นเทคนิคในการแทรก script tag ลงไปพร้อมกับตั้ง src ให้เป็น url ของไฟล์ที่มีฟอร์แมท JSONP
ทำให้เราสามารถเอาข้อมูลมาใช้งานได้เลย
ฟอร์แมทของ JSONP สรุปง่ายๆ เลยก็คือเป็น statement ของการ call function ธรรมดาๆ นี่เอง
โดยมี agument อยู่ในรูปแบบ JSON
เช่น callbackfunction({"name":"hello world"}); เป็นการส่ง argument
ไปให้กับ function ที่ชื่อว่า callbackfunction ดังนั้นเมื่อเราสร้าง function ที่ชื่อว่า callbackfunction อยู่ก่อนแล้ว
function callbackfunction(e){
alert(e.name); //แสดง hello world (จะทำงานทันทีหลังจากโหลด JSONP เรียบร้อย)
}
เราก็สามารถดึงเอา argument ที่ได้ server ส่งมาให้ได้โดยง่าย

เมื่อเราเรียกคำสั่ง $.ajax และกำหนด dataType เป็น jsonp
jQuery จะเปลี่ยนจากการรีเควสท์ AJAX เป็นการแทรก tag script ดังกล่าวข้างต้นให้โดยอัตโนมัติ
ทำให้เราสามารถรีเควสข้อมูลแบบ GET ผ่านทาง script tag ได้ราวกับการรีเควส AJAX ตามปกติ

test.php
<html>
<head>

<meta http-equiv="Content-Type" content="text/html; charset=TIS-620" />
<title>JSONP</title>
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
<script type="text/javascript">

$(function(){
 $("#jsonp-request").click(function(e){
   $.ajax({
     url:'http://goldxp.thport.com/jquery/jsonpdata.php',
   type:'GET',
   dataType:'jsonp', //ตรงนี้ทำให้สามารถ cross domain ได้
   dataCharset:'jsonp',
     success:function(e){
    alert("jsonp data="+e[0].name);
   }
   });
   e.preventDefault();
 });
});

</script>

</head>
<body>
    <a href="#" id="jsonp-request">JSONP-Request</a>
</body>
</html>



jsondata.php
<?php echo $_GET['callback']?>([{"name" : <?php echo rand(1,1000);?>}]);    



เนื่องจากเป็นการเรียกข้ามโดเมนจึงมีเรื่องต้องระวังเรื่องความปลอดภัยเพิ่มขึ้นดังนี้ครับ
1) ฝั่ง server ถ้าจะรับข้อมูลจาก client เอาไปบันทึก แม้ว่าจะเชื่อถือ http referer ไม่ค่อยได้
แต่อย่างน้อยก็ควรจะตรวจสอบ http referer เพื่อกันการยิ่งข้อมูลมั่วๆ เข้ามา
2) ฝั่ง client ถ้าไม่ได้ตรวจสอบ json ให้ละเอียดว่าเป็นข้อมูลอย่างเดียวไม่มีคำสั่งปนเข้ามา
จะต้องรับข้อมูล json, jsonp หรือ javascript จาก server ที่น่าเชื่อถือเท่านั้น
เพราะอาจจะมีการแทรกคำสั่ง javascript เข้ามาใน json ได้เหมือนกันยกตัวอย่างเช่น
callbackfunction(function(){alert('test');}());
สำหรับ json ยังพอที่จะตรวจสอบข้อมูลได้ก่อนจะเรียกคำสั่ง eval(response_text)
แต่ jsonp ที่เรียกผ่านทาง tag script เป็นคำสั่งโดยตรงเลย
ดังนั้นควรจะรับข้อมูล jsonp ก็เฉพาะเว็บไซท์ที่น่าเชื่อถือเท่านั้นครับ

วันจันทร์ที่ 24 มกราคม พ.ศ. 2554

jquery prepend and prependTo


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=tis-620" />
<title>prepend and prependTo</title>
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
<script>
//<![CDATA[
$(function(){
$('#button1').click(function(){
//method 1, append
var new_data = '<div>'+$('#data').val()+'</div>';
var container_el = $('#container').prepend(new_data);
alert(container_el.attr('id'));
});
$('#button2').click(function(){
//method 2, appendTo
var new_data = '<div class="t">'+$('#data').val()+'</div>';
var new_data_el = $(new_data).prependTo('#container');
alert(new_data_el.attr('class'));
});
});
//]]>
</script>
</head>

<body>

<div id="container">
<div id="a">#</div>
<div id="b">#</div>
<div id="c">#</div>
<div id="d">#</div>
<div id="e">#</div>
</div>

<input type="text" id="data" value="test"/>
<button id="button1">button1 prepend</button>
<button id="button2">button2 prependTo</button>

</body>
</html>

jquery append and appendTo


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=tis-620" />
<title>append and appendTo</title>
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
<script>
//<![CDATA[
$(function(){
$('#button1').click(function(){
//method 1, append
var new_data = '<div>'+$('#data').val()+'</div>';
var container_el = $('#container').append(new_data);
alert(container_el.attr('id'));
});
$('#button2').click(function(){
//method 2, appendTo
var new_data = '<div class="t">'+$('#data').val()+'</div>';
var new_data_el = $(new_data).appendTo('#container');
alert(new_data_el.attr('class'));
});
});
//]]>
</script>
</head>

<body>

<div id="container">
<div id="a">#</div>
<div id="b">#</div>
<div id="c">#</div>
<div id="d">#</div>
<div id="e">#</div>
</div>


<input type="text" id="data" value="test"/>
<button id="button1">button1 append</button>
<button id="button2">button2 appendTo</button>

</body>
</html>

วันจันทร์ที่ 17 มกราคม พ.ศ. 2554

javascript เปลี่ยนเป็น tab เป็น enter

โค้ด javascript เปลี่ยน tab เป็น enter ครับ

<html>
<head>
<script>
function handleEnter(event){
var e=window.event?window.event:event;
var keyCode=e.keyCode?e.keyCode:e.which?e.which:e.charCode;
if (keyCode == 13){
if (this.className && this.className=='last'){
this.form.submit();
return true;
}
var i;
for (i = 0; i < this.form.elements.length; i++)
if (this == this.form.elements[i])
break;
if (this.type=='textarea' && e.shiftKey)
return true;
else if (this.type=='radio')
this.form.elements[i+this.form.elements[this.name].length].focus();
else
this.form.elements[i+1].focus();
return false;
}
else
return true;
}

window.onload=function(){
var a=document.formA;
for(var i=0;i<a.elements.length;i++){
var e=a.elements[i];
e.onkeypress=handleEnter;
}
}

</script>
</head>
<body>
<?php echo 'random='.rand(1,200); ?>

<form name="formA">
<input type="text" />
<input type="text" />
<input type="text" />
<input type="text" />
<input type="text" class='last' />
<input type="submit" value="submit" />
</form>

</body>
</html>


inline update by num


<?php
if ($_SERVER['REQUEST_METHOD'] == 'POST' && $_GET['action'] == 'approve'){
$id = intval(@$_GET['id']);
echo 'update tb1 set APPROVE=1 where id='.$id;
//you will do real update yourself.
die;
}
if ($_SERVER['REQUEST_METHOD'] == 'POST' && $_GET['action'] == 'unapprove'){
$id = intval(@$_GET['id']);
echo 'update tb1 set APPROVE=0 where id='.$id;
//you will do real update yourself.
die;
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=tis-620" />
<title>inline update by num</title>
<style type="text/css">
* {margin:0;padding:0}
tr.checked {background-color:#ccc;}
#tb tr.orange {background-color:#F90;}
</style>
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
<script>
//<![CDATA[
$(function(){
$('.approve:checked').parents('tr').addClass('checked');
$('.approve').click(function(e){
var tr = $(this).parents('.tr');
var record_id = $(this).val();
tr.addClass('orange');

//set to valid
if ($(this).is(':checked')){
if (confirm('set to valid?')){
$.ajax({ //ajax update
url:'?action=approve&id='+record_id,
type:'POST',
dataType:'html',
success:function(data){
alert(data);
tr.removeClass('orange').addClass('checked');
}
}); //end ajax update
}else{
e.preventDefault();
tr.removeClass('orange').removeClass('checked');
}
}

//set to invalid
if (!$(this).is(':checked')){
if (confirm('set to invalid?')){
$.ajax({ //ajax update
url:'?action=unapprove&id='+record_id,
type:'POST',
dataType:'html',
success:function(data){
alert(data);
tr.removeClass('orange').removeClass('checked');
}
}); //end ajax update
}else{
e.preventDefault();
tr.removeClass('orange').addClass('checked');
}
}

});
});
//]]>
</script>
</head>

<body>

<table border="1">
<tbody id="tb">
<tr class="tr"><td>###### 1</td><td><input type="checkbox" value="1" class="approve" /></td></tr>
<tr class="tr"><td>###### 2</td><td><input type="checkbox" value="2" class="approve" /></td></tr>
<tr class="tr"><td>###### 3</td><td><input type="checkbox" value="3" class="approve" checked="checked" /></td></tr>
</tbody>
</table>

</body>
</html>

วันเสาร์ที่ 15 มกราคม พ.ศ. 2554

delete record confirmation by num


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=tis-620" />
<title>delete record confirmation by num</title>
<style type="text/css">
* {margin:0;padding:0}
tr.selected {background-color:#ccc;}
</style>
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
<script>
//<![CDATA[
$(function(){
$('.del').click(function(e){
e.preventDefault();
$(this).parents('.tr').addClass('selected');
if (confirm('delete?')){
//ajax delete
//var id = $(this).attr('rel');
//$.post('delete-action.php?id='+id);
$(this).parents('.tr').remove();
}else{
$(this).parents('.tr').removeClass('selected');
}
});
});
//]]>
</script>
</head>

<body>

<table border="1">
<tbody id="tb">
<tr class="tr"><td>###### 1</td><td><a href="#" class="del" rel="1">del</a></td></tr>
<tr class="tr"><td>###### 2</td><td><a href="#" class="del" rel="2">del</a></td></tr>
</tbody>
</table>

</body>
</html>

add dynamic method to object


<?php

class MyPrinter{
public static function echoStar($obj,$s){
echo '*******',$obj->data,'********',$s;
}
public static function echoLine($obj,$s){
echo '<br>--------------',$obj->data,'----------',$s;
}
public static function AddTo($obj){
$m = get_class_methods(__CLASS__);
foreach($m as $i)$obj->methods[$i] = array(__CLASS__,$i);
}
}

class MyData
{
public $methods = array();
public $data;
public function __construct($data) {
$this->data = $data;
}
public function __call($name,$args){
if (in_array($name,array_keys($this->methods))){
array_unshift($args,$this);
return call_user_func_array($this->methods[$name],$args);
}else{
die('call undefined function '.$name.'.');
}
}
}

$c = new MyData('hello');
MyPrinter::AddTo($c);
echo $c->echoStar('aaaaaaa');
echo '<hr>';
echo $c->echoLine('bbbbbbb');

?>

วันพุธที่ 5 มกราคม พ.ศ. 2554

javascript effect

http://www.openrise.com/lab/FlowerPower/
http://www.javascript-fx.com/submitscripts/fireworks/

วันจันทร์ที่ 3 มกราคม พ.ศ. 2554

php encryption

ทดสอบการเข้ารหัส
download libmcrypt.dll ไปไว้ที่ C:\Windows\system32\
http://files.edin.dk/php/win32/mcrypt/
แก้ไข php.ini
;extension=php_mcrypt.dll
เป็น
extension=php_mcrypt.dll
restart apache


<?php

$iv_size = mcrypt_get_iv_size(MCRYPT_3DES, MCRYPT_MODE_CBC);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$key = 'keytest';
$data = 'data-test';
$edata = mcrypt_encrypt(MCRYPT_3DES, $key, $data, MCRYPT_MODE_CBC,$iv);
$ddata = trim(mcrypt_decrypt(MCRYPT_3DES, $key, $edata, MCRYPT_MODE_CBC,$iv),"\0");

echo '<br>data='.$data;
echo '<br>edata='.$edata;
echo '<br>data='.$ddata;

?>




<?php

$iv_size = mcrypt_get_iv_size(MCRYPT_3DES, MCRYPT_MODE_CBC);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$key = 'keytest';
$data = 'data-test';

$edata = mcrypt_encrypt(MCRYPT_3DES, $key, $data, MCRYPT_MODE_CBC,$iv);
$edata .= $iv;

//สมมุติว่า edata ถูกส่งมา ในรูปแบบ $edata ต่อท้ายด้วย $iv
$iv_size = mcrypt_get_iv_size(MCRYPT_3DES, MCRYPT_MODE_CBC);
//แยกข้อมูลออกเป็น $edata และ $iv
$temp = $edata;
$edata = substr($temp,0,-$iv_size);
$iv = substr($temp,-$iv_size);
//ทำการแปลงค่าตามปกติ
$ddata = trim(mcrypt_decrypt(MCRYPT_3DES, $key, $edata, MCRYPT_MODE_CBC,$iv),"\0");

echo '<br>data='.$data;
echo '<br>edata='.$edata;
echo '<br>data='.$ddata;

?>