AJAX分類文章 顯示方式:簡文 | 列表

April 9,2009

[AJAX] jQuery的多重下拉式選單應用:Select box manipulation

從本網誌回應數最高的文章得知,大家似乎對多重下拉式選單的功能情有獨鍾啊!Ajax 能夠在不換頁的情況下,達到資料庫連結,是許多人夢寐以求的功能;而 jQuery 易上手與輕鬆操作的特性,讓我們能更簡單的運用 Ajax 達成目的。然而隨著時間的推移,過去介紹的 cascade 已經有很長一段時間沒有更新,而且在使用上其實存在不少綁手綁腳的地方;距離 jQuery 的宗旨「Write Less, Do More」似乎是還差那麼一小段距離...

經由公司的 jQuery 教育訓練,Jace 介紹了一個超讚的 jQuery Plugin:Select box manipulation。透過這個外掛的幫助,可以更輕鬆的實現多重下拉式選單的功能唷,甚至連 cascade 不容易做到的「預設值」也完全沒問題,所需要撰寫的程式碼也少於 cascade,整個就是夢幻的 Plugin!這麼神奇的外掛要怎麼用呢?以下簡單的範例,給有需要的人參考吧:範例是三階層的關聯式多重下拉式選單,分為index.php(呈現頁)、action.php(Ajax 後端資料處理頁)、index.js(JavaScript 處理)、以及 selectboxes ...繼續閱讀

Posted by taikobo0 at 樂多Roodo!12:05回應(12)引用(0)

March 3,2009

[AJAX] JavaScript 的 PHP 函數寫法:nl2br()、htmlspecialchars()

PHP 真的是一種非常方便的語言,其支援的龐大函式庫,可以讓人很輕鬆自在的使用許多實用的函數。其中常用的 nl2br()htmlspecialchars() 在 HTML 顯示的時候很常使用,但是 JavaScript 就沒有提供類似方便使用的函數了;因為某些原因要在前端使用這二個函數,稍微 google 了一下馬上發現有前輩已經寫出來囉!在此作個紀錄並分享給有需要的人:(來源:Replace newlines with BR (platform safe)Javascript 的 htmlspecialchars function 與 htmlspecialchars_decode function,感謝網路上的前輩們^^)
// javascript 版本的 nl2br
var nl2br = function (string) {
    string = escape(string);
    if (string.indexOf('%0D%0A') > -1) {
        var re_nlchar = /%0D%0A/g ;
    } else if (string.indexOf('%0A') > -1) {
        var re_nlchar = /%0A/g ;
    } else if (string.indexOf('%0D') > -1) {
        var re_nlchar = /%0D/g ;
    }
    return unescape(string.replace(re_nlchar, '<br />'));
}

