BloggerAds

顯示具有 jQuery 標籤的文章。 顯示所有文章
顯示具有 jQuery 標籤的文章。 顯示所有文章

2012年1月18日 星期三

(Chrome、FireFox) JavaScript設定值給TextBox時,無法觸發PostBack的一種解法


如果有使用.NET 中TextBox的OnTextChanged事件,希望在TextBox的文字變動後,在Server端做一些事,通常會像下方這樣用:
ex. <asp:TextBox ID="txt1" runat="server" OnTextChanged="txt1_TextChanged" AutoPostBack="True" />

這個方式在人為操作的狀況下並不會有什麼問題,修改TextBox中的字後,會PostBack去執行程式。但如果修改TextBox中的文字,是使用JavaScript去設定值的話(ex. txt1.value = 'abc'),在各瀏覽器卻會有不同的結果產生,IE 會正常的執行 PostBack,但在Chrome、FireFox卻無法正常的觸發PostBack!

在試過jQuery的一些function後(ex. bind、on、trigger),發現還是沒辦法解決這個問題,最後只好用一個偏方來處理,使用setInterval一段時間就檢查一次TextBox的值,發現值有變動,就執行PostBack,解法如下:

$(document).ready(function() {          
    //非IE才設Interval,因為IE可正常觸發
    if(navigator.userAgent.indexOf("MSIE")==-1) {
        setInterval('detectValueChange();', 500);
    }
});
   
function detectValueChange() {
    currentValue = $('#<%=txt1.ClientID%>').val();
    oldValue = $('#<%=hid1.ClientID%>').val();
         
    if (currentValue != oldValue) {
        //使用<asp:HiddenField>暫存值,讓PostBack後,值還存在 
        $('#<%= hid1.ClientID%>').val(currentValue);
        __doPostBack('<%= txt1.ClientID%>', '');              
    }  
}       

2011年8月29日 星期一

ASP.NET的WebService + autocomplete + tagit 合體

在使用Google+、Facebook時,會常常看到Tag這個東西,這東西在使用上,很方便,而且長的還蠻好看的,我很喜歡這操作很直覺的東西,所以上網找了些plugin,並拿來實作,而我找了 tagit 這個plugin,還算簡單使用(而且我認為這是我找的 plugin 當中最漂亮的...)。


一般的使用很簡單,照著 tagit 的 example就可以用了,但是一般的tag通常都會加上自動完成(AutoComplete)功能,所以不加個AutoComplete感覺就很弱,下面就提供個範例是用C#的WebService來實作AutoComplete功能(PHP很簡單,下面會提到一點):


