Clicking the "Show" button in the example below shows a simple bootstrap modal dialog with two buttons: Cancel (dismissed with data-dismiss), and "OK" which would presumably do some work on the server side, then call a bit of Javascript to hide the dialog.
The basic concept works fine--until I try to wrap the whole thing in an UpdatePanel as shown below. What the devil am I doing wrong? (And for bonus points, how would I attempt to set up a trace through Javascript which would have told me what I'm screwing up?)
Thanks!
Form Code:
<%# Page Language="VB" AutoEventWireup="false"
CodeFile="Default2.aspx.vb" Inherits="Default2" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<link rel="stylesheet"
href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" />
<link rel="stylesheet"
href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap-theme.min.css" />
<script type="text/javascript" src="/includes/js/jquery-min.js"></script>
<script src="//netdna.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js">
</script>
</head>
<body>
<form id="form1" runat="server">
<ajaxToolkit:ToolkitScriptManager ID="ToolkitScriptManager1"
runat="server" ScriptMode="Debug">
</ajaxToolkit:ToolkitScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<div>
<asp:Panel ID="pnlTestPanel" runat="server" role="dialog"
CssClass="modal fade TestDialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close"
data-dismiss="modal"
aria-hidden="true">×
</button>
<h2 class="modal-title">Test Dialog</h2>
</div>
<asp:Panel runat="server" ID="pnlTestBody"
class="modal-body">
<label>This is a test dialog</label>
</asp:Panel>
<asp:Panel runat="server" ID="Panel3"
class="modal-footer">
<asp:Button ID="cmdOK" runat="server"
Text="OK"
CssClass="btn btn-warning">
</asp:Button>
<asp:Button ID="cmdCancel" runat="server"
CssClass="btn btn-default"
Text="Cancel"
data-dismiss="modal">
</asp:Button>
</asp:Panel>
</div>
</div>
</asp:Panel>
<asp:Button runat="server" Text="Show" ID="cmdShow" />
</div>
</ContentTemplate>
</asp:UpdatePanel>
</form>
</body>
</html>
Code-behind code
Partial Class Default2
Inherits System.Web.UI.Page
Protected Sub cmdShow_Click(sender As Object, e As EventArgs) Handles cmdShow.Click
ScriptManager.RegisterStartupScript(Page, Page.GetType(), "pnlTestPanel", _
"$('#" & pnlTestPanel.ClientID & "').modal();", True)
End Sub
Protected Sub cmdOK_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles cmdOK.Click
' Do some server side work
' And now, close the dialog
ScriptManager.RegisterStartupScript(Me.UpdatePanel1, UpdatePanel1.GetType(), _
"Hide Test Dialog", "$('.TestDialog').modal('hide');", True)
End Sub
End Class
The ScriptManager.RegisterStartupScript will only work when you there is a full PostBack. In your case the PostBack occurs inside an UpdatePanel.
You will need to use the JavaScript events that ASP.NET has when an UpdatePanel is updated.
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_beginRequest(BeginRequestHandler);
prm.add_endRequest(EndRequestHandler);
function BeginRequestHandler(sender, args) {
console.log('UpdatePanel start');
}
function EndRequestHandler(sender, args) {
console.log('UpdatePanel end');
}
You need to put your code in the EndRequestHandler event to close the modal.
For more info you can read here and here.
Even if button is inside an update panel, the script manager will still work as you are passing updatepanel & not the page as its parameter..
There is only one thing missing.
Write this statement inside your Register startup script.
$(document).ready(function () {
$('.TestDialog').modal('hide');
});
The best approach I found was to create a simple javascript function.
function closeModal(modalid) {
$('#' + modalid).modal('hide');
}
Then, in your various Modals on the page, you can set a OnClientClick value of the Submit/Create button to "closeModal('id_of_your_modal_container');"
I can then use UpdatePanels with Triggers, as well as all the normal trimmings I want on the page (Toastr notifications etc), and it works very seamlessly. If it's just a standard button or anchor tag then setting a data attribute is all you need 'data-dismiss="modal"'
Related
I've just followed this very basic code on Youtube and it works perfectly. However, I go to try the same code on my asp.net webforms website, have tried it in both chrome and edge, and javascript doesn't seem to want to run. Can anyone please tell me where I am going wrong? I am using Visual Studio 2015. I must have a setting turned off somewhere or something as it does not make any sense to me why a basic alert is failing to run.
Here is the basic code:
<%# Page Language="C#" AutoEventWireup="true" CodeFile="webform.aspx.cs" Inherits="webform" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script type="text/javascript">
function pleaseWork(){
alert("this is running");
};
</script>
</head>
<body>
<form id="form1" runat="server">
<asp:Button ID="Button1" runat="server" Text="Button"/>
</form>
</body>
</html>
protected void Button1_Click(object sender, EventArgs e)
{
ScriptManager.RegisterClientScriptBlock(this, GetType(), "mykey", "pleaseWork();", true);
}
}
If you just need this to execute on the client, then you probably don't need any server side controls for it. So the head section doesn't need to run on the server.
<asp:Button ID="Button1" runat="server" Text="Button" OnClientClick="pleaseWork();"/>
OR
<input type="button" value="Button2" onclick ="pleaseWork();" />
Your button is missing an onclick attribute, so Button1_Click is not being called.
<asp:Button ID="Button1" runat="server" Text="Button" onclick="Button1_Click" />
I have a small problem in Webforms. I'm trying to disable the submit button on submit, to prevent double posts.
The problem is, that the onclick method in codebehind is not getting called if the submit button is disabled during postback. Postback still occurs, but the buttons onclick method doesn't get called.
Is there a way to get around this?
Here a small demo of the problem:
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="default.aspx.cs" Inherits="WebApplication2._default" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script src="Scripts/jquery-2.0.3.min.js"></script>
<script>
function disableButton() {
//$('#<%=btn.ClientID%>').attr('disabled', 'diabled');
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Literal runat="server" ID="ltrDate" />
<asp:Button runat="server" ID="btn" OnClientClick="disableButton();" Text="Hit me!" OnClick="Unnamed_Click" />
</div>
</form>
</body>
</html>
codebehind:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace WebApplication2
{
public partial class _default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Unnamed_Click(object sender, EventArgs e)
{
Thread.Sleep(1000);
ltrDate.Text = DateTime.Now.ToString();
}
}
}
If this code is run, it works fine, but if the // is removed from the javascript method, the buttons onclick method is not being called anymore. (postback still occurs fine)
/Martin
Update:
It seems to be an old issue..
I never got this to work, because when the button is disabled client-side, its information is no longer posted back to the server, so its server-side click event does not fire. I suspect that's the behavior you're seeing.
If you do manage to make this work, I'd love to know how.
Ian Olsen
Wednesday, June 09, 2004
A more simple solution:
<asp:Button ID="btnFind" runat="server" Text="Find"
OnClientClick="if(this.alreadClicked == true) {this.disabled = true;
this.value = 'Wait...';} else {this.alreadClicked = true;}" EnableViewState=false
</asp:Button>
You disable the button anyway and also give the user a feedback "Wait...", but must use EnableViewState=false so the button reset to it's original state when the page refresh.
Ok.. I found the answer :)
The trick is to use Page.GetPostBackEventReference(btn). The method will insert a call to dopostback, and the right events will be fired.
The easy solution is to just insert that line after the javascript line that disables the button. Then it'll work, but if you have client side validation, that wont work. (Or, it'll work, but the submit button will be disabled if the user forgot to enter the required information).
Here's the demo from my original question edited to use client validation, and with the disabeling of the submit button on postback:
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="default.aspx.cs" Inherits="WebApplication2._default" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script src="Scripts/jquery-2.0.3.min.js"></script>
<script>
$(function () {
if (typeof ValidatorUpdateDisplay != 'undefined') {
var originalValidatorUpdateDisplay = ValidatorUpdateDisplay;
ValidatorUpdateDisplay = function (val) {
originalValidatorUpdateDisplay(val);
//Bind();
if (val.isvalid) {
$('#<%=btn.ClientID%>').attr('disabled', 'disabled');
<%=Page.GetPostBackEventReference(btn)%>
}
}
}
});
</script>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager runat="server" />
<div>
<asp:TextBox runat="server" ID="txtFirstname" />
<asp:RequiredFieldValidator runat="server" ControlToValidate="txtFirstname" Display="Dynamic" EnableClientScript="true" ErrorMessage="Please enter your firstname" />
<br />
<asp:Literal runat="server" ID="ltrDate" />
<br />
<asp:Button runat="server" ID="btn" Text="Hit me!" OnClick="Unnamed_Click" />
</div>
</form>
</body>
</html>
Codebehind:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace WebApplication2
{
public partial class _default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Unnamed_Click(object sender, EventArgs e)
{
Thread.Sleep(1000);
ltrDate.Text = DateTime.Now.ToString();
}
}
}
I have mocked up a very simple page and I am absolutely stumped as to why the javascript wont fire when I tab between the 2 textboxes:-
<%# Page Language="C#" AutoEventWireup="true" CodeFile="test.aspx.cs" inherits="Checkout_test" %>
<!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 runat="server">
<title>c</title>
<script type="text/javascript">
function checkthisvalue(source, args) {
alert('hello');
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Label ID="lbl1" AssociatedControlID="txtUsername" Text="1:" runat="server" />
<asp:TextBox runat="server" CssClass="username" ID="txtUsername" ValidationGroup="vg"></asp:TextBox>
<asp:CustomValidator Enabled="true" ID="cvUsername" Display="Dynamic" ValidationGroup="vg" ControlToValidate="txtUsername" EnableClientScript="true" ClientValidationFunction="checkthisvalue" ValidateEmptyText="true" runat="server">*</asp:CustomValidator>
<asp:Label ID="lbl2" AssociatedControlID="txtPassword" Text="2:" runat="server" />
<asp:TextBox runat="server" CssClass="username" ID="txtPassword"></asp:TextBox>
<asp:CustomValidator Enabled="true" ID="cvPassword" Display="Dynamic" ControlToValidate="txtPassword" EnableClientScript="true" ClientValidationFunction="checkthisvalue" ValidateEmptyText="true" runat="server"></asp:CustomValidator>
</div>
</form>
</body>
</html>
Note that both CustomValidators have ValidateEmptyText=true
I've tried this in IE and Chrome with no luck.
I guess it is not a problem of empty text. The CustomValidator won't fire upon tab navigation only if you don't change the control value. (try to put a value in your TextBox, navigate with tab, come back to empty the TextBox, and navigate again with Tab. The CustomValidator will fire)
When thinking about it, having the validators firing upon a simple tab navigation would be somewhat disturbing for the user.
Anyway, the validators will fire upon form submission (provided you remove the ValidationGroup attributes on first TextBox and Validator), and value changes, which is what they are supposed to do.
Hope this will help,
I am working on a project where I want to refresh a part of the web page where i have a user control that contain dynamic data.user control will load data from a text file as this text file will update frequently. I need to refresh the user control alone not the whole page using javascript. I tried the following but it did not worked for me.
<%# Page Language="C#" %>
<%# Register src="ucTest.ascx" tagname="ucTest" tagprefix="uc1" %>
<script runat="server">
void button_Click(object sender, EventArgs e)
{
lbltest.Text = "Refreshed by server side event handler at " + DateTime.Now + ".<br>";
}
</script>
<!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>How to update an UpdatePanel with JavaScript</title>
<script type="text/javascript">
function UpdPanelUpdate()
{
__doPostBack("<%= button.ClientID %>","");
}
</script>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server" />
<div>
Update the Panel
<asp:Button ID="button" runat="server" OnClick="button_Click" style="display:none;"/>
<asp:UpdatePanel runat="server" ID="UpdatePanel1" UpdateMode="Conditional">
<ContentTemplate>
<uc1:ucTest ID="ucTest1" runat="server" />
<asp:Label ID="lbltest" runat="server"></asp:Label>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="button" EventName="Click" />
</Triggers>
</asp:UpdatePanel>
</div>
</form>
</body>
</html>
my user control is.
<%# Control Language="C#" AutoEventWireup="true" CodeFile="ucTest.ascx.cs" Inherits="ucTest" %>
<table border="3">
<tr>
<td>
<% Response.WriteFile("TextFile.txt"); %>
</td>
</tr>
</table>
Here TextFile.txthas some information that will be changed frequently.
any help would be greatly appreciated.
To make things simpler, you can put the hidden button within the UpdatePanel so that you don't have to put async triggers. First keep the button visible and see if the update panel is refreshing or not. If yes then you can hide the button.
Next part is triggering the button by simulating click event. I will suggest you to use library such as jquery from cross-browser solution. For example,
function UpdPanelUpdate()
{
$("<%= button.ClientID %>").click();
}
For code __doPostBack("<%= button.ClientID %>",""); to work, you should try setting button's UseSubmitBehavior property as false.
So, I have an .aspx webpage as follows:
..
<form id="frm" runat="server">
<asp:FileUpload runat="server" id="fileupload" onchange="browsed()" />
<asp:Button runat="server" OnClick="Upload_Click" id="uploadbutton" class="uploadbutton" Text="start upload" Enabled="false" />
<div id="nfo" style="display: none">
blabla
</div>
</form>
..
Now, as you can guess correctly, user chooses file to upload, clicks #uploadbutton and, voila, Upload_Click is called after the postback.
Then, I want to show div #nfo with some jQuery effects during the upload. To do this, I write:
$(function() {
$('.uploadbutton').click(function() {
$('#nfo').slideDown().show("fast");
})
})
and everything works just fine, until the user starts browsing in IE...
First of all, in IE, user has to click #uploadbutton twice - first time to display #nfo, second time, for some reason, to initiate postback.
Secondly, after the postback, Upload_Click's this.fileupload.HasFile shows false.
FF and Chrome works quite well though.
As far, as I can understand this - in IE jQuery's function prevents something important for asp:FileUpload from happening and stops the postback. Though, on the second click it does initiate the postback, but still with no info for asp:FileUpload's Upload_Click.
Any help?
Update:
followed #joelt'd advice. turned out, there was some different problem, never thought it could be of importance, so I didn't provide source code for that part =(
see localizing <asp:FileUpload>. IE problem
<%# Page Language="VB" AutoEventWireup="false" CodeFile="Default.aspx.vb" Inherits="_Default" %>
<!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 runat="server">
<title></title>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$("#Button1").click(function() {
$("#progress").show();
});
});
</script>
</head>
<body>
<form runat="server">
<asp:FileUpload ID="FileUpload1" runat="server" />
<asp:Button ID="Button1" runat="server" Text="Button" />
<div id="progress" style="display:none; background-color:Red;">test</div>
</form>
</body>
</html>
This works fine for me in FF and IE7, except in IE, the progress indicator doesn't really give you anything because of how it's rendering, I suppose. I would say the biggest difference between our code is the "onchange=browsed()" function. It's possible that's not getting called until you click the button? In any case, I would start with a stripped down page like this, and start adding in other elements you have until it breaks.
try this:
<asp:Button runat="server" OnClick="Upload_Click" id="uploadbutton"
class="uploadbutton" Text="start upload" Enabled="false"
OnClientClick="return myFunction();"/>
<script type="text/javascript">
function myFunction(){
$('#nfo').slideDown().show("fast");
return true;//THIS WILL FIRE POSTBACK EVENT
//return false;//THIS WILL STOP POSTBACK EVENT, WHICH YOU MAY WANT IF THERE
//IS NO FILE SELECTED
}
</script>