這個需求是要模仿電子信箱中的CheckBox(我是參考GMail),勾選了第1筆之後,Shift鍵+滑鼠左鍵勾選第2筆,可以勾選我們要的多筆資料,稱這種功能為「連續選取」(我沒說錯吧)。
如果有想嘗試的人,可以先去我的前一篇(ASP.NET Table中的刪除按鈕,顯示2次提示訊息)複製SQL CREATE TABLE指令先建立資料表,所以後端程式碼我就不貼出來了,因為差不多一樣,只是這次的重點在JavaScript怎麼達到連續選取的功能,說明都寫在註解中。
test_gv_checkbox.aspx
前端
<%@ Page Title="" Language="vb" AutoEventWireup="false" MasterPageFile="~/MasterPage1.master" CodeBehind="test_gv_checkbox.aspx.vb" Inherits="test_gridview_dialog.test_gv_checkbox" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
<style type="text/css">
/*test_gv_dialog.aspx 只要是要使用在這個網頁的css都寫在此處*/
/*設定CheckBox大小,套用的對象有2個
1.只要是input的checkbox都套用。
2.因為GridView的CheckBox CssClass屬性有設定CSS,經過轉譯後CheckBox會被span標籤包起來,
所以只要是span標籤class是rowcb底下的CheckBox都套用。
*/
input[type="checkbox"], span[class="rowcb"]>input[type="checkbox"]{
width: 20px;
height: 20px;
}
</style>
<script type="text/javascript">
//test_gv_dialog.aspx JavaScript只要是要使用在這個網頁的JavaScript都寫在此處
var shiftkeydown = false; //紀錄使用者目前有沒有按下Shift鍵
$(document).ready(function () {
//只要是CSS類別名稱為GV1_headcb,底下的CheckBox就註冊change事件
$('.GV1_headcb > input[type="checkbox"]').change(function () {
var bool_change;
bool_change = this.checked; //取得自己勾選狀態
//table底下的tbody底下的tr CheckBox透過each(類似迴圈),將table中所有的CheckBox設定為勾選或取消勾選
$('#<%=GridView1.ClientID %> > tbody > tr input[type="checkbox"]').each(function () {
$(this).prop('checked', bool_change); //設定CheckBox狀態
});
});
//註冊keydown keyup事件,function名稱為listening_for_shift
$(document).on('keydown keyup', listening_for_shift);
//為GridView註冊change事件,對象是所有的CheckBox
$('#<%=GridView1.ClientID %>').on('change', 'input[type="checkbox"]', function () {
var this_checked_index = $(this).closest('tr').index(); //取得使用者勾選哪一個checkbox tr index
var str_hfval=$('#<%=HF_cbindex.ClientID%>').val(); //取得使用者上一次點了哪一個CheckBox
//當使用者按下shift 且 大於0(不包含GridView table head中CheckBox)
if (shiftkeydown == true && this_checked_index > 0) {
var before_index;
if (str_hfval != '') {
var re = /^[0-9]+$/;
if (!re.test(str_hfval)) {
return false; //不是數字就中斷
};
before_index = parseInt(str_hfval);
if (before_index < this_checked_index) {
for (var i = before_index; i <= this_checked_index; i++) {
$('#<%=GridView1.ClientID %>').find('tr:eq(' + i + ') input[type="checkbox"]').prop('checked', true);
};
} else if (before_index > this_checked_index) {
for (var i = this_checked_index; i <= before_index; i++) {
$('#<%=GridView1.ClientID %>').find('tr:eq(' + i + ') input[type="checkbox"]').prop('checked', true);
};
};
};
};
if (this_checked_index > 0){
$('#<%=HF_cbindex.ClientID%>').val(this_checked_index); //紀錄目前使用者勾選哪一個checkbox tr index
};
});
});
function listening_for_shift(e) {
if (e.keyCode == 16) {
if (e.type === "keydown") {
//alert('down shift');
shiftkeydown = true;
}
if (e.type === "keyup") {
//alert('no shift');
shiftkeydown = false;
}
}
};
</script>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
<div class="container">
<div class="row cust_blank1">
<div class="col-xs-12">
仿電子信箱中的CheckBox,勾選了第1筆之後,Shift鍵+滑鼠左鍵勾選第2筆,可以勾選我們要的多筆資料
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False">
<Columns>
<asp:TemplateField HeaderText="">
<HeaderTemplate>
<asp:CheckBox ID="GV1_headcb" runat="server" CssClass="rowcb GV1_headcb"/>
</HeaderTemplate>
<ItemTemplate>
<asp:CheckBox ID="CheckBox1" runat="server" CssClass="rowcb" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="編號">
<ItemTemplate>
<%# Eval("ser_no")%>
<asp:HiddenField ID="HF_serno" runat="server" Value='<%# Eval("ser_no")%>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="標題">
<ItemTemplate>
<%# Eval("title")%>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="內容">
<ItemTemplate>
<%# Eval("cont")%>
</ItemTemplate>
</asp:TemplateField>
</Columns>
<EmptyDataTemplate>
<asp:Label ID="GV_Empty" runat="server" Text="目前無資料"></asp:Label>
</EmptyDataTemplate>
</asp:GridView>
<asp:HiddenField ID="HF_cbindex" runat="server" />
</div>
</div>
</div>
</asp:Content>
說明:重點要記錄使用者第1次點了哪一個CheckBox,當使用者點了第2次時,就可以知道使用者點的範圍到哪裡,來作連續勾選的動作。
以上如有錯誤請指證,謝謝。
2017年6月25日 星期日
ASP.NET Table中的刪除按鈕,顯示2次提示訊息
以往要在GridView要刪除資料時,都會使用javascript confirm來問使用者是否確定要刪除資料,這次的需求是要跟使用者確認兩次,第一次詢問使用者「您確定要刪除這筆資料嗎?刪除後將無法還原!」,當按下確定後,第二次再次詢問使用者「真的確定要刪除這筆資料?」,按下確定刪除後,就真的刪除資料,所以這次要使用的是bootstrap dialog。
Step 1.首先到這個GitHub下載bootstrap3-dialog套件。
Step 2.我會使用到jquery-1.11.3.js檔,也請先準備好,並且將下載好的dialog放到專案中。
說明:我的css目錄中有一個檔案名為bootstrap-dialog_vc.css,它的作用主要是讓訊息框可以垂直置中(請點我),因為預設dialog是不會幫我們作垂直置中的。
bootstrap-dialog_vc.css檔,內容如下:
.modal {
text-align: center;
padding: 0 !important;
}
.modal:before {
content: '';
display: inline-block;
height: 100%;
vertical-align: middle;
margin-right: -4px;
}
.modal-dialog {
display: inline-block;
text-align: left;
vertical-align: middle;
}
Step 3.我在寫ASP.NET WebForm的時候,都會習慣使用Master Page,所以請建立一個Master Page,名稱使用預設的名稱即可或自行定義也可以,程式碼如下:
<%@ Master Language="VB" CodeFile="MasterPage1.master.vb" Inherits="MasterPage1" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>test_gridview_dialog</title>
<link rel="stylesheet" href="css/bootstrap.min.css" />
<script src="js/jquery-1.11.3.js"></script>
<script src="js/bootstrap.min.js"></script>
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
<asp:ContentPlaceHolder id="head" runat="server">
</asp:ContentPlaceHolder>
<style type="text/css">
/*MasterPage1 css*/
body {
background-color:#ffffff; /*背景顏色*/
}
</style>
<script type="text/javascript">
//MasterPage1 JavaScript
</script>
</head>
<body>
<form id="form1" runat="server">
<asp:ContentPlaceHolder id="ContentPlaceHolder1" runat="server">
</asp:ContentPlaceHolder>
</form>
</body>
</html>
Step 5.建立資料表,待會測試要用,以下是sql指令,方便讓大家建立資料表
以下為CREATE TABLE指令:
USE [test1]--這裡改成自己測試的資料庫
GO
/****** Object: Table [dbo].[test_table1] Script Date: 06/25/2017 19:16:26 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[test_table1](
[ser_no] [char](4) NOT NULL,
[title] [varchar](10) NULL,
[cont] [varchar](10) NULL,
CONSTRAINT [PK_test_table1] PRIMARY KEY CLUSTERED
(
[ser_no] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
以下為INSERT指令:
INSERT [dbo].[test_table1] ([ser_no], [title], [cont]) VALUES (N'0001', N'標題01', N'內容01')
INSERT [dbo].[test_table1] ([ser_no], [title], [cont]) VALUES (N'0002', N'標題02', N'內容02')
INSERT [dbo].[test_table1] ([ser_no], [title], [cont]) VALUES (N'0003', N'標題03', N'內容03')
INSERT [dbo].[test_table1] ([ser_no], [title], [cont]) VALUES (N'0004', N'標題04', N'內容04')
INSERT [dbo].[test_table1] ([ser_no], [title], [cont]) VALUES (N'0005', N'標題05', N'內容05')
Step 4.再來建立名為test_gv_dialog.aspx的網頁,程式碼如下:
前端:
<%@ Page Title="" Language="vb" AutoEventWireup="false" MasterPageFile="~/MasterPage1.master" CodeBehind="test_gv_dialog.aspx.vb" Inherits="test_gridview_dialog.test_gv_dialog" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
<link rel="stylesheet" href="css/bootstrap-dialog.min.css" />
<link rel="stylesheet" href="css/bootstrap-dialog_vc.css" />
<script src="js/bootstrap-dialog.min.js"></script>
<style type="text/css">
/*test_gv_dialog.aspx 只要是要使用在這個網頁的css都寫在此處*/
</style>
<script type="text/javascript">
//test_gv_dialog.aspx JavaScript只要是要使用在這個網頁的JavaScript都寫在此處
function delmessbox(int_row,str_mess) {
BootstrapDialog.show({
title: '確認是否刪除',
message: '您確定要刪除「編號' + str_mess + '」這筆資料嗎?<br/>刪除後將無法還原!',
buttons: [{
label: '確定',
action: function (dialog) {
delmessbox_again1(int_row, str_mess);
dialog.close();
}
}, {
label: '取消',
action: function (dialog) {
dialog.close();
}
}]
});
//因為使用bootstrap-dialog關係,當使用者按下按鈕後,呼叫delmessbox方法,會執行BootstrapDialog.show,
//但必須要注意,程式它並不會停在BootstrapDialog.show,等待使用者回傳哪一個動作(確認或取消),
//程式還是會繼續往下執行,如果沒有回傳false則會繼續執行Bdel按鈕中的OnClick事件中的下一個function,一樣會執行刪除。
return false;
};
function delmessbox_again1(int_row, str_mess) {
BootstrapDialog.show({
title: '再次確認',
message: '真的確定要刪除「編號' + str_mess + '」這筆資料?',
buttons: [{
label: '確定刪除',
action: function (dialog) {
dialog.close();
con_exedel(int_row);
}
}, {
label: '取消刪除',
action: function (dialog) {
dialog.close();
}
}]
});
};
function con_exedel(int_row) {
//這裡將會把GridView所有的Button該呼叫哪一個function寫在這裡
switch (int_row) {
<%=str_deljs.ToString()%>
<% str_deljs.Clear() : str_deljs = Nothing%>
};
};
</script>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
<div class="container">
<div class="row cust_blank1">
<div class="col-xs-12">
<span id="span_mess" runat="server"></span>
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False">
<Columns>
<asp:TemplateField HeaderText="">
<ItemTemplate>
<asp:Button ID="Bdel" runat="server" Text="刪除" CommandName="de" CssClass="btn btn-default"/>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="編號">
<ItemTemplate>
<%# Eval("ser_no")%>
<asp:HiddenField ID="HF_serno" runat="server" Value='<%# Eval("ser_no")%>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="標題">
<ItemTemplate>
<%# Eval("title")%>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="內容">
<ItemTemplate>
<%# Eval("cont")%>
</ItemTemplate>
</asp:TemplateField>
</Columns>
<EmptyDataTemplate>
<asp:Label ID="GV_Empty" runat="server" Text="目前無資料"></asp:Label>
</EmptyDataTemplate>
</asp:GridView>
</div>
</div>
</div>
</asp:Content>
後端:
Imports System.Data.SqlClient
Public Class test_gv_dialog
Inherits System.Web.UI.Page
Dim str_sqlconn As String = "Server=127.0.0.1;uid=test;pwd=test;Database=test1" '可以寫在web.config
Dim str_sql As String = String.Empty
Dim def_dt As DataTable = Nothing
Dim int_gv_row As Integer = 0
Public str_deljs As StringBuilder = Nothing
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not Page.IsPostBack Then
str_sql = "select * from test_table1"
def_dt = queryDataTable2(str_sql)
GridView1.DataSource = def_dt
GridView1.DataBind()
GridView1.CssClass = "table table-bordered"
def_dt.Clear() : def_dt.Dispose() : def_dt = Nothing
End If
End Sub
Function queryDataTable2(ByVal sql_str As String, Optional ByVal pv As String = Nothing, Optional ByVal sqlvalue_p() As String = Nothing) As DataTable
Dim sql_p() As String = Nothing
If Not pv Is Nothing Then
sql_p = pv.Split(",") 'sql字串中的參數
End If
Dim ds As New DataSet()
Using conn As New SqlConnection(str_sqlconn)
Dim command As SqlCommand = New SqlCommand(sql_str, conn)
If Not pv Is Nothing And Not sqlvalue_p Is Nothing Then
Dim x_end As Integer = sql_p.Length - 1
For x As Integer = 0 To x_end
If command.Parameters.Contains(sql_p(x)) Then
command.Parameters(sql_p(x)).Value = sqlvalue_p(x)
Else
command.Parameters.AddWithValue(sql_p(x), sqlvalue_p(x)) '讓ADO.NET自行判斷型別轉換
End If
Next
End If
Dim da As New SqlDataAdapter()
da.SelectCommand = command
da.Fill(ds)
command.Cancel()
command.Dispose()
End Using
If ds.Tables.Count > 0 Then
Return ds.Tables(0)
Else
Return New DataTable()
End If
End Function
Private Sub GridView1_RowDataBound(sender As Object, e As GridViewRowEventArgs) Handles GridView1.RowDataBound
If e.Row.RowType = DataControlRowType.Header Then
'設定欄位Class
e.Row.CssClass = "bg-primary"
e.Row.Cells(0).CssClass = "col-xs-1 col-md-1"
e.Row.Cells(1).CssClass = "col-xs-1 col-md-1"
e.Row.Cells(2).CssClass = "col-xs-1 col-md-1"
e.Row.Cells(3).CssClass = "col-xs-1 col-md-1"
str_deljs = New StringBuilder()
End If
If e.Row.RowType = DataControlRowType.DataRow Then
Dim Bdel As Button = CType(e.Row.FindControl("Bdel"), Button)
If Not (Bdel Is Nothing) Then
'在Bdel按鈕中,加入onclick事件delmessbox方法
Bdel.Attributes.Add("onclick", "javascript:return delmessbox(" & int_gv_row & ",'" & CType(e.Row.DataItem, DataRowView).Item("ser_no").ToString() & "');" & ClientScript.GetPostBackEventReference(Bdel, "").ToString() & ";")
End If
str_deljs.Append("case " & int_gv_row & ":" & ClientScript.GetPostBackEventReference(Bdel, "").ToString() & ";break;")
int_gv_row = int_gv_row + 1
End If
End Sub
Private Sub GridView1_RowCommand(sender As Object, e As GridViewCommandEventArgs) Handles GridView1.RowCommand
If e.CommandName = "de" Then
Dim str_commandName As String = e.CommandName
Dim BS As Button = CType(e.CommandSource, Button) '先取得命令的來源並轉換成按鈕
Dim GV_Row As GridViewRow = CType(BS.NamingContainer, GridViewRow) '將Button轉換成GridViewRow就是您所點選的某一列
str_sql = "delete test_table1 where ser_no=@ser_no"
'建議HF_serno的Value要事先先加密,當使用按下按鈕之後,再解密這樣會比較安全
Dim str_serno As String = CType(GridView1.Rows(GV_Row.RowIndex).FindControl("HF_serno"), HiddenField).Value
Dim int_enq As Integer = 0
Using conn As New SqlConnection(str_sqlconn)
conn.Open()
Dim command As SqlCommand = New SqlCommand(str_sql, conn)
If command.Parameters.Contains("@ser_no") Then
command.Parameters("@ser_no").Value = str_serno
Else
command.Parameters.AddWithValue("@ser_no", str_serno) '讓ADO.NET自行判斷型別轉換
End If
int_enq = command.ExecuteNonQuery()
command.Cancel() 'SqlDataReader要close前,要先Cancel SqlCommand
command.Dispose()
conn.Close()
End Using
If int_enq = 1 Then
Me.span_mess.InnerHtml = "<span style=" & Chr(34) & "color:blue;" & Chr(34) & ">系統於 " & Date.Now.ToString("yyyy/MM/dd HH:mm:ss") & " 已刪「編號:" & str_serno & "」這筆資料。</span>"
'刪除成功,重新讀取資料
str_sql = "select * from test_table1"
def_dt = queryDataTable2(str_sql)
GridView1.DataSource = def_dt
GridView1.DataBind()
GridView1.CssClass = "table table-bordered"
Else
Me.span_mess.InnerHtml = "<span style=" & Chr(34) & "color:red;" & Chr(34) & ">系統於 " & Date.Now.ToString("yyyy/MM/dd HH:mm:ss") & " 「編號:" & str_serno & "」刪除失敗。</span>"
End If
End If
End Sub
End Class
執行結果:
以上,說明我寫在註解中,如有錯誤的地方,請指證,謝謝。
Step 1.首先到這個GitHub下載bootstrap3-dialog套件。
Step 2.我會使用到jquery-1.11.3.js檔,也請先準備好,並且將下載好的dialog放到專案中。
bootstrap-dialog_vc.css檔,內容如下:
.modal {
text-align: center;
padding: 0 !important;
}
.modal:before {
content: '';
display: inline-block;
height: 100%;
vertical-align: middle;
margin-right: -4px;
}
.modal-dialog {
display: inline-block;
text-align: left;
vertical-align: middle;
}
Step 3.我在寫ASP.NET WebForm的時候,都會習慣使用Master Page,所以請建立一個Master Page,名稱使用預設的名稱即可或自行定義也可以,程式碼如下:
<%@ Master Language="VB" CodeFile="MasterPage1.master.vb" Inherits="MasterPage1" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>test_gridview_dialog</title>
<link rel="stylesheet" href="css/bootstrap.min.css" />
<script src="js/jquery-1.11.3.js"></script>
<script src="js/bootstrap.min.js"></script>
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
<asp:ContentPlaceHolder id="head" runat="server">
</asp:ContentPlaceHolder>
<style type="text/css">
/*MasterPage1 css*/
body {
background-color:#ffffff; /*背景顏色*/
}
</style>
<script type="text/javascript">
//MasterPage1 JavaScript
</script>
</head>
<body>
<form id="form1" runat="server">
<asp:ContentPlaceHolder id="ContentPlaceHolder1" runat="server">
</asp:ContentPlaceHolder>
</form>
</body>
</html>
Step 5.建立資料表,待會測試要用,以下是sql指令,方便讓大家建立資料表
以下為CREATE TABLE指令:
USE [test1]--這裡改成自己測試的資料庫
GO
/****** Object: Table [dbo].[test_table1] Script Date: 06/25/2017 19:16:26 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[test_table1](
[ser_no] [char](4) NOT NULL,
[title] [varchar](10) NULL,
[cont] [varchar](10) NULL,
CONSTRAINT [PK_test_table1] PRIMARY KEY CLUSTERED
(
[ser_no] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
以下為INSERT指令:
INSERT [dbo].[test_table1] ([ser_no], [title], [cont]) VALUES (N'0001', N'標題01', N'內容01')
INSERT [dbo].[test_table1] ([ser_no], [title], [cont]) VALUES (N'0002', N'標題02', N'內容02')
INSERT [dbo].[test_table1] ([ser_no], [title], [cont]) VALUES (N'0003', N'標題03', N'內容03')
INSERT [dbo].[test_table1] ([ser_no], [title], [cont]) VALUES (N'0004', N'標題04', N'內容04')
INSERT [dbo].[test_table1] ([ser_no], [title], [cont]) VALUES (N'0005', N'標題05', N'內容05')
Step 4.再來建立名為test_gv_dialog.aspx的網頁,程式碼如下:
前端:
<%@ Page Title="" Language="vb" AutoEventWireup="false" MasterPageFile="~/MasterPage1.master" CodeBehind="test_gv_dialog.aspx.vb" Inherits="test_gridview_dialog.test_gv_dialog" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
<link rel="stylesheet" href="css/bootstrap-dialog.min.css" />
<link rel="stylesheet" href="css/bootstrap-dialog_vc.css" />
<script src="js/bootstrap-dialog.min.js"></script>
<style type="text/css">
/*test_gv_dialog.aspx 只要是要使用在這個網頁的css都寫在此處*/
</style>
<script type="text/javascript">
//test_gv_dialog.aspx JavaScript只要是要使用在這個網頁的JavaScript都寫在此處
function delmessbox(int_row,str_mess) {
BootstrapDialog.show({
title: '確認是否刪除',
message: '您確定要刪除「編號' + str_mess + '」這筆資料嗎?<br/>刪除後將無法還原!',
buttons: [{
label: '確定',
action: function (dialog) {
delmessbox_again1(int_row, str_mess);
dialog.close();
}
}, {
label: '取消',
action: function (dialog) {
dialog.close();
}
}]
});
//因為使用bootstrap-dialog關係,當使用者按下按鈕後,呼叫delmessbox方法,會執行BootstrapDialog.show,
//但必須要注意,程式它並不會停在BootstrapDialog.show,等待使用者回傳哪一個動作(確認或取消),
//程式還是會繼續往下執行,如果沒有回傳false則會繼續執行Bdel按鈕中的OnClick事件中的下一個function,一樣會執行刪除。
return false;
};
function delmessbox_again1(int_row, str_mess) {
BootstrapDialog.show({
title: '再次確認',
message: '真的確定要刪除「編號' + str_mess + '」這筆資料?',
buttons: [{
label: '確定刪除',
action: function (dialog) {
dialog.close();
con_exedel(int_row);
}
}, {
label: '取消刪除',
action: function (dialog) {
dialog.close();
}
}]
});
};
function con_exedel(int_row) {
//這裡將會把GridView所有的Button該呼叫哪一個function寫在這裡
switch (int_row) {
<%=str_deljs.ToString()%>
<% str_deljs.Clear() : str_deljs = Nothing%>
};
};
</script>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
<div class="container">
<div class="row cust_blank1">
<div class="col-xs-12">
<span id="span_mess" runat="server"></span>
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False">
<Columns>
<asp:TemplateField HeaderText="">
<ItemTemplate>
<asp:Button ID="Bdel" runat="server" Text="刪除" CommandName="de" CssClass="btn btn-default"/>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="編號">
<ItemTemplate>
<%# Eval("ser_no")%>
<asp:HiddenField ID="HF_serno" runat="server" Value='<%# Eval("ser_no")%>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="標題">
<ItemTemplate>
<%# Eval("title")%>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="內容">
<ItemTemplate>
<%# Eval("cont")%>
</ItemTemplate>
</asp:TemplateField>
</Columns>
<EmptyDataTemplate>
<asp:Label ID="GV_Empty" runat="server" Text="目前無資料"></asp:Label>
</EmptyDataTemplate>
</asp:GridView>
</div>
</div>
</div>
</asp:Content>
後端:
Imports System.Data.SqlClient
Public Class test_gv_dialog
Inherits System.Web.UI.Page
Dim str_sqlconn As String = "Server=127.0.0.1;uid=test;pwd=test;Database=test1" '可以寫在web.config
Dim str_sql As String = String.Empty
Dim def_dt As DataTable = Nothing
Dim int_gv_row As Integer = 0
Public str_deljs As StringBuilder = Nothing
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not Page.IsPostBack Then
str_sql = "select * from test_table1"
def_dt = queryDataTable2(str_sql)
GridView1.DataSource = def_dt
GridView1.DataBind()
GridView1.CssClass = "table table-bordered"
def_dt.Clear() : def_dt.Dispose() : def_dt = Nothing
End If
End Sub
Function queryDataTable2(ByVal sql_str As String, Optional ByVal pv As String = Nothing, Optional ByVal sqlvalue_p() As String = Nothing) As DataTable
Dim sql_p() As String = Nothing
If Not pv Is Nothing Then
sql_p = pv.Split(",") 'sql字串中的參數
End If
Dim ds As New DataSet()
Using conn As New SqlConnection(str_sqlconn)
Dim command As SqlCommand = New SqlCommand(sql_str, conn)
If Not pv Is Nothing And Not sqlvalue_p Is Nothing Then
Dim x_end As Integer = sql_p.Length - 1
For x As Integer = 0 To x_end
If command.Parameters.Contains(sql_p(x)) Then
command.Parameters(sql_p(x)).Value = sqlvalue_p(x)
Else
command.Parameters.AddWithValue(sql_p(x), sqlvalue_p(x)) '讓ADO.NET自行判斷型別轉換
End If
Next
End If
Dim da As New SqlDataAdapter()
da.SelectCommand = command
da.Fill(ds)
command.Cancel()
command.Dispose()
End Using
If ds.Tables.Count > 0 Then
Return ds.Tables(0)
Else
Return New DataTable()
End If
End Function
Private Sub GridView1_RowDataBound(sender As Object, e As GridViewRowEventArgs) Handles GridView1.RowDataBound
If e.Row.RowType = DataControlRowType.Header Then
'設定欄位Class
e.Row.CssClass = "bg-primary"
e.Row.Cells(0).CssClass = "col-xs-1 col-md-1"
e.Row.Cells(1).CssClass = "col-xs-1 col-md-1"
e.Row.Cells(2).CssClass = "col-xs-1 col-md-1"
e.Row.Cells(3).CssClass = "col-xs-1 col-md-1"
str_deljs = New StringBuilder()
End If
If e.Row.RowType = DataControlRowType.DataRow Then
Dim Bdel As Button = CType(e.Row.FindControl("Bdel"), Button)
If Not (Bdel Is Nothing) Then
'在Bdel按鈕中,加入onclick事件delmessbox方法
Bdel.Attributes.Add("onclick", "javascript:return delmessbox(" & int_gv_row & ",'" & CType(e.Row.DataItem, DataRowView).Item("ser_no").ToString() & "');" & ClientScript.GetPostBackEventReference(Bdel, "").ToString() & ";")
End If
str_deljs.Append("case " & int_gv_row & ":" & ClientScript.GetPostBackEventReference(Bdel, "").ToString() & ";break;")
int_gv_row = int_gv_row + 1
End If
End Sub
Private Sub GridView1_RowCommand(sender As Object, e As GridViewCommandEventArgs) Handles GridView1.RowCommand
If e.CommandName = "de" Then
Dim str_commandName As String = e.CommandName
Dim BS As Button = CType(e.CommandSource, Button) '先取得命令的來源並轉換成按鈕
Dim GV_Row As GridViewRow = CType(BS.NamingContainer, GridViewRow) '將Button轉換成GridViewRow就是您所點選的某一列
str_sql = "delete test_table1 where ser_no=@ser_no"
'建議HF_serno的Value要事先先加密,當使用按下按鈕之後,再解密這樣會比較安全
Dim str_serno As String = CType(GridView1.Rows(GV_Row.RowIndex).FindControl("HF_serno"), HiddenField).Value
Dim int_enq As Integer = 0
Using conn As New SqlConnection(str_sqlconn)
conn.Open()
Dim command As SqlCommand = New SqlCommand(str_sql, conn)
If command.Parameters.Contains("@ser_no") Then
command.Parameters("@ser_no").Value = str_serno
Else
command.Parameters.AddWithValue("@ser_no", str_serno) '讓ADO.NET自行判斷型別轉換
End If
int_enq = command.ExecuteNonQuery()
command.Cancel() 'SqlDataReader要close前,要先Cancel SqlCommand
command.Dispose()
conn.Close()
End Using
If int_enq = 1 Then
Me.span_mess.InnerHtml = "<span style=" & Chr(34) & "color:blue;" & Chr(34) & ">系統於 " & Date.Now.ToString("yyyy/MM/dd HH:mm:ss") & " 已刪「編號:" & str_serno & "」這筆資料。</span>"
'刪除成功,重新讀取資料
str_sql = "select * from test_table1"
def_dt = queryDataTable2(str_sql)
GridView1.DataSource = def_dt
GridView1.DataBind()
GridView1.CssClass = "table table-bordered"
Else
Me.span_mess.InnerHtml = "<span style=" & Chr(34) & "color:red;" & Chr(34) & ">系統於 " & Date.Now.ToString("yyyy/MM/dd HH:mm:ss") & " 「編號:" & str_serno & "」刪除失敗。</span>"
End If
End If
End Sub
End Class
執行結果:
2017年6月14日 星期三
ASP.NET input button使用javascript觸發postback
不使用ASP.NET WebForm Button控制項,使用html Button並在Button的onclick事件中,使用javascript觸發postback,在Page_Load中去確認哪一個按鈕觸發。
以下的作法,不曉得是否正確,還請各位程式設計師們不吝指教。
test_js_postback.aspx
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="test_js_postback.aspx.vb" Inherits="test_js_postback" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title></title>
<script type="text/javascript">
function Button1_Click() {
<%=ClientScript.GetPostBackEventReference(Me, "Button1_Click").ToString%>
};
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<input id="Button1" type="button" value="測試javascript觸發postback" onclick="Button1_Click();" />
<span id="span_message" runat="server">[訊息顯示在此處]</span>
</div>
</form>
</body>
</html>
test_js_postback.aspx.vb
Partial Class test_js_postback
Inherits System.Web.UI.Page
Private Sub test_js_postback_Load(sender As Object, e As EventArgs) Handles Me.Load
If Not Page.IsPostBack Then
Else
Dim con As Control = Nothing
Dim str_event_target As String = String.Empty
Dim str_event_targument As String = String.Empty
str_event_target = Page.Request.Params.Get("__EVENTTARGET") 'html hidden __EVENTTARGET
str_event_targument = Page.Request.Params.Get("__EVENTARGUMENT") 'html hidden __EVENTARGUMENT
If (Not str_event_target Is Nothing) And (str_event_target <> "") Then
con = Page.FindControl(str_event_target)
Response.Write("EVENTTARGET=[" & str_event_target & "][" & con.GetType.ToString & "]<br/>")
If InStr(1, str_event_target.ToLower, "page", CompareMethod.Text) > 0 Then
If (Not str_event_targument Is Nothing) And (str_event_targument <> "") Then
Response.Write("EVENTARGUMENT=[" & str_event_targument & "]<br/>")
If str_event_targument = "Button1_Click" Then 'html input的Button1_Click
Me.span_message.InnerHtml = "觸發Button1_Click<br/>"
End If
Else
Response.Write("EVENTARGUMENT=[無]<br/>")
End If
End If
Else
Response.Write("PostBack:可能是某個控制項送出<br/>")
End If
End If
End Sub
End Class
以下的作法,不曉得是否正確,還請各位程式設計師們不吝指教。
test_js_postback.aspx
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="test_js_postback.aspx.vb" Inherits="test_js_postback" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title></title>
<script type="text/javascript">
function Button1_Click() {
<%=ClientScript.GetPostBackEventReference(Me, "Button1_Click").ToString%>
};
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<input id="Button1" type="button" value="測試javascript觸發postback" onclick="Button1_Click();" />
<span id="span_message" runat="server">[訊息顯示在此處]</span>
</div>
</form>
</body>
</html>
test_js_postback.aspx.vb
Partial Class test_js_postback
Inherits System.Web.UI.Page
Private Sub test_js_postback_Load(sender As Object, e As EventArgs) Handles Me.Load
If Not Page.IsPostBack Then
Else
Dim con As Control = Nothing
Dim str_event_target As String = String.Empty
Dim str_event_targument As String = String.Empty
str_event_target = Page.Request.Params.Get("__EVENTTARGET") 'html hidden __EVENTTARGET
str_event_targument = Page.Request.Params.Get("__EVENTARGUMENT") 'html hidden __EVENTARGUMENT
If (Not str_event_target Is Nothing) And (str_event_target <> "") Then
con = Page.FindControl(str_event_target)
Response.Write("EVENTTARGET=[" & str_event_target & "][" & con.GetType.ToString & "]<br/>")
If InStr(1, str_event_target.ToLower, "page", CompareMethod.Text) > 0 Then
If (Not str_event_targument Is Nothing) And (str_event_targument <> "") Then
Response.Write("EVENTARGUMENT=[" & str_event_targument & "]<br/>")
If str_event_targument = "Button1_Click" Then 'html input的Button1_Click
Me.span_message.InnerHtml = "觸發Button1_Click<br/>"
End If
Else
Response.Write("EVENTARGUMENT=[無]<br/>")
End If
End If
Else
Response.Write("PostBack:可能是某個控制項送出<br/>")
End If
End If
End Sub
End Class
2017年6月12日 星期一
CSS
20170613
改變checkbox大小(參考:Check box size change with CSS [duplicate])
input[type="checkbox"]{
width: 20px; /*Desired width*/
height: 20px; /*Desired height*/
}
2017年5月26日 星期五
Bootstrap ASP.NET TextBox使用jquery.bootcomplete.js達到自動完成功能,並帶出其他資料
前篇「Bootstrap ASP.NET TextBox使用jquery.bootcomplete.js達到自動完成功能」說明到如何使用別人寫好的jquery.bootcomplete.js,而這次呢,我要依照我key入的關鍵字搜尋出來的結果,點擊其中一筆,帶出某個人的詳細資料。這次要來修改它的js檔,並把它改個名子。
Step 1.先準備要查詢的功能網頁,資料表不變(不知道是什麼看前篇),此網頁我叫它getData2.aspx,一樣前端就一行程式碼,以下是後端程式碼,跟前篇的一樣,但只改Select指令。
Imports System.Data
Imports System.Data.SqlClient
Imports Newtonsoft.Json
Imports UControls.cswfunclass
Partial Class getData2
Inherits System.Web.UI.Page
Dim str_sql As String = String.Empty
Private Sub getData_Load(sender As Object, e As EventArgs) Handles Me.Load
'進到getData.aspx最好作個身分驗證,免得重要資訊外流
If Not Page.IsPostBack Then
'第一次進入
Dim str_rdata As StringBuilder = Nothing
If (Not Request("k") Is Nothing) Then
If Request("k").ToString = "1" Then
Dim str_query As String = String.Empty
If (Not Request("query") Is Nothing) Then
str_query = Request("query").ToString
End If
str_rdata = New StringBuilder()
Dim def_ds As New DataSet()
str_sql = "select cname as f1,id_no as f2,address1 as addr,email as mail from test_member where cname like @cname+'%'"
Using conn As New SqlConnection("Server=127.0.0.1;uid=test;pwd=test;Database=test1")
Using command As SqlCommand = New SqlCommand(str_sql, conn)
'避免 SQL Injection(資料隱碼)攻擊
If command.Parameters.Contains("@cname") Then
command.Parameters("@cname").Value = str_query
Else
command.Parameters.AddWithValue("@cname", str_query) '讓ADO.NET自行判斷型別轉換
End If
Using da As New SqlDataAdapter()
da.SelectCommand = command
da.Fill(def_ds)
End Using
End Using
End Using
str_rdata.Append(JsonConvert.SerializeObject(def_ds.Tables(0), Formatting.Indented))
Response.Write(str_rdata.ToString)
def_ds.Clear() : def_ds.Dispose()
Else
Response.Write("[]")
End If
Else
Response.Write("[]")
End If
End If
End Sub
End Class
Step 1.先準備要查詢的功能網頁,資料表不變(不知道是什麼看前篇),此網頁我叫它getData2.aspx,一樣前端就一行程式碼,以下是後端程式碼,跟前篇的一樣,但只改Select指令。
Imports System.Data
Imports System.Data.SqlClient
Imports Newtonsoft.Json
Imports UControls.cswfunclass
Partial Class getData2
Inherits System.Web.UI.Page
Dim str_sql As String = String.Empty
Private Sub getData_Load(sender As Object, e As EventArgs) Handles Me.Load
'進到getData.aspx最好作個身分驗證,免得重要資訊外流
If Not Page.IsPostBack Then
'第一次進入
Dim str_rdata As StringBuilder = Nothing
If (Not Request("k") Is Nothing) Then
If Request("k").ToString = "1" Then
Dim str_query As String = String.Empty
If (Not Request("query") Is Nothing) Then
str_query = Request("query").ToString
End If
str_rdata = New StringBuilder()
Dim def_ds As New DataSet()
str_sql = "select cname as f1,id_no as f2,address1 as addr,email as mail from test_member where cname like @cname+'%'"
Using conn As New SqlConnection("Server=127.0.0.1;uid=test;pwd=test;Database=test1")
Using command As SqlCommand = New SqlCommand(str_sql, conn)
'避免 SQL Injection(資料隱碼)攻擊
If command.Parameters.Contains("@cname") Then
command.Parameters("@cname").Value = str_query
Else
command.Parameters.AddWithValue("@cname", str_query) '讓ADO.NET自行判斷型別轉換
End If
Using da As New SqlDataAdapter()
da.SelectCommand = command
da.Fill(def_ds)
End Using
End Using
End Using
str_rdata.Append(JsonConvert.SerializeObject(def_ds.Tables(0), Formatting.Indented))
Response.Write(str_rdata.ToString)
def_ds.Clear() : def_ds.Dispose()
Else
Response.Write("[]")
End If
Else
Response.Write("[]")
End If
End If
End Sub
End Class
說明紅色的部分
待會我將帶出f1,f2,addr,mail資料,顯示到我要的介面上
Step 2.在新增一個aspx網頁,命名為:test_bootcomplete2
Step 3.將jquery.bootcomplete.js程式碼複製一份到test_bootcomplete2.aspx網頁中,沒有再額外建立js檔,如下:
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="test_bootcomplete2.aspx.vb" Inherits="test_bootcomplete2" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>test bootcomplete2</title>
<link rel="stylesheet" href="css/bootstrap.css" />
<script src="js/jquery-1.11.3.js"></script>
<script src="js/bootstrap.js"></script>
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
<script type="text/javascript">
(function ($) {
$.fn.bootcomplete_new1 = function (options) {
var defaults = {
url: "/search.php",
method: 'get',
wrapperClass: "bc-wrapper",
menuClass: "bc-menu",
idField: true,
idFieldName: $(this).attr('name') + "_id",
minLength: 3,
dataParams: {},
formParams: {},
mainDBField:'NULL',
otherFieldID: false,
arrFieldID: [],
arrDBField: []
};
var settings = $.extend({}, defaults, options);
$(this).attr('autocomplete', 'off');
//載入之後,在原本TextBox再包一層div
$(this).wrap('<div class="' + settings.wrapperClass + '"></div>');
/** //不曉得原作者的用意
if (settings.idField) {
if ($(this).parent().parent().find('input[name="' + settings.idFieldName + '"]').length !== 0) {
//use existing id field
} else {
//there is no existing id field so create one
$('<input type="hidden" name="' + settings.idFieldName + '" value="">').insertBefore($(this));
};
};
*/
//載入之後,insertAfter在目前的元素(一開始的元素是TextBox)後面插入div
$('<div class="' + settings.menuClass + ' list-group"></div>').insertAfter($(this));
$('div[class="' + settings.menuClass + ' list-group"]').hide(); //載入後隱藏
$(this).on("keyup", searchQuery);
$(this).on("focusout", hideThat);
var xhr;
var that = $(this);
function hideThat() {
if ($('.list-group-item' + ':hover').length) {
return;
};
$(that).next('.' + settings.menuClass).hide();
};
function searchQuery() {
var arr = [];
$.each(settings.formParams, function (k, v) {
arr[k] = $(v).val();
});
var dyFormParams = $.extend({}, arr);
var Data = $.extend({ query: $(this).val() }, settings.dataParams, dyFormParams);
if (!Data.query) {
$(this).next('.' + settings.menuClass).html('');
$(this).next('.' + settings.menuClass).hide();
};
if (Data.query.length >= settings.minLength) {
if (xhr && xhr.readyState != 4) {
xhr.abort();
};
xhr = $.ajax({
type: settings.method,
url: settings.url,
data: Data,
dataType: "json",
success: function (json) {
var str_datahtml=''; //產生html屬性
var results = '';
$.each(json, function (i, j) {
str_datahtml = '';
//兜出自己想要的資料,這邊要加上自己要顯示的欄位,例如sql指令欄位有f1、f2、addr、mail,就必須加上data-f1、data-f2、data-addr、data-mail
for (var i = 0; i < settings.arrDBField.length; i++) {
str_datahtml = str_datahtml + 'data-' + settings.arrDBField[i] + '="' + j[settings.arrDBField[i]] + '" ';
};
str_datahtml = str_datahtml + 'data-' + settings.mainDBField + '="' + j[settings.mainDBField] + '" ';
results += '<a href="#" class="list-group-item" ' + str_datahtml + '>' + j[settings.mainDBField] + '</a>';
});
$(that).next('.' + settings.menuClass).html(results);
$(that).next('.' + settings.menuClass).children().on("click", selectResult);
$(that).next('.' + settings.menuClass).show();
}
});
};
};
function selectResult() {
$(that).val($(this).data(settings.mainDBField));
//otherFieldID=true代表要將資料填入到其它欄位
if (settings.otherFieldID) {
for (var i = 0; i < settings.arrFieldID.length; i++) {
$('input[id="' + settings.arrFieldID[i] + '"]').val($(this).data(settings.arrDBField[i]));
};
};
/** //不曉得原作者的用意
if (settings.idField) {
if ($(that).parent().parent().find('input[name="' + settings.idFieldName + '"]').length !== 0) {
//use existed id field
$(that).parent().parent().find('input[name="' + settings.idFieldName + '"]').val($(this).data(settings.mainDBField));
//ensure we trigger the onchange so we can do stuff
$(that).parent().parent().find('input[name="' + settings.idFieldName + '"]').trigger('change');
} else {
//use created id field
$(that).prev('input[name="' + settings.idFieldName + '"]').val($(this).data(settings.mainDBField));
//ensure we trigger the onchange so we can do stuff
$(that).prev('input[name="' + settings.idFieldName + '"]').trigger('change');
};
};
*/
$(that).next('.' + settings.menuClass).hide();
return false;
};
return this;
};
}(jQuery));
</script>
</head>
<body>
<form id="form1" runat="server">
<div class="container-fluid">
<div class="row">
<div class="col-xs-12">
<asp:Label ID="L_cname" runat="server" Text="請輸入要查詢的姓名" Font-Size="X-Large" AssociatedControlID="TB_cname"></asp:Label>
<asp:TextBox ID="TB_cname" runat="server" CssClass="form-control"></asp:TextBox>
<script type="text/javascript">
$('#<%=TB_cname.ClientID%>').bootcomplete_new1({
idField:false,
url: 'getData2.aspx',
minLength: 1,
method: 'post',
dataParams: {
'k': '1'
},
mainDBField:'f1',
otherFieldID: true,
arrFieldID: ['<%=TB_iden.ClientID%>', '<%=TB_email.ClientID%>', '<%=TB_addr.ClientID%>'],
arrDBField: ['f2', 'addr', 'mail']
});
</script>
</div>
<div class="col-xs-12">
<asp:Label ID="L_iden" runat="server" Text="身分證字號" Font-Size="X-Large" AssociatedControlID="TB_iden"></asp:Label>
<asp:TextBox ID="TB_iden" runat="server" CssClass="form-control"></asp:TextBox>
</div>
<div class="col-xs-12">
<asp:Label ID="L_email" runat="server" Text="信箱" Font-Size="X-Large" AssociatedControlID="TB_email"></asp:Label>
<asp:TextBox ID="TB_email" runat="server" CssClass="form-control"></asp:TextBox>
</div>
<div class="col-xs-12">
<asp:Label ID="L_addr" runat="server" Text="地址" Font-Size="X-Large" AssociatedControlID="TB_addr"></asp:Label>
<asp:TextBox ID="TB_addr" runat="server" CssClass="form-control"></asp:TextBox>
</div>
</div>
</div>
</form>
</body>
</html>
說明紅色的部分
bootcomplete_new1:我將原本的套件bootcomplete,重新修改它的名子為bootcomplete_new1。
mainDBField、otherFieldID、arrFieldID、arrDBField:這幾個參數是我額外自己加上去的,mainDBField設定主要的欄位也就是f1要填回原本的TextBox欄位、otherFieldID是否有其他的欄位要填入資料、arrFieldID其他的欄位ID名稱、arrDBField其他資料庫資料表的欄位名稱也就是f2,addr,mail;arrFieldID與arrDBField參數必須要一致,資料才能順利填到我們要的位置。
以上我有將一些說明寫在註解裡,也有把一些原作者的語法註解掉,可能原作者還在開發或修改階段,所以不清楚他的用意,以上如有錯誤請指正,謝謝。
Bootstrap ASP.NET TextBox使用jquery.bootcomplete.js達到自動完成功能
參考資料:bootcomplete.js
參考資料:Demo jquery.bootcomplete.js
說說這個禮拜作了什麼...最近在使用ASP.NET WebForm加上Bootstrap達到響應式,因要讓使用者在TextBox上輸入關鍵字時,可以搜尋出相關的資料,就像是Google在搜尋資料的時候也會跑出關鍵字,這就叫作自動完成功能,先前自己也有紀錄過一篇jquery autocomplete自動完成,但這次因為有加上Bootstrap,想說應該介面上有什麼不一樣的地方,所以就上Google key入了bootstrap autocomplete關鍵字,就找到了jquery.bootcomplete.js別人寫好的jquery套件(別人寫好的我都稱它為套件)。
好...發這篇主要是紀錄過程,將來如果有同樣的需求,可以趕快的恢復遺忘的記憶....
Step 1.先介紹待會會用到的資料表,就一個資料表,稱它為會員(test_member)資料表
Step 2.首先先作好使用者介面,此網頁為test_bootcomplete.aspx
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="test_bootcomplete.aspx.vb" Inherits="test_bootcomplete" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>test bootcomplete</title>
<link rel="stylesheet" href="css/bootstrap.css" />
<script src="js/jquery-1.11.3.js"></script>
<script src="js/bootstrap.js"></script>
<script src="js/jquery.bootcomplete.js"></script>
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
<form id="form1" runat="server">
<div class="container-fluid">
<div class="row">
<div class="col-xs-12">
<asp:Label ID="L_cname" runat="server" Text="請輸入要查詢的姓名" Font-Size="X-Large" AssociatedControlID="TB_cname"></asp:Label>
<asp:TextBox ID="TB_cname" runat="server" CssClass="form-control"></asp:TextBox>
<script type="text/javascript">
$('#<%=TB_cname.ClientID%>').bootcomplete({
url: 'getData.aspx',
minLength: 2,
method: 'post',
dataParams: {
'k': '1'
}
});
</script>
</div>
</div>
</div>
</form>
</body>
</html>
說明紅色的部分:
url 希望傳到哪一個網頁幫我們作查詢。
minLength 最少輸入幾個字,才幫我們作查詢。
method 使用什麼方式傳給另外一個網頁,就像form的get、post。
dataParams 我們可以額外帶參數給另外一個網頁,此參數為k,k的資料為1。
如果有使用過jquery ajax應該就會知道怎麼使用。
畫面結果:
Step 3.製作getData.aspx網頁
getData.aspx前端的網頁只留一行
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="getData.aspx.vb" Inherits="getData" %>
getData.aspx.vb後置程式碼
Imports System.Data
Imports System.Data.SqlClient
Imports Newtonsoft.Json
Partial Class getData
Inherits System.Web.UI.Page
Dim str_sql As String = String.Empty
Private Sub getData_Load(sender As Object, e As EventArgs) Handles Me.Load
'進到getData.aspx最好作個身分驗證,免得重要資訊外流
If Not Page.IsPostBack Then
'第一次進入
Dim str_rdata As StringBuilder = Nothing
If (Not Request("k") Is Nothing) Then
If Request("k").ToString = "1" Then
Dim str_query As String = String.Empty
If (Not Request("query") Is Nothing) Then
str_query = Request("query").ToString
End If
str_rdata = New StringBuilder()
Dim def_ds As New DataSet()
str_sql = "select id_no as id,cname as label from test_member where cname like @cname+'%'"
Using conn As New SqlConnection("Server=127.0.0.1;uid=test;pwd=test;Database=test1")
Using command As SqlCommand = New SqlCommand(str_sql, conn)
'避免 SQL Injection(資料隱碼)攻擊
If command.Parameters.Contains("@cname") Then
command.Parameters("@cname").Value = str_query
Else
command.Parameters.AddWithValue("@cname", str_query) '讓ADO.NET自行判斷型別轉換
End If
Using da As New SqlDataAdapter()
da.SelectCommand = command
da.Fill(def_ds)
End Using
End Using
End Using
str_rdata.Append(JsonConvert.SerializeObject(def_ds.Tables(0), Formatting.Indented))
Response.Write(str_rdata.ToString)
def_ds.Clear() : def_ds.Dispose()
Else
Response.Write("[]")
End If
Else
Response.Write("[]")
End If
End If
End Sub
End Class
注意:程式碼中有使用到Newtonsoft.Json套件
說明紅色的部分:
Request("k") 是剛才在test_bootcomplete.aspx,所帶入的k參數。
Request("query") query是什麼呢? 這個是 jquery.bootcomplete.js它使用的參數,也就是當使用者在TextBox輸入關鍵字帶給getData.aspx的參數值,它已經預設好名稱叫query,所以在js檔中可以找到query這個參數,請各位去開啟 jquery.bootcomplete.js檔案,圖解如下。
SQL指令中的id_no as id,cname as label,是什麼意思呢? 這個也是在 jquery.bootcomplete.js會用到的參數,會把搜尋出來的結果呈現給使用者看,也就是會跟TextBox有所關聯。
執行結果:
這雖然是別人寫的套件,但我覺得可以從中學習到一些技巧,以上如果有錯誤請指正,因為是用自己的方法去理解,所以可能有些地方不正確,還請多多指教。
參考資料:Demo jquery.bootcomplete.js
說說這個禮拜作了什麼...最近在使用ASP.NET WebForm加上Bootstrap達到響應式,因要讓使用者在TextBox上輸入關鍵字時,可以搜尋出相關的資料,就像是Google在搜尋資料的時候也會跑出關鍵字,這就叫作自動完成功能,先前自己也有紀錄過一篇jquery autocomplete自動完成,但這次因為有加上Bootstrap,想說應該介面上有什麼不一樣的地方,所以就上Google key入了bootstrap autocomplete關鍵字,就找到了jquery.bootcomplete.js別人寫好的jquery套件(別人寫好的我都稱它為套件)。
好...發這篇主要是紀錄過程,將來如果有同樣的需求,可以趕快的恢復遺忘的記憶....
Step 1.先介紹待會會用到的資料表,就一個資料表,稱它為會員(test_member)資料表
Step 2.首先先作好使用者介面,此網頁為test_bootcomplete.aspx
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="test_bootcomplete.aspx.vb" Inherits="test_bootcomplete" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>test bootcomplete</title>
<link rel="stylesheet" href="css/bootstrap.css" />
<script src="js/jquery-1.11.3.js"></script>
<script src="js/bootstrap.js"></script>
<script src="js/jquery.bootcomplete.js"></script>
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
<form id="form1" runat="server">
<div class="container-fluid">
<div class="row">
<div class="col-xs-12">
<asp:Label ID="L_cname" runat="server" Text="請輸入要查詢的姓名" Font-Size="X-Large" AssociatedControlID="TB_cname"></asp:Label>
<asp:TextBox ID="TB_cname" runat="server" CssClass="form-control"></asp:TextBox>
<script type="text/javascript">
$('#<%=TB_cname.ClientID%>').bootcomplete({
url: 'getData.aspx',
minLength: 2,
method: 'post',
dataParams: {
'k': '1'
}
});
</script>
</div>
</div>
</div>
</form>
</body>
</html>
說明紅色的部分:
url 希望傳到哪一個網頁幫我們作查詢。
minLength 最少輸入幾個字,才幫我們作查詢。
method 使用什麼方式傳給另外一個網頁,就像form的get、post。
dataParams 我們可以額外帶參數給另外一個網頁,此參數為k,k的資料為1。
如果有使用過jquery ajax應該就會知道怎麼使用。
畫面結果:
Step 3.製作getData.aspx網頁
getData.aspx前端的網頁只留一行
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="getData.aspx.vb" Inherits="getData" %>
getData.aspx.vb後置程式碼
Imports System.Data
Imports System.Data.SqlClient
Imports Newtonsoft.Json
Partial Class getData
Inherits System.Web.UI.Page
Dim str_sql As String = String.Empty
Private Sub getData_Load(sender As Object, e As EventArgs) Handles Me.Load
'進到getData.aspx最好作個身分驗證,免得重要資訊外流
If Not Page.IsPostBack Then
'第一次進入
Dim str_rdata As StringBuilder = Nothing
If (Not Request("k") Is Nothing) Then
If Request("k").ToString = "1" Then
Dim str_query As String = String.Empty
If (Not Request("query") Is Nothing) Then
str_query = Request("query").ToString
End If
str_rdata = New StringBuilder()
Dim def_ds As New DataSet()
str_sql = "select id_no as id,cname as label from test_member where cname like @cname+'%'"
Using conn As New SqlConnection("Server=127.0.0.1;uid=test;pwd=test;Database=test1")
Using command As SqlCommand = New SqlCommand(str_sql, conn)
'避免 SQL Injection(資料隱碼)攻擊
If command.Parameters.Contains("@cname") Then
command.Parameters("@cname").Value = str_query
Else
command.Parameters.AddWithValue("@cname", str_query) '讓ADO.NET自行判斷型別轉換
End If
Using da As New SqlDataAdapter()
da.SelectCommand = command
da.Fill(def_ds)
End Using
End Using
End Using
str_rdata.Append(JsonConvert.SerializeObject(def_ds.Tables(0), Formatting.Indented))
Response.Write(str_rdata.ToString)
def_ds.Clear() : def_ds.Dispose()
Else
Response.Write("[]")
End If
Else
Response.Write("[]")
End If
End If
End Sub
End Class
注意:程式碼中有使用到Newtonsoft.Json套件
說明紅色的部分:
Request("k") 是剛才在test_bootcomplete.aspx,所帶入的k參數。
Request("query") query是什麼呢? 這個是 jquery.bootcomplete.js它使用的參數,也就是當使用者在TextBox輸入關鍵字帶給getData.aspx的參數值,它已經預設好名稱叫query,所以在js檔中可以找到query這個參數,請各位去開啟 jquery.bootcomplete.js檔案,圖解如下。
SQL指令中的id_no as id,cname as label,是什麼意思呢? 這個也是在 jquery.bootcomplete.js會用到的參數,會把搜尋出來的結果呈現給使用者看,也就是會跟TextBox有所關聯。
執行結果:
這雖然是別人寫的套件,但我覺得可以從中學習到一些技巧,以上如果有錯誤請指正,因為是用自己的方法去理解,所以可能有些地方不正確,還請多多指教。
2017年5月25日 星期四
ASP.NET 為RadioButtonList套上Bootstrap
參考資料:RadioButtonList toggle button with databind
參考資料:ASP.NET 4.0 New Feature : 清單控制項之延伸RepeatLayout功能
Step 1.前端aspx
注意:RepeatLayout要設為Flow,當程式經過轉譯後,前端的html會轉換為span標籤,這樣比較符合div。
<head>
...
<link rel="stylesheet" href="css/bootstrap.css" />
<script src="js/jquery-1.11.3.js"></script>
<script src="js/bootstrap.js"></script>
...
<script type="text/javascript">
$(document).ready(function () {
//當PostBack重新載入時,要能夠呈現被選取的狀態
var allspan;
allspan = $('#<%=RadioButtonList1.ClientID%>').find('span');
for (var i = 0; i < allspan.length; i++) {
if ($(allspan[i]).find('input[type="radio"]').prop('checked') == true) {
$(allspan[i]).addClass('active');
//因asp.net radiobuttonlist會記錄選了哪一個選項,所以不用再做一次checked的設定
//$(allspan[i]).find('input[type="radio"]').prop('checked', true);
} else {
$(allspan[i]).removeClass('active');
};
};
//===================================================
//當點選RadioButtonList時,要可以呈現被選取的狀態
$('#<%=RadioButtonList1.ClientID%> .btn-success').click(function () {
$(this).addClass('active');
allspan = $('#<%=RadioButtonList1.ClientID%>').find('span');
for (var i = 0; i < allspan.length; i++) {
if (allspan[i] == this) {
//$(this).find('input[type="radio"]').prop('checked', true);
//alert($(this).find('input[type="radio"]').val());
}else {
$(allspan[i]).removeClass('active');
};
};
});
});
</script>
</head>
<body>
<form id="form1" runat="server">
...
<div class="container-fluid">
<div class="row">
<div class="col-xs-12 col-md-12">
<asp:RadioButtonList ID="RadioButtonList1" runat="server" RepeatDirection="Horizontal" RepeatLayout="Flow" class="btn-group" data-toggle="buttons" >
<asp:ListItem Value="A" >這是項目A</asp:ListItem>
<asp:ListItem Value="B" >這是項目B</asp:ListItem>
<asp:ListItem Value="C" >這是項目C</asp:ListItem>
<asp:ListItem Value="D" >這是項目D</asp:ListItem>
</asp:RadioButtonList>
<asp:Button ID="Button1" runat="server" Text="PostBack" />
</div>
</div>
</div>
...
</form>
</body>
Step 2.後端aspx.vb
Private Sub test_rbl_bootstrap_Load(sender As Object, e As EventArgs) Handles Me.Load
For x As Integer = 0 To RadioButtonList1.Items.Count - 1
RadioButtonList1.Items(x).Attributes.Add("class", "btn btn-success") 'btn-success
Next
End Sub
結果:
參考資料:ASP.NET 4.0 New Feature : 清單控制項之延伸RepeatLayout功能
Step 1.前端aspx
注意:RepeatLayout要設為Flow,當程式經過轉譯後,前端的html會轉換為span標籤,這樣比較符合div。
<head>
...
<link rel="stylesheet" href="css/bootstrap.css" />
<script src="js/jquery-1.11.3.js"></script>
<script src="js/bootstrap.js"></script>
...
<script type="text/javascript">
$(document).ready(function () {
//當PostBack重新載入時,要能夠呈現被選取的狀態
var allspan;
allspan = $('#<%=RadioButtonList1.ClientID%>').find('span');
for (var i = 0; i < allspan.length; i++) {
if ($(allspan[i]).find('input[type="radio"]').prop('checked') == true) {
$(allspan[i]).addClass('active');
//因asp.net radiobuttonlist會記錄選了哪一個選項,所以不用再做一次checked的設定
//$(allspan[i]).find('input[type="radio"]').prop('checked', true);
} else {
$(allspan[i]).removeClass('active');
};
};
//===================================================
//當點選RadioButtonList時,要可以呈現被選取的狀態
$('#<%=RadioButtonList1.ClientID%> .btn-success').click(function () {
$(this).addClass('active');
allspan = $('#<%=RadioButtonList1.ClientID%>').find('span');
for (var i = 0; i < allspan.length; i++) {
if (allspan[i] == this) {
//$(this).find('input[type="radio"]').prop('checked', true);
//alert($(this).find('input[type="radio"]').val());
}else {
$(allspan[i]).removeClass('active');
};
};
});
});
</script>
</head>
<body>
<form id="form1" runat="server">
...
<div class="container-fluid">
<div class="row">
<div class="col-xs-12 col-md-12">
<asp:RadioButtonList ID="RadioButtonList1" runat="server" RepeatDirection="Horizontal" RepeatLayout="Flow" class="btn-group" data-toggle="buttons" >
<asp:ListItem Value="A" >這是項目A</asp:ListItem>
<asp:ListItem Value="B" >這是項目B</asp:ListItem>
<asp:ListItem Value="C" >這是項目C</asp:ListItem>
<asp:ListItem Value="D" >這是項目D</asp:ListItem>
</asp:RadioButtonList>
<asp:Button ID="Button1" runat="server" Text="PostBack" />
</div>
</div>
</div>
...
</form>
</body>
Step 2.後端aspx.vb
Private Sub test_rbl_bootstrap_Load(sender As Object, e As EventArgs) Handles Me.Load
For x As Integer = 0 To RadioButtonList1.Items.Count - 1
RadioButtonList1.Items(x).Attributes.Add("class", "btn btn-success") 'btn-success
Next
End Sub
結果:
訂閱:
文章 (Atom)