1.在WebService部份,我們用DataTable來傳回傳,所以可以在asmx.cs這樣寫:
[WebMethod]
public DataTable GetList(string prefixText) {  
        DataTable dt = new DataTable();
        //從資料庫查詢資料的語法,請自發揮...     
        // ......略
        return dt;    //最後return一個DataTable
}
2.在aspx部份,用一個TextBox:
<asp:TextBox ID="txtTag"  runat="server" autocomplete="off"  />
3.再來就是JavaScript的實作了,通常是在document.ready時實作
$(document).ready(function() {
    $("#<% =txtTag.ClientID %>").tagit({
        allowSpaces: true,
        tagSource: function(request, response) {
            $.ajax({
                url: "/GetList.asmx/GetList", //步驟1的WebService網址及Function名稱
                data: { prefixText: request.term }, //要傳入WebService Function的變數,這裡是用來抓user所輸入的內容
                dataType: "xml",  //dataType設成Xml,php直接用json,再搭配json_encode來產生資料就可以了
                type: "POST",
                contentType: "application/x-www-form-urlencoded; charset=utf-8",    //這裡很重要,要把contentType改成WebService預設回傳的application/x-www-form-urlencoded
                dataFilter: function(data) { return data; },
                success: function(data) {    //成功抓到資料後,要執行的動作
                    response($.map($(data).find("[欄位名稱]"), function(item) {  //因為是XML所以用這個方式來取資料,[欄位名稱]請記得更改成DataTable的欄位名稱
                        return { value: $(item).text() }
                    }));
                },
                error: function(XMLHttpRequest, textStatus, errorThrown) {
                    alert(textStatus + ":" + errorThrown);  //Debug用
                }
            });
        }         
    });
4.AutoComplete的部份完成!


5.如果要再龜毛點,限制使用者必須輸入DataTable中的內容的話,就在JavaScript中先加入這一段:
$.expr[':'].textEquals = function(a, i, m) {
        return $(a).text().match("^" + m[3] + "$");
};
6.再來改一下document.ready中tagit的部份,加入onTagAdded 的事件。


7.最後還要為tagit所產生的text加入change事件。


6+7後的JavaScript如下:
$(document).ready(function() {
    $("#<%=txtTag.ClientID %>").tagit({
        allowSpaces: true,
        tagSource: function(request, response) {
            $.ajax({
                url: "/GetList.asmx/GetList",
                data: { prefixText: request.term },
                dataType: "xml",
                type: "POST",
                contentType: "application/x-www-form-urlencoded; charset=utf-8",
                dataFilter: function(data) { return data; },
                success: function(data) {
                    response($.map($(data).find("[欄位名稱]"), function(item) {
                        return { value: $(item).text() }
                    }));
                },
                error: function(XMLHttpRequest, textStatus, errorThrown) {
                    alert(textStatus + ":" + errorThrown);
                }
            });
        },
        onTagAdded: function(event, tag) {  
            //注意!別在這alert東西,不然會執行兩次
            //.ui-autocomplete、tagit-label 是tagit執行後預設的class
            if ($(".ui-autocomplete li:textEquals('" + tag.find(".tagit-label").text() + "')").size() == 0) {
                that.removeTag(tag);    //若輸入的內容不在資料庫中,則移除tag
            }
        }
    });


    $(".tagit input").change(function() {
        if ($(".tagit li:textEquals('" + $(this).val() + "')").size() == 0) {
            $(this).val('');  //若輸入的內容不在資料庫中,則清空TextBox的內容
        }
    });
});
8. 再次大功告成


參考資料:
http://stackoverflow.com/questions/2587378/how-to-implement-mustmatch-and-selectfirst-in-jquery-ui-autocomplete
https://github.com/aehlke/tag-it
http://jqueryui.com/demos/autocomplete/

2011年7月27日 星期三

用jQuery取得RadioButtonList所選的值

開發.NET程式時,常常會使用到RadioButtonList控制項,在很多狀況下常需要依照使用者所選的值去做一些判斷或動作,雖然.Net本身就有OnSelectedIndexChanged事件可以用,搭配UpdatePanel等,可以做到不用PostBack的功能,但用jQuery也是可以寫的很簡單。

若使用的是RadioButtonList控制項,aspx內容如下:

<asp:RadioButtonList ID="rblTest" runat="server" >
    <asp:ListItem Text="1" Value="1" Selected="True" />
    <asp:ListItem Text="2" Value="2" />           
</asp:RadioButtonList>
產生的Html語法會長成這個樣子:
<table id="rblTest" border="0">
<tr>
<td><input id="rblTest_0" type="radio" name="rblTest" value="1" checked="checked" /><label for="rblTest_0">1</label></td>
</tr><tr>
<td><input id="rblTest_1" type="radio" name="rblTest" value="2" /><label for="rblTest_1">2</label></td>
</tr>
</table>
有看到吧? 產生的input物件,name 都是 rbTest,但id卻是以rbTest_開頭,再加上從0開始的序號,所以如果要使用jQuery取得所選的值的話,可以有兩種方法:
1.用id開頭取得:
$("input[id^='<% =rblTest.ClientID %>']:checked").val()
2.用name取得:
$("input[name='<% =rblTest.ClientID %>']:checked").val()
兩種都可以試試。

2011年7月15日 星期五

當 $(document).ready 碰上UpdatePanel

在 ASP.NET的開發中,UpdatePanel 是一個讓人又愛又恨的存在,讓人很方便使用,卻又常會造成一些問題。其中一個問題就是當UpdatePanel的(Partial) PostBack觸發後,你會發現你在$(document).ready中所設定的事件、屬性、ccs…等,全部都消失了,畫面並沒有reload,但你設定的動畫、mouseover、mouseout、watermark…等,卻都失效,沒有作用了。下面就是為了應對這種問題的解決方式:
$(document).ready(function() {
     pageLoad();
   
     Sys.WebForms.PageRequestManager.getInstance().add_endRequest(function() {
            pageLoad();
     });
});

function pageLoad() {
    //你要執行的程式碼
}
加入Sys.WebForms.PageRequestManager.getInstance().add_endRequest 這個事件,並重新執行一次原本$(document).ready所執行的程式就可以解決這個問題了。

如果你要在UpdatePanel的(Partial) PostBack執行前,去處理一些事件,像是記錄當下的數值之類的,你可以用 Sys.WebForms.PageRequestManager.getInstance().add_beginRequest這個事件來做處理。

如果你在$(document).ready中有設定css的class,這個方式在Chrome、Firefox等瀏覽器下,也可以確實的解決問題。但在IE下,有時你會發現,不管你怎麼重新設定css class,好像都沒作用,javascript事件、function、甚至用$(selector).css()來設定css,全部都有跑,但唯獨設定css class的部份卻跟沒跑一樣。

如果你的css class是寫在網頁中,那這個問題的解決方式有二:
1.將你的css屬性,全改用$(selector).css()來設定。
2.將你class的style區段移至<head>中,這樣就可以解決問題了,真是莫明奇妙...

參考資料:
http://stackoverflow.com/questions/256195/jquery-document-ready-and-updatepanels
http://stackoverflow.com/questions/1732164/losing-css-class-added-through-jquery-on-updatepanel-partial-postback
http://sudheerkondraguntaprogramming.blogspot.com/2011/05/issue-with-css-stylesheet-and.html

2011年7月1日 星期五

jQuery UI Modal Dialog 中ASP:Button 無法PostBack的解決方式

如果有在.NET網頁(aspx)中使用jQuery UI 的Modal Dialog Plugin的人,應該會發現,若將ASP:Button控制項放在Dialog中,裡面的Button按下去是不會PostBack的,google了一下後,發現只要加一行程式就可以解決了,解決方式如下:
$("#btnA").click(function() {                             
    $("#divDialog").dialog({    //顯示Modal Dialog
        title: 'title',
        modal: true
    });
    //重點在這
    $("#divDialog").parent().appendTo($("form:first")); 
});          

$("#btnCancel").click(function() {
    $("#divDialog").dialog("close");   //關閉Modal Dialog
});

參考資料:
http://stackoverflow.com/questions/568784/jquery-modal-form-dialog-postback-problems

2011年6月6日 星期一

Codeigniter上實現Ajax (使用jQuery)

下面這個在Codeigniter上實現Ajax的方式,是透過jQuery的post方法來實現,首先寫好一個controller,controller的程式範例如下:
<?php
class testAjax extends CI_Controller {
function index() {
}
function testPost() {
echo "result=".$this->input->post('para');
}
 function testPara($strPara) {
echo "result=".$strPara;
}
}
?>
上面有兩個function,分別是以post (testPost)、傳入參數 (testPara)兩種方式來呈現,其實只要選擇一種來實作即可,可以自已選擇自已喜歡的方式。View的程式範例如下:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script type="text/javascript" src="jquery-1.6.1.min.js"></script>
<title></title>
</head>
<body>
    <script language='javascript'>
    //<![CDATA[
    function testAjaxPost() {     
      var options = {'para' : '[在這輸入para的值]'};
   
    $.post('/index.php/testAjax/testPost', options, function(data) {
           alert(data);
    });
    }

    function testAjaxPara() {            
       $.post('/index.php/testAjax/testPara/[在這輸入要傳入$strPara的值]', null, function(data) {
         alert(data); 
     });
    } 
    //]]>
    </script>
 
<form id='frm1' method='post'>
<table border="0">
<tr>
<td>
<input type='button' id='btnTestPost' value='Post' onclick='testAjaxPost();' />
<input type='button' id='btnTestPara' value='Para' onclick='testAjaxPara();' />
</td>
</tr>
</table>
</form>    
</body>
</html>
這樣就可以執行了,jQuery的post說明如下:
$.post(URL [,POST_Para] [,Success] [,Fail]);

URL:Server端的URL。
POST_Para:要以Post方式傳入的陣列變數(不需使用時,可不傳入)。
Success:成功時要執行的程式碼(不需使用時,可不傳入)。
Fail:失敗時要執行的程式碼(不需使用時,可不傳入)。
其中傳入參數(testAjaxPara)方式,可以直接在網址輸入參數的值
而Post (testAjaxPost)方式則是透過javascript的陣列來傳入參數的值。

若要做比較進階的Ajax運用,可以在controller將值輸出成json或xml格式,就可以做到更多的功能

參考:http://stackoverflow.com/questions/308054/learning-how-to-use-ajax-with-codeigniter