// javascript 版本的 htmlspecialchars
var htmlspecialchars = function (string, quote_style) {
   string = string.toString();

   string = string.replace(/&/g, '&amp;');
   string = string.replace(/</g, '&lt;');
   string = string.replace(/>/g, '&gt;');

   if (quote_style == 'ENT_QUOTES') {
       string = string.replace(/"/g, '&quot;');
       string = string.replace(/\'/g, '&#039;');
   } else if (quote_style != 'ENT_NOQUOTES') {
       string = string.replace(/"/g, '&quot;');
   }

   return string;
}

Posted by taikobo0 at 樂多Roodo!15:14回應(0)引用(0)

September 3,2008

[AJAX] jQuery的多重下拉式選單應用,當有預設值的時候

在多重下拉式選單的應用中,常常也會遇到已經有預設值的時候,這時候該怎麼辦呢?其實前陣子我也遇過這個問題,當初還花了一點時間尋找 jQuery的cascade 是不是有提供參數讓我輕鬆預設;不過拜完 Google 大神之後似乎是沒有什麼線索;所以最後我採用了一個很笨的方法,在頁面讀取完畢時如果有預設值的話,就直接丟一個 Ajax 取得第二層的選項。以下是實作的程式碼:(目前我只實作到二階層)

index.php:

<!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=utf-8" />
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="jquery.cascade.js"></script>
<script type="text/javascript" src="jquery.cascade.ext.js"></script>
<script type="text/javascript" src="jquery.templating.js"></script>
</head>
<body>
第一項 <select id="myParentSelect">
<option value="">請選擇</option>
<?php
    // 資料庫設定
    $host_sql = "localhost";
    $username_sql = "username";
    $password_sql = "password";

    // 預設值設定
    $defaultParentId = '3';
    $defaultChildId = '13';


    $link = mysql_connect($host_sql, $username_sql, $password_sql) or die("無法連結資料庫");
    mysql_select_db('target', $link);
    mysql_query("SET NAMES UTF8");

    $query = "SELECT id, name FROM table where lv = 1";
    $result = mysql_query($query, $link);
    while ($row = mysql_fetch_assoc($result)) {
        echo '<option value="' . $row["id"] . '">' . $row["name"] . '</option>' . "\n";
    }

?>
</select>

<!-- 設定一個隱藏的欄位紀錄預設值 -->
<input type="hidden" name="defaultParentId" value="<?php echo $defaultParentId; ?>" />
<input type="hidden" name="defaultChildId" value="<?php echo $defaultChildId; ?>" />

 
第二項 <select id="myChildSelect">
<option value="">請選擇</option>
</select>

<script type="text/javascript">

// 如果已有預設值,即時送出 Ajax 呼叫
function getSelectedList(defaultParentId, defaultFirstChildId) {
    $.ajax({
        type: "get",
        url:  'action.php',
        data: { act: 'default', val: defaultParentId, child: defaultFirstChildId },
        dataType: "json",
        success: function (json) {
            $('select#myChildSelect').append(json.data);
        }
    });
};


$(function () {

    // 檢查是否有預設值
    if ($('input[name=defaultParentId]').val()) {
        getSelectedList ($('input[name=defaultParentId]').val(), $('input[name=defaultChildId]').val());
    }


    // 第一階層對應第二階層
    $('#myChildSelect').cascade('#myParentSelect', {
    ajax: {
        type: "post",
        url:  'action.php',
        data: { act: 'first', val: $('#myParentSelect').val() },
        dataType: "json",
    },
    template: function(item) { return "<option value='" + item.Value + "'>" + item.Text + "</option>"; },
    match: function(selectedValue) { return this.When == selectedValue; }
    });
});
</script>
</body>
</html>

action.php:

<?php

// 資料庫設定
$host_sql = "localhost";
$username_sql = "username";
$password_sql = "password";

$link = mysql_connect($host_sql, $username_sql, $password_sql) or die("無法連結資料庫");
mysql_select_db('target', $link);
mysql_query("SET NAMES UTF8");

if (!empty($_GET['act'])) {
    $action = $_GET['act'];
}

if (!empty($_GET['val'])) {
    $parentId = $_GET['val'];
}

if (!empty($_GET['child'])) {
    $childId = $_GET['child'];
}


switch ($action) {
    case 'first':
        $list = array();
        $query = "SELECT id, name FROM table where lv = 2 AND parentid= $parentId";
        $result = mysql_query($query, $link);
        while ($row = mysql_fetch_assoc($result)) {
            $arr = array ('When' => $parentId, 'Value' => $row["ID"], 'Text' => $row["NAME"]);
            $list[] = $arr;

        }
        break;
    case 'default':
    default :
        $list = '';
        $query = "SELECT id, name FROM table where lv = 2 AND parentid= $parentId";
        $result = mysql_query($query, $link);
        while ($row = mysql_fetch_assoc($result)) {
            $list .= '<option value="' . $row["ID"] . '"';
            if ($childId == $row["ID"]) {
                $list .= ' selected="selected"';
            }
            $list .= '>' . $row["NAME"] . '</option>';
        }
        $list = array('data' => $list);

        break;
}

echo json_encode($list);

第二階層的選項,其實是用字串硬湊出來的,所以程式碼看起來還蠻醜的,請見諒。基本上用的概念只是在頁面讀取完畢以後直接送出 Ajax 而已,是蠻笨的方法;不過也不失為解決問題的一種方法啦!如果有其他適合的解法,有希望高手們能提供一下嚕!謝謝^^

Posted by taikobo0 at 樂多Roodo!10:32回應(0)引用(0)

September 1,2008

[AJAX] jQuery 的 lightBox

一般網頁上圖片的展示,很難讓人不聯想到 Lightbox;這個 Prototype 的燈箱特效。無奈現在公司使用的 jQuery 與 Lightbox 犯沖~沒辦法讓基於 Prototype 寫成的這個外掛直接引用。雖然如此,這麼經典的覽圖介面 jQuery 怎麼會放過呢?所以,jQuery lightBox plugin 就因此誕生了!

基本上官方網站已經講的非常清楚了,使用方法也跟 Lightbox 非常類似;不過更方便,也更有彈性。只要在需引用的網頁中載入:

<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript" src="js/jquery.lightbox-0.5.js"></script>
<link rel="stylesheet" type="text/css" href="css/jquery.lightbox-0.5.css" media="screen" />

之後,寫一隻小小的 JavaScript 於頁面中:

<script type="text/javascript">
$(function() {
    $('a[@rel*=lightbox]').lightBox();
});
</script>

就可以完全相容 Lightbox 的使用環境,無痛移植。此外,jQuery lightBox plugin 提供很多可以自訂的參數,自由度提高許多!

Posted by taikobo0 at 樂多Roodo!10:23回應(1)引用(0)

June 13,2008

[AJAX] jQuery的多重下拉式選單應用 PART2

昨天Jace傳授密技!原本 Ajax 回傳值我是用字串硬湊出來的,不過有密技可以用比較簡單易懂的方式呈現回傳資料,那就是PHP的json_encode!它會把陣列資料轉變成 json 的格式(其實原本 jQuery 吃的格式就是 json ),所以就不用辛苦的自己湊字串啦!提供第二種方法囉~修改過的地方用紅色標記:

index.php:

<!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=utf-8" />
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="jquery.cascade.js"></script>
<script type="text/javascript" src="jquery.cascade.ext.js"></script>
<script type="text/javascript" src="jquery.templating.js"></script>
</head>
<body>
第一項 <select id="myParentSelect">
<option value="">請選擇</option>
<?php
    // 資料庫設定
    $host_sql = "localhost";
    $username_sql = "username";
    $password_sql = "password";

    $link = mysql_connect($host_sql, $username_sql, $password_sql) or die("無法連結資料庫");
    mysql_select_db('target', $link);
    mysql_query("SET NAMES UTF8");

    $query = "SELECT id, name FROM table where lv = 1";
    $result = mysql_query($query, $link);
    while ($row = mysql_fetch_assoc($result)) {
        echo '<option value="' . $row["id"] . '">' . $row["name"] . '</option>' . "\n";
    }

?>
</select> 
第二項 <select id="myFirstChildSelect">
<option value="">請選擇</option>
</select>
第三項 <select id="mySecondChildSelect">
<option value="">請選擇</option>
</select>

<script type="text/javascript">
$(function () {

    // 第一階層對應第二階層
    $('#myFirstChildSelect').cascade('#myParentSelect', {
    ajax: {
        type: "post",
        url:  'action.php',
        data: { act: 'first', val: $('#myParentSelect').val() },
        dataType: "json"
    },
    template: function(item) { return "<option value='" + item.Value + "'>" + item.Text + "</option>"; },
    match: function(selectedValue) { return this.When == selectedValue; }
    });

    // 第二階層對應第三階層
    $('#mySecondChildSelect').cascade('#myFirstChildSelect', {
    ajax: {
        type: "post",
        url:  'action.php',
        data: { act: 'second', val: $('#myFirstChildSelect').val() },
        dataType: "json"
    },
    template: function(item) { return "<option value='" + item.Value + "'>" + item.Text + "</option>"; },
    match: function(selectedValue) { return this.When == selectedValue; }
    });
});
</script>
</body>
</html>

action.php:

<?php

// 資料庫設定
$host_sql = "localhost";
$username_sql = "username";
$password_sql = "password";

$link = mysql_connect($host_sql, $username_sql, $password_sql) or die("無法連結資料庫");
mysql_select_db('target', $link);
mysql_query("SET NAMES UTF8");

if (!empty($_GET['act'])) {
    $action = $_GET['act'];
}

if (!empty($_GET['val'])) {
    $parentId = $_GET['val'];
}

$list = array();

switch ($action) {
    case 'first':
        $query = "SELECT id, name FROM table where lv = 2 AND parentid= $parentId";
        $result = mysql_query($query, $link);
        while ($row = mysql_fetch_assoc($result)) {
            $arr = array ('When' => $parentId, 'Value' => $row["ID"], 'Text' => $row["NAME"]);
            $list[] = $arr;

        }
        break;
    case 'second':
    default :
        $query = "SELECT id, name FROM table where lv = 3 AND parentid = $parentId";
        $result = mysql_query($query, $link);
        while ($row = mysql_fetch_assoc($result)) {
            $arr = array ('When' => $parentId, 'Value' => $row["ID"], 'Text' => $row["NAME"]);
            $list[] = $arr;

        }
        break;
}

echo json_encode($list);

哈,這樣就清楚多了呢!當然昨天用字串組的方式也可以囉,其所達到的效果是一樣的啦!提供另一種思考方向^^

Posted by taikobo0 at 樂多Roodo!11:02回應(5)引用(0)

June 12,2008

[AJAX] jQuery的多重下拉式選單應用

P.S 2009-04-09 update:有更輕鬆簡單的方法,詳見[AJAX] jQuery的多重下拉式選單應用:Select box manipulation

關於Ajax,我想最棒的地方就是可以於背景呼叫資料庫傳值吧~多重下拉式選單就是一項非常棒的Ajax應用;前幾天Jace丟過來一個國外的網址:jQuery.cascade : Cascading values from forms,這篇文章主要是在說明jQuery的cascade,而它就是用來實現多重下拉式選單的功能。

花了一點時間實作了一下,發現非常簡單就能實現!以前我也作過類似的功能,可是花了我非常多的時間...jQuery把它包裝起來,讓一切變的簡單多了;以下是簡單的範例,給有需要的人參考吧:範例是三階層的關聯式多重下拉式選單,分為index.php(呈現頁)、action.php(Ajax後端資料處理頁)、以及jQuery的cascade

index.php:

<!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=utf-8" />
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="jquery.cascade.js"></script>
<script type="text/javascript" src="jquery.cascade.ext.js"></script>
<script type="text/javascript" src="jquery.templating.js"></script>
</head>
<body>
第一項 <select id="myParentSelect">
<option value="">請選擇</option>
<?php
    // 資料庫設定
    $host_sql = "localhost";
    $username_sql = "username";
    $password_sql = "password";

    $link = mysql_connect($host_sql, $username_sql, $password_sql) or die("無法連結資料庫");
    mysql_select_db('target', $link);
    mysql_query("SET NAMES UTF8");

    $query = "SELECT id, name FROM table where lv = 1";
    $result = mysql_query($query, $link);
    while ($row = mysql_fetch_assoc($result)) {
        echo '<option value="' . $row["id"] . '">' . $row["name"] . '</option>' . "\n";
    }

?>
</select> 
第二項 <select id="myFirstChildSelect">
<option value="">請選擇</option>
</select>
第三項 <select id="mySecondChildSelect">
<option value="">請選擇</option>
</select>

<script type="text/javascript">
$(function () {

    // 第一階層對應第二階層
    $('#myFirstChildSelect').cascade('#myParentSelect', {
    ajax: {
        type: "post",
        url:  'action.php',
        data: { act: 'first', val: $('#myParentSelect').val() }
    },
    template: function(item) { return "<option value='" + item.Value + "'>" + item.Text + "</option>"; },
    match: function(selectedValue) { return this.When == selectedValue; }
    });

    // 第二階層對應第三階層
    $('#mySecondChildSelect').cascade('#myFirstChildSelect', {
    ajax: {
        type: "post",
        url:  'action.php',
        data: { act: 'second', val: $('#myFirstChildSelect').val() }
    },
    template: function(item) { return "<option value='" + item.Value + "'>" + item.Text + "</option>"; },
    match: function(selectedValue) { return this.When == selectedValue; }
    });
});
</script>
</body>
</html>

action.php:

<?php

// 資料庫設定
$host_sql = "localhost";
$username_sql = "username";
$password_sql = "password";

$link = mysql_connect($host_sql, $username_sql, $password_sql) or die("無法連結資料庫");
mysql_select_db('target', $link);
mysql_query("SET NAMES UTF8");

if (!empty($_GET['act'])) {
    $action = $_GET['act'];
}

if (!empty($_GET['val'])) {
    $parentId = $_GET['val'];
}

$list = '[';

switch ($action) {
    case 'first':
        $query = "SELECT id, name FROM table where lv = 2 AND parentid= $parentId";
        $result = mysql_query($query, $link);
        while ($row = mysql_fetch_assoc($result)) {
            $list .= '{\'When\':\'' . $parentId . '\',\'Value\':\'' . $row["id"] . '\',\'Text\':\'' . $row["name"] . '\'},';
        }
        break;
    case 'second':
    default :
        $query = "SELECT id, name FROM table where lv = 3 AND parentid = $parentId";
        $result = mysql_query($query, $link);
        while ($row = mysql_fetch_assoc($result)) {
            $list .= '{\'When\':\'' . $parentId . '\',\'Value\':\'' . $row["id"] . '\',\'Text\':\'' . $row["name"] . '\'},';
        }
        break;
}

$list .= ']';
echo $list;

實作的重點是在資料的格式:

list = [{'When':'A1','Value':'W','Text':'SubchildA1a'},
          {'When':'A1','Value':'X','Text':'SubchildA1b'},
         ];

其中When代表上一階層的值,Value是此一階層的值,Test則是下拉式選單顯示的文字;要特別注意JavaScript是大小寫敏感的!實作這個範例途中,曾經被大小寫拖了一段時間...後來才發現~所以這地方要特別注意!希望大家都能輕鬆寫出關聯資料庫的多重下拉式選單囉^^

Posted by taikobo0 at 樂多Roodo!11:22回應(31)引用(0)

April 11,2008

[AJAX] 初探jQuery

因為哇寶在Ajax的應用上是採用jQuery,所以利用時間稍為了解一下。

我以往在處理Ajax時大部分是借用網上的範例JS檔,所以它通常都有一套制式的規範,哪裡要new,哪裡要丟參數,範例上都寫得清清楚楚,只要按部就班,通常都能很快達到我想要的功能。另外一種是土法煉鋼,自己造輪子;先從JS丟參數到php,再由php切我要的參數去跟伺服端Query我要的資料,最後呈現。這二種方式其實好像都不是正統的方式說...在看完jQuery的介紹後更是讓我有這樣的感覺~

網路上其實有很多淺顯易懂的介紹,我是看:國二學生認真打雜jQuery 學習心得筆記一系列文章稍微接觸jQuery這個Framework的。詳盡且生動有趣的介紹,讓我對jQuery有粗淺的認識!有興趣可以去逛逛~^^

Posted by taikobo0 at 樂多Roodo!11:29回應(0)引用(0)

February 9,2008

[AJAX] 自動完成autocomplete

春節前在公司卡很久的自動完成,終於解套啦!(吼)

會碰到這個問題,主要是因為本公司的專案管理系統,在材料成本新增時的廠商欄,會計反應會花很多時間在建立重複的資料上;一開始她建議使用下拉式選單...但是可想而知隨著資料量的增加,這下拉式選單也會變的愈來愈龐大...(汗)剛好前一陣子在研究自動完成,就想把這個應用加在專案管理系統中。關於自動完成,英文絕對沒什麼大問題;重點是中文啊~本來是要自己寫,真正動手以後才發現這個功能不是這麼簡單低。後來熊熊發現網路上有好用的免費資源啊!索性就先借用(?)來試試囉~

起初非常驚訝,沒想到網路上的自動完成功能完善,畫面精美;簡單說就是一整個適合!不過是二個javascript跟一個css就把自動完成做的如此完美,用法也非常簡單!不過高興的情緒並沒有持續太久,我很快的發現到這個自動完成,在IE瀏覽器下對中文不支援!(英文OK)非常出乎意料的該網誌作者註明對firefox不支援...但是我的firefox卻OK;很殘念的會計所慣用的瀏覽器是IE6...就這樣自動完成又走進死胡同。

後來我又花了不少時間在網上尋找適合的lib,期間不經意的發現原來一開始我所找到的免費資源其實是CAPXOUS的破解版;這壓根兒不是什麼免費資源!(汗)我所找到的是v1.3.0的版本,目前最新則是到v1.4.4版本。CAPXOUS本身也有提供程式碼下載以及解說~只不過它既然是個共享程式,廣告自然就少不了囉!最新的版本漂亮許多,當然付費授權的價格也就有點不親切...349 USD。

v1.4.4版也只有幾個檔案,當然重點還是在autocomplete.js、prototype.js以及autocomplete.css上囉!有興趣的人可以直接從CAPXOUS下載位置下載到,程式碼其實還頗複雜本人目前攻力尚淺,是處於一整個看不懂的階段,只好稍微解釋一下連結資料庫時的PHP檔,以及是如何運用在input欄位中的。

主要使用自動完成的頁面,千萬別忘記先導入二個javascript跟一個css:(夾在<head></head>之間)

<script language="JavaScript" src="javascripts/prototype.js" type="text/JavaScript"></script>
<script language="JavaScript" src="javascripts/autocomplete.js" type="text/JavaScript"></script>
<link rel="stylesheet" type="text/css" href="styles/autocomplete.css" />

廠商欄的輸入框:

<input name="supplier" type="text" id="supplier" size="10" />

表格結束後的javascript,導入AJAX:

<script>
 var d = new Date();
 new Autocomplete("supplier", function() {
  return "Suggest.php?msec=" + d.getMilliseconds() + "&type=0&keyword=" + this.value;
 });
</script>

d:特別建立的時間值,利用d.getMilliseconds()取得毫秒後,用以防止瀏覽器在以後只讀快取中的資料而沒有重新查詢。
supplier:input時的id(還是name忘記了...)
type&keyword:要傳入Suggest.php用以查詢資料庫

連結資料庫用的Suggest.php:

<?php
// 利用GET取得變數
$keyword = $_GET['keyword'];
$type = $_GET['type'];

// 連線《Project》資料庫
if($keyword != ''){
  $query = 'SELECT SUPPLIER ' .
           'FROM wh01_project_supplier ' .
           'WHERE SUPPLIER LIKE "' . $keyword . '%"' .
           'AND TYPE = "' . $type . '"';
}
// keyword無值時
else{
  $query = 'SELECT SUPPLIER ' .
           'FROM wh01_project_supplier ' .
           'WHERE SUPPLIER=""';
}
// 執行 SQL query
$result=mysql_query($query,$link);
// 如果$result存在時
if(!empty($result)>0){
  while (list($SUPPLIER) = mysql_fetch_row($result)){
    echo "<li onselect=\"this.text.value = '".$SUPPLIER."';\">\n";
    echo $SUPPLIER."\n";
    echo "</li>\n";
  }
}
// 結束這個連線
mysql_close();

?>

從資料庫取出後只要把結果呈現成:

<li onselect="this.text.value = '結果'; ">
 結果
</li>

就OK囉,最後請看成果


Posted by taikobo0 at 樂多Roodo!18:03回應(0)引用(0)
 [1]