从 GridView 事件获取模态显示的问题
Problem getting modal to display from GridView event
在有人说之前,我已经尝试了我能找到的所有示例,但到目前为止似乎没有任何效果,所以这就是我发布新问题的原因。
我正在处理一个 ASP.NET 网络表单项目,我有一个包含 GridView 控件的页面,该控件有多个命令按钮,用于代表不同选项的每条记录。其中之一是“订阅”,我想用它在 Bootstrap 模态对话框中显示订阅记录的详细信息。我将模态对话框代码剥离到最低限度:
<asp:Panel ID="pnlSubscriptionPopUp" runat="server" Visible="false">
<div id="SubscriptionPopUp" class="modal fade" role="dialog">
<div class="modal-dialog modal-dialog-scrollable modal-dialog-centered modal-lg">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Subscription Details</h4>
</div>
<div class="modal-body">
</div>
<div class="modal-footer">
<button id="Button1" runat="server" onclick="btnCancel_Click" cssclass="btn btn-primary">Cancel</button>
<button id="btnClose" class="btn btn-success">Close</button>
</div>
</div>
</div>
</div>
</asp:Panel>
这是我正在使用的 JavaScript 代码:
<script type="text/javascript">
$(document).ready(function () {
$("#SubscriptionPopUp").modal("show");
$("#btnClose").click(function () {
$("#SubscriptionPopUp").modal("hide");
});
});
function ShowStatus() {
console.log("got here!");
$("#SubscriptionPopUp").modal("show");
}
</script>
现在,当我单击 GridView 中的按钮时,它会很好地触发 RowCommand 事件,下面是我包含的用于注册和调用客户端脚本的代码:
ScriptManager.RegisterStartupScript ( this.Page, this.GetType ( ), "ShowSubscriptionStatus", "ShowStatus();", true );
因此,所有代码都会触发,如果您注意到的话,我使用了 JavaScript 函数来记录一条消息,这确实有效。问题是,模态形式从未出现过。控制台中没有任何类型的错误或消息,没有调试错误……什么都没有。
我很困惑为什么它没有正确触发,或者为什么我至少没有收到任何类型的错误消息。
这是我写的一个小示例,希望它能让您了解如何修复您的问题,因为我并不真正了解您的 GridView 设置。尽管可能只是将 document.ready()
添加到您的 ShowStatus()
可能会解决此问题。
前端
<asp:Content ContentPlaceHolderID="headcontent" runat="server">
<script type="text/javascript">
function ShowStatus() {
$(document).ready(function () {
$("#SubscriptionPopUp").modal("show");
})
}
function closeModal(e) {
e.preventDefault();
$("#SubscriptionPopUp").modal("hide");
return false; // don't want a post back
}
</script>
</asp:Content>
<asp:Content ContentPlaceHolderID="MainContentHolder" runat="server">
<asp:GridView ID="gvTest" runat="server" AutoGenerateColumns="false" OnRowDataBound="gvTest_RowDataBound" OnRowCommand="gvTest_RowCommand">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<div class="row">
<asp:Button ID="btnShowSubscription" runat="server" CommandName="Subscription" Text="Show Subscription Data" />
</div>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<div id="SubscriptionPopUp" class="modal fade" role="dialog">
<div class="modal-dialog modal-dialog-scrollable modal-dialog-centered modal-lg">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Subscription Details</h4>
</div>
<div class="modal-body">
<asp:Label ID="lblTestOutput" runat="server" />
</div>
<div class="modal-footer">
<button id="btnClose" onclick="closeModal(event)" class="btn btn-success">Close</button>
</div>
</div>
</div>
</div>
</asp:Content>
代码隐藏
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
List<String> names = new List<string>() { "Kobe", "Jordan", "Wilt" };
gvTest.DataSource = names;
gvTest.DataBind();
}
}
protected void gvTest_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
Button btnShowSubscription = (Button)e.Row.FindControl("btnShowSubscription");
if (btnShowSubscription != null)
{
// usually if my DataItem is an object, I'll cast it first and make sure it's not null
btnShowSubscription.CommandArgument = (string)e.Row.DataItem;
}
}
}
protected void gvTest_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (string.Equals(e.CommandName, "Subscription"))
{
// again, probably cast this and do a !string.IsNullOrWhiteSpace() check
switch ((string)e.CommandArgument)
{
case "Kobe":
this.lblTestOutput.Text = "Kobe is the best";
break;
case "Wilt":
this.lblTestOutput.Text = "Wilt is the best";
break;
case "Jordan":
this.lblTestOutput.Text = "Jordan is the best";
break;
}
ClientScript.RegisterClientScriptBlock(typeof(string), "ShowSubscriptionStatus", "ShowStatus();", true);
}
}
好的,已经做了很多次了?
我真的很喜欢 bootstrap 很多事情。但是,对于对话,我跳到了 jQuery.UI。
我发现添加此 class 和 class 的标记有点太多,无法使此类对话框正常工作。
你在下面有一个非常好的答案——(我投了这个答案)。
我也尽量避免文档“就绪”代码(除非我必须这样做——它总是很难调试)。
但是,我发现 jQuery.UI 只是简单的“div”,您可以将其放在页面上(显示:none 隐藏)。就是这样!
所以,假设我们有一个网格,单击一行,我们想在 div 中显示该行数据。
所以,我们的网格是这样的:
<div style="width:40%">
<asp:GridView ID="MyGrid" runat="server" CssClass="table table-hover"
DataKeyNames="ID" AutoGenerateColumns="false"
OnSelectedIndexChanged="MyGrid_SelectedIndexChanged" >
<Columns>
<asp:BoundField DataField="FirstName" HeaderText="FirstName" />
<asp:BoundField DataField="LastName" HeaderText="Last Name" />
<asp:BoundField DataField="HotelName" HeaderText="Hotel Name" />
<asp:BoundField DataField="City" HeaderText="City" />
<asp:BoundField DataField="Province" HeaderText="Porvince" />
<asp:Templatefield HeaderText ="View">
<ItemTemplate>
<asp:Button ID="cmdView" runat="server" Text="View"
CommandName = "Select"/>
</ItemTemplate>
</asp:Templatefield>
</Columns>
</asp:GridView>
没什么特别的。
注意:我没有使用模板化字段。如果这样做,则必须使用查找控件来代替“本示例的简单”.cells 集合。
所以,上面是标记。
这是我们要在上面加载的代码:
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack == false)
{
LoadGrid();
}
}
public void LoadGrid()
{
using (SqlCommand cmdSQL = new SqlCommand("SELECT TOP 12 * from tblHotels ORDER BY HotelName",
new SqlConnection(Properties.Settings.Default.TEST3)))
{
cmdSQL.Connection.Open();
MyGrid.DataSource = cmdSQL.ExecuteReader();
MyGrid.DataBind();
}
}
好的,到目前为止一切顺利。
我们现在有了这个:
现在让我们添加我们的 pop div。
<div id="mypop" style="display:none">
<br />
<div style="text-align:right">
<p>Hotel Name:<asp:TextBox ID="txtHotel" runat="server"></asp:TextBox></p>
<p>First Name:<asp:TextBox ID="txtFirst" runat="server"></asp:TextBox></p>
<p>Last Name:<asp:TextBox ID="txtLast" runat="server"></asp:TextBox></p>
<p>City:<asp:TextBox ID="txtCity" runat="server"></asp:TextBox></p>
<p>Province:<asp:TextBox ID="txtProvince" runat="server"></asp:TextBox></p>
</div>
</div>
再一次,很好 - 简单而漂亮的飞机简 div 这将是我们的弹出窗口。
(请注意我们如何没有 gazzllion class 和设置 - 非常好和简单)。
现在,该按钮具有“魔法”CommandName =“Select”,因此将触发 Selected 索引更改事件。
所以,我们弹出对话框的代码是这样的:
protected void MyGrid_SelectedIndexChanged(object sender, EventArgs e)
{
// fill out dialog boxes
GridViewRow dG = MyGrid.SelectedRow;
txtFirst.Text = dG.Cells[0].Text;
txtLast.Text = dG.Cells[1].Text; ;
txtHotel.Text = dG.Cells[2].Text; ;
txtCity.Text = dG.Cells[3].Text; ;
txtProvince.Text = dG.Cells[4].Text; ;
// call our js routine to pop
ScriptManager.RegisterStartupScript(this.Page, this.GetType(),"my test","poptest()", true);
}
最后但并非最重要的是,上面调用的 jQuery.UI pop 例程。
<script>
function poptest() {
var mydiv = $('#mypop')
mydiv.dialog({
autoOpen: false, modal: true, title: 'Hotel Information', width: '400px',
position: { my: 'top', at: 'top+150' },
closeText: '',
buttons: {
'ok': function () {
// $('#cmdAdd').click() - click standard asp button
mydiv.dialog('close')
},
'cancel': function () {
mydiv.dialog('close')
}
}
});
// Open the dialog
// mydiv.parent().appendTo($("form:first")) - only add if editing in div
mydiv.dialog('open')
}
</script>
现在上面的好处是我们有两个按钮 - 我展示了如何关闭对话框 - 但我们也可以 call/click 在表单上说一个按钮到 运行 代码基于任一选择(我确实建议为这些按钮设置 ClientIDMode="Static",因此上面用于确定或取消的非常简单的代码可以因此只需“单击()”那个按钮。这样你就不必花哨的脚根据选择调用代码。
当对话框弹出时,它会自动将页面的其余部分“变暗”,并启用除对话框之外的所有其他控件。
现在,结果如下所示:
如您所见,我们在这里的努力得到了很大的回报。一个简单的 div 变成了那个相当不错的对话框。我们有一组简单的按钮,它们是对话框的一部分,然后可以根据您在对话框支持的那些按钮上单击的内容执行操作。
对于建议一条不同的道路,我深表歉意。我发现 jQuery.UI 对话框很好用,非常简单。如果有人愿意构建一个可爱的小库来使用带有 bootstrap 对话框的简单 divs - 请注册! - 但我在尝试使 bootstrap 对话框正常工作时发现了太多“问题”。这很可能是我的缺点 - 但通常只有一个简单的 div + jQuery.UI 对话框的简单方法非常有效。
在有人说之前,我已经尝试了我能找到的所有示例,但到目前为止似乎没有任何效果,所以这就是我发布新问题的原因。
我正在处理一个 ASP.NET 网络表单项目,我有一个包含 GridView 控件的页面,该控件有多个命令按钮,用于代表不同选项的每条记录。其中之一是“订阅”,我想用它在 Bootstrap 模态对话框中显示订阅记录的详细信息。我将模态对话框代码剥离到最低限度:
<asp:Panel ID="pnlSubscriptionPopUp" runat="server" Visible="false">
<div id="SubscriptionPopUp" class="modal fade" role="dialog">
<div class="modal-dialog modal-dialog-scrollable modal-dialog-centered modal-lg">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Subscription Details</h4>
</div>
<div class="modal-body">
</div>
<div class="modal-footer">
<button id="Button1" runat="server" onclick="btnCancel_Click" cssclass="btn btn-primary">Cancel</button>
<button id="btnClose" class="btn btn-success">Close</button>
</div>
</div>
</div>
</div>
</asp:Panel>
这是我正在使用的 JavaScript 代码:
<script type="text/javascript">
$(document).ready(function () {
$("#SubscriptionPopUp").modal("show");
$("#btnClose").click(function () {
$("#SubscriptionPopUp").modal("hide");
});
});
function ShowStatus() {
console.log("got here!");
$("#SubscriptionPopUp").modal("show");
}
</script>
现在,当我单击 GridView 中的按钮时,它会很好地触发 RowCommand 事件,下面是我包含的用于注册和调用客户端脚本的代码:
ScriptManager.RegisterStartupScript ( this.Page, this.GetType ( ), "ShowSubscriptionStatus", "ShowStatus();", true );
因此,所有代码都会触发,如果您注意到的话,我使用了 JavaScript 函数来记录一条消息,这确实有效。问题是,模态形式从未出现过。控制台中没有任何类型的错误或消息,没有调试错误……什么都没有。
我很困惑为什么它没有正确触发,或者为什么我至少没有收到任何类型的错误消息。
这是我写的一个小示例,希望它能让您了解如何修复您的问题,因为我并不真正了解您的 GridView 设置。尽管可能只是将 document.ready()
添加到您的 ShowStatus()
可能会解决此问题。
前端
<asp:Content ContentPlaceHolderID="headcontent" runat="server">
<script type="text/javascript">
function ShowStatus() {
$(document).ready(function () {
$("#SubscriptionPopUp").modal("show");
})
}
function closeModal(e) {
e.preventDefault();
$("#SubscriptionPopUp").modal("hide");
return false; // don't want a post back
}
</script>
</asp:Content>
<asp:Content ContentPlaceHolderID="MainContentHolder" runat="server">
<asp:GridView ID="gvTest" runat="server" AutoGenerateColumns="false" OnRowDataBound="gvTest_RowDataBound" OnRowCommand="gvTest_RowCommand">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<div class="row">
<asp:Button ID="btnShowSubscription" runat="server" CommandName="Subscription" Text="Show Subscription Data" />
</div>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<div id="SubscriptionPopUp" class="modal fade" role="dialog">
<div class="modal-dialog modal-dialog-scrollable modal-dialog-centered modal-lg">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Subscription Details</h4>
</div>
<div class="modal-body">
<asp:Label ID="lblTestOutput" runat="server" />
</div>
<div class="modal-footer">
<button id="btnClose" onclick="closeModal(event)" class="btn btn-success">Close</button>
</div>
</div>
</div>
</div>
</asp:Content>
代码隐藏
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
List<String> names = new List<string>() { "Kobe", "Jordan", "Wilt" };
gvTest.DataSource = names;
gvTest.DataBind();
}
}
protected void gvTest_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
Button btnShowSubscription = (Button)e.Row.FindControl("btnShowSubscription");
if (btnShowSubscription != null)
{
// usually if my DataItem is an object, I'll cast it first and make sure it's not null
btnShowSubscription.CommandArgument = (string)e.Row.DataItem;
}
}
}
protected void gvTest_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (string.Equals(e.CommandName, "Subscription"))
{
// again, probably cast this and do a !string.IsNullOrWhiteSpace() check
switch ((string)e.CommandArgument)
{
case "Kobe":
this.lblTestOutput.Text = "Kobe is the best";
break;
case "Wilt":
this.lblTestOutput.Text = "Wilt is the best";
break;
case "Jordan":
this.lblTestOutput.Text = "Jordan is the best";
break;
}
ClientScript.RegisterClientScriptBlock(typeof(string), "ShowSubscriptionStatus", "ShowStatus();", true);
}
}
好的,已经做了很多次了?
我真的很喜欢 bootstrap 很多事情。但是,对于对话,我跳到了 jQuery.UI。
我发现添加此 class 和 class 的标记有点太多,无法使此类对话框正常工作。
你在下面有一个非常好的答案——(我投了这个答案)。
我也尽量避免文档“就绪”代码(除非我必须这样做——它总是很难调试)。
但是,我发现 jQuery.UI 只是简单的“div”,您可以将其放在页面上(显示:none 隐藏)。就是这样!
所以,假设我们有一个网格,单击一行,我们想在 div 中显示该行数据。
所以,我们的网格是这样的:
<div style="width:40%">
<asp:GridView ID="MyGrid" runat="server" CssClass="table table-hover"
DataKeyNames="ID" AutoGenerateColumns="false"
OnSelectedIndexChanged="MyGrid_SelectedIndexChanged" >
<Columns>
<asp:BoundField DataField="FirstName" HeaderText="FirstName" />
<asp:BoundField DataField="LastName" HeaderText="Last Name" />
<asp:BoundField DataField="HotelName" HeaderText="Hotel Name" />
<asp:BoundField DataField="City" HeaderText="City" />
<asp:BoundField DataField="Province" HeaderText="Porvince" />
<asp:Templatefield HeaderText ="View">
<ItemTemplate>
<asp:Button ID="cmdView" runat="server" Text="View"
CommandName = "Select"/>
</ItemTemplate>
</asp:Templatefield>
</Columns>
</asp:GridView>
没什么特别的。 注意:我没有使用模板化字段。如果这样做,则必须使用查找控件来代替“本示例的简单”.cells 集合。
所以,上面是标记。
这是我们要在上面加载的代码:
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack == false)
{
LoadGrid();
}
}
public void LoadGrid()
{
using (SqlCommand cmdSQL = new SqlCommand("SELECT TOP 12 * from tblHotels ORDER BY HotelName",
new SqlConnection(Properties.Settings.Default.TEST3)))
{
cmdSQL.Connection.Open();
MyGrid.DataSource = cmdSQL.ExecuteReader();
MyGrid.DataBind();
}
}
好的,到目前为止一切顺利。
我们现在有了这个:
现在让我们添加我们的 pop div。
<div id="mypop" style="display:none">
<br />
<div style="text-align:right">
<p>Hotel Name:<asp:TextBox ID="txtHotel" runat="server"></asp:TextBox></p>
<p>First Name:<asp:TextBox ID="txtFirst" runat="server"></asp:TextBox></p>
<p>Last Name:<asp:TextBox ID="txtLast" runat="server"></asp:TextBox></p>
<p>City:<asp:TextBox ID="txtCity" runat="server"></asp:TextBox></p>
<p>Province:<asp:TextBox ID="txtProvince" runat="server"></asp:TextBox></p>
</div>
</div>
再一次,很好 - 简单而漂亮的飞机简 div 这将是我们的弹出窗口。 (请注意我们如何没有 gazzllion class 和设置 - 非常好和简单)。
现在,该按钮具有“魔法”CommandName =“Select”,因此将触发 Selected 索引更改事件。
所以,我们弹出对话框的代码是这样的:
protected void MyGrid_SelectedIndexChanged(object sender, EventArgs e)
{
// fill out dialog boxes
GridViewRow dG = MyGrid.SelectedRow;
txtFirst.Text = dG.Cells[0].Text;
txtLast.Text = dG.Cells[1].Text; ;
txtHotel.Text = dG.Cells[2].Text; ;
txtCity.Text = dG.Cells[3].Text; ;
txtProvince.Text = dG.Cells[4].Text; ;
// call our js routine to pop
ScriptManager.RegisterStartupScript(this.Page, this.GetType(),"my test","poptest()", true);
}
最后但并非最重要的是,上面调用的 jQuery.UI pop 例程。
<script>
function poptest() {
var mydiv = $('#mypop')
mydiv.dialog({
autoOpen: false, modal: true, title: 'Hotel Information', width: '400px',
position: { my: 'top', at: 'top+150' },
closeText: '',
buttons: {
'ok': function () {
// $('#cmdAdd').click() - click standard asp button
mydiv.dialog('close')
},
'cancel': function () {
mydiv.dialog('close')
}
}
});
// Open the dialog
// mydiv.parent().appendTo($("form:first")) - only add if editing in div
mydiv.dialog('open')
}
</script>
现在上面的好处是我们有两个按钮 - 我展示了如何关闭对话框 - 但我们也可以 call/click 在表单上说一个按钮到 运行 代码基于任一选择(我确实建议为这些按钮设置 ClientIDMode="Static",因此上面用于确定或取消的非常简单的代码可以因此只需“单击()”那个按钮。这样你就不必花哨的脚根据选择调用代码。
当对话框弹出时,它会自动将页面的其余部分“变暗”,并启用除对话框之外的所有其他控件。
现在,结果如下所示:
如您所见,我们在这里的努力得到了很大的回报。一个简单的 div 变成了那个相当不错的对话框。我们有一组简单的按钮,它们是对话框的一部分,然后可以根据您在对话框支持的那些按钮上单击的内容执行操作。
对于建议一条不同的道路,我深表歉意。我发现 jQuery.UI 对话框很好用,非常简单。如果有人愿意构建一个可爱的小库来使用带有 bootstrap 对话框的简单 divs - 请注册! - 但我在尝试使 bootstrap 对话框正常工作时发现了太多“问题”。这很可能是我的缺点 - 但通常只有一个简单的 div + jQuery.UI 对话框的简单方法非常有效。