I followed several web resources to understand how to show a popup from client side, and I made this code:
<asp:ImageButton runat="server" ID="btnOk" ImageUrl="imagens/btnAlterar.gif" OnClientClick="btnOkClick()" />
<asp:LinkButton runat="server" ID="dummyForPopup" Visible="false"/>
<ajaxToolKit:ModalPopupExtender runat="server" BehaviorID="btnOkPopupBehavior" ID="MPXtender" TargetControlID="dummyForPopup" PopupControlID="pnlUpdateUserModal" BackgroundCssClass="modalBackground" OkControlID="btnCloseRequestUserUpdate" OnOkScript="userUpdReq_onOk()" />
function btnOkClick()
{
if(validateAll())
{
var behavior = $find('btnOkPopupBehavior');
if (behavior)
{
behavior.show();
}
else
{
var lblOutput = $get('<%= lblOutput .ClientID %>');
lblOutput .innerText = 'Couldn't find popup';
}
}
}
previously I had the modal popup linked to the ok button, it was working pretty well. Now I need some validation before opening the popup, and this code is not working anylonger =/
1) Your dummy button has to be visible = true, otherwise the javascript doesn't work properly. So set visible = true but disaply none with css:
<asp:LinkButton runat="server"
ID="dummyForPopup" style
="display:none" Visible="true" />
2) lblOutput .innerText = 'Couldn't find popup'; is a javascript error. You need to change it to: "Couldn't find popup"; (or use ')
3) OnClientClick="btnOkClick()" should really say: OnClientClick="btnOkClick(); return false;"
4) Look for any other javascript errors on your page because those will stop the popup from workign properly.
Related
I have a search form consisting of the following...
<asp:Panel DefaultButton="btnSearch" ... >
[...search criteria fields...]
<asp:Button ID="btnReset" OnClick="btnReset_Click" ... />
<asp:Button ID="btnSearch" OnClick="btnSearch_Click" ... />
</asp:Panel>
The desired behaviour is that pressing the Enter key should invoke btnSearch_Click (which is working thanks to the DefaultButton attribute in the asp:panel)
The problem is that when btnReset has focus, pressing Enter should invoke btnReset_Click instead (which it doesn't - it's always btnSearch).
Is this easily achievable somehow, or am I going to have to hack up some bespoke JS to intercept .NET's defaultButton event handler?
Thanks in advance.
ETA: Here's a reusable solution I went with based on HenryChuang's accepted answer below.
Add a custom attribute preventDefaultButton to panels.
<asp:Panel DefaultButton="btnSearch" preventDefaultButton="btnReset" >
[...search criteria fields...]
<asp:Button ID="btnReset" OnClick="btnReset_Click" ... />
<asp:Button ID="btnSearch" OnClick="btnSearch_Click" ... />
</asp:Panel>
Run the following jQuery on pageload.
$("div[preventDefaultButton]").each(function () {
var div = $(this);
var keypressEvent = div.attr("onkeypress");
var btn = $("input[id$=" + div.attr("preventDefaultButton") + "]");
btn.on("focus", { div: div }, function (event) {
event.data.div.attr("onkeypress", "");
});
btn.on("blur", { div: div, keypressEvent: keypressEvent }, function (event) {
event.data.div.attr("onkeypress", event.data.keypressEvent);
});
});
see the panel generate html
<div id="yourPanelClientID" onkeypress="javascript:return WebForm_FireDefaultButton(event, 'btnSearch')">
so, when btnReset onfocus we break onkeypress event of Panel, add below to btnReset,
remember when btnReset onblur, change Panel keypress to oringinal
onfocus="document.getElementById('yourPanelClientID').onkeypress = '';"
onblur="funA();"
function funA() {
document.getElementById('yourPanelClientID').onkeypress = function () { return WebForm_FireDefaultButton(event, "btnSearch") };
}
like this
<asp:Button ID="btnReset"
onfocus="document.getElementById('yourPanelClientID').onkeypress = '';"
onblur="funA();"
onclick="btnReset_Click" .../>
you need to change DefaultButton attribute of your panel but this will work for only one at a time, better way would be to have Javascript to capture enter event and process accordingly.
One way can be having multiple panels, have a look at http://www.jstawski.com/archive/2008/09/23/multiple-default-buttons.aspx
<script type="text/javascript">
function ClientSideClick(myButton) {
//make sure the button is not of type "submit" but "button"
if (myButton.getAttribute('type') == 'button') {
// disable the button
myButton.disabled = true;
//myButton.className = "btn-inactive";
myButton.value = "Posting...";
}
return true;
}
</script>
<asp:UpdatePanel ID="upComments" runat="server" UpdateMode="Always" >
<ContentTemplate>
<asp:ListView ... >
<asp:Button ID="btnSubPostComment" runat="server" Text="Reply Comment"
CommandName="cmdPostSubComment" OnClientClick="ClientSideClick(this)" UseSubmitBehavior="false"
</asp:ListView>
</ContentTemplate>
</asp:UpdatePanel>
The Javascript function (ClientSideClick) disables the button when it's processing.
The problem is that when I include
OnClientClick="ClientSideClick" UseSubmitBehavior="false"
in my button, even though it's inside an Update Panel it causes full postback.
If I remove those two Properties OnClientClic and UseSubmitBehavior the button does not cause full postback. Does anyone know why this happens?
All I wanted to do is disable the button and chagne it's text to prevent multiple submissions.
I'm not sure if this is exactly what you're looking for but I usually use this:
<asp:ScriptManager ID="ScriptManager1" runat="server" />
<script type="text/javascript">
var pbControl = null;
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_beginRequest(BeginRequestHandler);
prm.add_endRequest(EndRequestHandler);
function BeginRequestHandler(sender, args) {
pbControl = args.get_postBackElement();
pbControl.disabled = true;
}
function EndRequestHandler(sender, args) {
pbControl.disabled = false;
pbControl = null;
}
</script>
<asp:UpdatePanel ID="UpdatePanel1" UpdateMode="Conditional" runat="server">
<ContentTemplate>
<asp:ListView ... >
<asp:Button ID="btnSubPostComment" runat="server" Text="Reply Comment" CommandName="cmdPostSubComment" OnClientClick="this.value='Posting...';" />
</asp:ListView>
</ContentTemplate>
</asp:UpdatePanel>
The only problem is that if the same button is clicked again after the first async postback then it throws a "Operation is not valid due to the current state of the object" error. This might appear as a javascript exception in the form of a 500 internal server error. After doing some research, I came across:
"Microsoft recently (12-29-2011) released an update to address several serious security vulnerabilities in the .NET Framework. MS11-100 was introduced just recently that handles potential DoS attacks. Unfortunately the fix has also broken page POSTs with very large amounts of posted data (form fields). MS11-100 places a limit of 500 on postback items. The new default max introduced by the recent security update is 1000."
Scott Gu writes about it here: http://weblogs.asp.net/scottgu/archive/2011/12/28/asp-net-security-update-shipping-thursday-dec-29th.aspx
Adding the setting key to the web-config file overcomes this error:
<appSettings>
<add key="aspnet:MaxHttpCollectionKeys" value="2000" />
</appSettings>
How do I disable a button in an ascx page? I know how to do it on an aspx page with:
btnSave.Attributes.Add("onclick",
"this.disabled=true;this.value='Please Wait...';needToConfirm=false;" +
ClientScript.GetPostBackEventReference(btnSave, "").ToString());
But the ClientScript function is not present in the ascx page.
You don't need the ClientScript in code behind, you can also have it directly in the button tag as OnClientClick attribute:
<asp:Button id="btnSave" runat="server" OnClientClick="this.disabled=true; this.value='Please Wait...'; needToConfirm=false;" Text="Save" />
You can access the ClientScript property using Page.ClientScript from your user control (ascx).
you can access ClientScript through the Page property of your control
Page.ClientScript.GetPostBackEventReference(btnSave, "")
Did you try: Page.ClientScript.GetPostBackEventReference?
Here's how I fixed the problem. In every page, I have three divs:
<div align="center" id="divWait" style="display:none"><asp:Label ID="lblSaveorCancel" runat="server"></asp:Label></div>
<div style="display:block" id="divMain">
---- page actual content here ------
</divMain>
<div id="divBut" style="text-align:center;display:block">
<asp:button id="SaveBtn" runat="server" CssClass="button" Text="Save" OnClientClick="return Validate('save');"/>
<asp:button id="CancelBtn" runat="server" CssClass="button" Text="Cancel" OnClientClick="return ShowWaitDiv('cancel');"/>
</div>
And then I added scripts:
function Validate(saveorcancel) {
----- validation checks for data on the page ------
}
function ShowWaitDiv(saveorcancel) {
var div = document.getElementById(divWait.id);
div.style.display = "block";
var div1 = document.getElementById(divMain.id);
div1.style.display = "none";
var div2 = document.getElementById(divBut.id);
div2.style.display = "none";
if (saveorcancel == 'save') {
document.getElementById('<%= lblSaveorCancel.ClientID %>').innerHTML = 'Saving data, please wait...';
}
else {
document.getElementById('<%= lblSaveorCancel.ClientID %>').innerHTML = 'Redirecting, please wait...';
}
return true;
}
Simple, quick, and the user sees the result of clicking a button immediately and cannot click any buttons again.
I have the code below to implement a dropdownlist with checkboxes. My problem is that every time i click a checkbox the dropdownlist closes and i need to reopen it to select more checkboxes. How do i make it so the dropdownlist dosn't close until i click off of it?
<asp:Panel ID="pnl_Items" runat="server" BorderColor="Aqua" BorderWidth="1">
<asp:CheckBoxList ID="cbl_Items" runat="server">
<asp:ListItem Text="Item 1" />
<asp:ListItem Text="Item 2" />
<asp:ListItem Text="Item 3" />
</asp:CheckBoxList>
</asp:Panel>
<br />
<asp:TextBox ID="tb_Items" runat="server"></asp:TextBox>
<ajax:DropDownExtender ID="TextBox1_DropDownExtender"
runat="server"
DynamicServicePath=""
Enabled="True"
DropDownControlID="pnl_Items" on
TargetControlID="tb_Items">
</ajax:DropDownExtender>
i prefer not altering AjaxControlToolkit. As follows:
$(document).ready(function() {
$('input[type=checkbox], label').click(function(e){
if (!e) var e = window.event;
e.cancelBubble = true;
if (e.stopPropagation)e.stopPropagation();
});
});
change jquery selector to your checkboxes!
I was able to get the desired behavior by adding the following javascript that I found on this post.
var DDE;
function pageLoad()
{
DDE = $find('<%= TextBox1_DropDownExtender.ClientID %>');
DDE._dropWrapperHoverBehavior_onhover();
$get('<%= pnl_Items.ClientID %>').style.width = $get('<%= tb_Items.ClientID %>').clientWidth;
if (DDE._dropDownControl) {
$common.removeHandlers(DDE._dropDownControl, DDE._dropDownControl$delegates);
}
DDE._dropDownControl$delegates = {
click: Function.createDelegate(DDE, ShowMe),
contextmenu: Function.createDelegate(DDE, DDE._dropDownControl_oncontextmenu)
}
$addHandlers(DDE._dropDownControl, DDE._dropDownControl$delegates);
}
function ShowMe() {
DDE._wasClicked = true;
}
You will need to get the Ajax control toolkit source code and modify the DropDownExtender to behave the way you want it to. Each control has its own folder with all the files related to it's ability to function within.
Recompile, drop the new dll into your project.
I am trying to use the following script in asp.net:
<script language="javascript" type="text/javascript">
function checktext() {
var txt = document.getElementById('tbComments');
if (txt.Text.Length > 0) {
alert('Thank you for submitting feedback.');
return true;
}
else {
alert('Sorry, you must enter text before submitting.')
return false;
}
}
</script>
<asp:Button ID="btnSave" runat="server" Text="Submit" onclick="btnSave_Click" OnClientClick="checktext();" />
I have tried using it on the onclick event.. the script will just not work at all.
Any Ideas?
you can use the ClientID property for getting the name of a Control on the client side. I suggest you to try jQuery for all these though
var txt = document.getElementById('<%=tbComments.ClientID%>');
besides, the OnClientClick has to receive a true or false value, in order to "know" whether to send the request to the server; so you have to change it with something like OnClientClick="return checktext();"
Try calling it like this:
<asp:Button
ID="btnSave"
runat="server"
Text="Submit"
onclick="btnSave_Click"
OnClientClick="return checktext();" />
Also this line looks suspicious in a web forms application:
document.getElementById('tbComments');
Make sure that the generated id of your control is not prefixed with something else.
Replace:
<asp:Button ID="btnSave" runat="server" Text="Submit" onclick="btnSave_Click" OnClientClick="checktext();" />
with:
<asp:Button ID="btnSave" runat="server" Text="Submit" onclick="btnSave_Click" OnClientClick="return checktext();" />
Replace:
var txt = document.getElementById('tbComments');
With:
var txt = document.getElementById('<%= tbComments.ClientId %>');
HTH.
everone else mentioned OnClientClick so I won't address that.
assuming tbComments is a textbox of some kind, this line
if (txt.Text.Length > 0) {
is going to fail because Text is not a property of html inputs or textareas, which is how asp.net textboxes are rendered. what you want is
if (txt.value.length > 0) {
also, is there some reason you're not using a regular asp.net RequiredFieldValidator control? you're doing more work than you need to. If you absolutely have to have alert boxes, you can use a CustomValidator control to call your function (you'll have to tweak it to fit the model).