I am wondering how to add a Javascript event handler using asp.net ajax.
I need to add event handlers after ajax update because jQuery plugin to sort tables doesn't work and the onload method to display a screen keyboard does not trigger as well.
Is there a way to do that?
Maybe I need to switch to some other ajax library or/and try Asp.Net MVC to accomplish?
Your question is a little unclear. Anyway, if you are after to add an event handler to an element after partial update, check the following sample.
<asp:ScriptManager ID="ScriptManager1" runat="server" />
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Button ID="Button1" runat="server" Text="Button" />
</ContentTemplate>
</asp:UpdatePanel>
<script type="text/javascript">
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_endRequest(function() {
if (prm.get_isInAsyncPostBack) {
$addHandler($get("Button1"), "click", function() {
alert("This is a test...");
});
}
});
</script>
Related
I'm fairly new to jQuery and I was trying to achieve some of this functionality in client-side rather than my usual server side code. I just figured that I would add some click events, to get some practice, etc...but I'm seeing this issue and not sure where to start troubleshooting as it is working on my stand alone html page.
This is a web app page which inherits from a Masterpage (Site.Master). I was modifying the .js file a bit as I have been running around a bit by placing the Alert() just to see something...but that wasn't firing.
Why are my events not firing?
HTML:
<%# Page Title="" Language="vb" AutoEventWireup="false" MasterPageFile="~/Site.Master"
CodeBehind="ProductMaintenance.aspx.vb" Inherits="CStock.ProductMaintenance" %>
<asp:Content ID="Content1" ContentPlaceHolderID="HeadContent" runat="server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="true">
</asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel2" runat="server" >
<ContentTemplate>
<asp:Panel ID="Panel1" runat="server" GroupingText="" cssClass="pnl1">
</asp:Panel>
<div class="mainGroup">
<div class="headerGroup">
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
<select name="type" id="type">
<option value="Categories">Categories </option>
<option value="Products">Products </option>
</select>
</div>
</div>
<div>
<asp:Button ID="submitform" runat="server" Text="Button" />
<asp:Button ID="HideButton" runat="server" Text="HideButton" />
<hr />
</div>
</ContentTemplate>
</asp:UpdatePanel>
<div class="sqlData">
...
...
...
</div>
<script type="text/javascript" src="scripts/jquery.js"></script>
<script type="text/javascript" src="scripts/site.js"></script>
Javascript (site.js)
$('#submitform').on('click', function (event) {
Alert("TESTING");
$( ".HideButton" ).hide();
$( "#HideButton" ).hide();
})
$('input[name=submitform]')
.click(
function ()
{
$(this).hide();
$( ".HideButton" ).hide();
$("#HideButton").hide();
Alert("TESTING");
}
);
Updated Javascript:
$('#submitform').on('click', function (event) {
Alert("TESTING");
// $( ".HideButton" ).hide();
// $( "#HideButton" ).hide();
})
$('input[id*=submitform]')
.click(
function ()
{
Alert("TESTING2");
}
);
$('input[name=submitform]')
.click(
function () {
Alert("TESTING2");
}
);
Separately, which method to add the events is best practice?
Your events aren't firing because .NET translates your IDs when they're server controls (has the runat="server" attribute). For instance, you gave the button the ID "submitform", but when it's generated on the page it's probably something like "ctl00_container_submitform". Take a look at the generated page source and you'll see what I mean. You can still accomplish what you want with jquery. Just change your selector to $("[id*=submitform]") which will look for any control with the attribute "id" that ends with "submitform".
EDIT:
Since your button is in an update panel, you'll want to update to the following:
$(document).on('click', '[id*=submitform]', function () {});
Check out the documentation for "on" here http://api.jquery.com/on/
When the content in the update panel is replaced, the binding for that button is being lost. if you bind to the document (which is static), the binding will always be in effect. The optional selector parameter indicates that the function should be fired if the document is clicked, and if the element in the document matches the selector.
add the attribute ClientIDMode="static to the buttons
<asp:Button ID="submitform" runat="server" Text="Button" ClientIDMode="Static"/>
<asp:Button ID="HideButton" runat="server" Text="HideButton" ClientIDMode="Static" />
then you can reference them by just $("#submitForm") and $("#HideButton")
in order to guarantee unique IDs webforms adds things to the id field when it is added. Changing ClientIDMode to static tells it that you will make sure that it will always be unique and it will give you the proper ID
im stuck with Javascript in Asp.net...
I made a TextBox named tbValidFrom and another named tbValidTo.
I also made two ModalPopups.
Then i try to open the ModalPopupExtenders when the TextBoxes get focus:
<script type="text/javascript">
$('#tbValidTo').focus(function () {
$find('ModalPopupExtenderNV1').show();
})
$('#tbValidFrom').focus(function () {
$find('ModalPopupExtenderNV2').show();
})
</script>
but it doesnt finds tbValidTo or ModalPopUpExtender ?
Runtime-Error in Microsoft JScript: Object expected
Here is one of the two ModalPopupExtenders and TextBoxes:
<asp:TextBox ID="tbValidFrom" runat="server"></asp:TextBox>
<asp:UpdatePanel ID="UpdatePanelNV2" runat="server" RenderMode="Inline" UpdateMode="Conditional">
<ContentTemplate>
<cc1:ModalPopupExtender ID="ModalPopupExtenderNV2" runat="server" TargetControlID="HiddenField6"
PopupControlID="PanelNewVersion" BackgroundCssClass="modalBackground" BehaviorID="ModalPopupExtenderNV2"
Enabled="True" />
<asp:HiddenField ID="HiddenField6" runat="server" />
</ContentTemplate
</asp:UpdatePanel>
The same as above is with the other ModalPopupExtender and TextBox...
Help would be really nice.
Thanks
Edit: Yes i use a masterpage!
Fails where it is marked yellow.
your jQuery syntax is wrong.
change your script to:
<script type="text/javascript">
$('#tbValidTo').focus(function () {
$(this).find('#<%=ModalPopupExtenderNV1.ClientID%>').show();
});
$('#tbValidFrom').focus(function () {
$(this).find('#<%=ModalPopupExtenderNV2.ClientID%>').show();
})
</script>
elements that has runat="server" will eventually end with a different ID than you entered in the aspx file.
i used the <%= %> to get the 'final' id.
hope that helps
Seeing that markup there is two chances for the issues.
With the ModalPopupExtender.
Where you have given the panel "PanelNewVersion" . Seems like its missing in the markup.
In the Javascript code. If you want to hide that Popup, give the name of the panel. NOt the name of the ModalPopupextender.
Also you have given an update panel there in page, so you can easily handle the modalpopup in any srever side event of your textbox.
Otherwise, if you want to use the Modal popup ijn client side, use jQuery Modalpopup. That will the better option.
ASP.NET Can modify the ID's of elements, if you use a Masterpage the element id's will be modified to something like the following : ctl001_ContentPlaceHolder1_tbValidFrom
To get around this ASP.NET modification of your elements you can use ASP.NET Inline Expressions to get the rendered ID from the object.
See the answer to the following question for more information on ASP.NET Inline Expressions
You can look at changing the Client ID Mode (The way ASP.NET Modifies IDs when the page is rendered) here :
ASP.NET Client ID Modes
EDIT :
The AjaxControlToolkit's ModalPopupExtender is not rendered on the page as a html element, therefore you cannot find this item using the ClientID of the ModalPopupExtender.
You must use the BehaviourID to call the show function on.
The below code should work correctly :
$('#<%= tbValidTo.ClientID %>').focus(function () {
$find('ModalPopupExtenderNV1').show();
})
$('#<%= tbValidFrom.ClientID %>').focus(function () {
$find('ModalPopupExtenderNV2').show();
});
This will find the textbox object using the ASP.NET Inline expressions to find the client ID and will then find the behaviour ID and execute the Show method.
Example Markup :
<script type="text/javascript">
$(document).ready(function() {
$('#<%= tbValidFrom.ClientID %>').focus(function () {
$find('ModalPopupExtenderNV2').show();
});
});
</script>
<asp:TextBox ID="tbValidFrom" runat="server"></asp:TextBox>
<asp:UpdatePanel ID="UpdatePanelNV2" runat="server" RenderMode="Inline" UpdateMode="Conditional">
<ContentTemplate>
<cc1:modalpopupextender id="ModalPopupExtenderNV2" runat="server" targetcontrolid="HiddenField6"
popupcontrolid="PanelNewVersion" backgroundcssclass="modalBackground" behaviorid="ModalPopupExtenderNV2"
enabled="True" />
<asp:HiddenField ID="HiddenField6" runat="server" />
</ContentTemplate>
</asp:UpdatePanel>
<asp:Panel ID="PanelNewVersion" runat="server">
testing panel
</asp:Panel>
I've been working on this for quite a while and haven't found anything to solve my problem. When I select a node I want the value of that node to populate a textbox. I can get this to work using vb codebehind but it causes a postback and I don't want it to. I want to try to use javascript to do this instead but I'm not sure where call the function or how to set it up.
Here's the code for my treeview and the textbox I want to send it to:
<asp:TextBox ID="tbSelectedOrg" runat="server" Enabled="false" asp:TextBox>
<asp:TreeView
ID="tvOrganizationTree"
ExpandDepth="0"
runat="server"
PopulateNodesFromClient = "true"
ShowLines="true"
ShowExpandCollapse="true"
OnSelectedNodeChanged="tvOrganizationTree_SelectedNodeChanged"> // currently calls vb code causing postback
</asp:TreeView>
I created this example really quick. Give it a try.
<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
<script src="Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>
<script language="javascript" type="text/javascript">
$(document).ready(function () {
$("#<%= TreeView1.ClientID %> div a").click(function () {
$("#txt").val(this.innerHTML);
return false;
});
});
</script>
</asp:Content>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
<asp:TreeView ID="TreeView1" runat="server">
</asp:TreeView>
<input type="text" id="txt" />
</asp:Content>
Good luck!
I would use JQuery to solve such a problem.
This code is not perfect but should give you an idea of where to look:
$("#tvOrganizationTree .what-ever-class-aspnet-gives-the-nodes")
.click(function()
{
$("#id-of-textbox").html(this.html());
});
I have a asp.net panel that is initially hidden and is shown when a button is clicked. There is javascript inside that panel and it doesn't execute after the panel is set to be visible. I can see that javascript function gets outputted on page but it is not called. What can I do to make it so that function gets called? Here is an example:
<asp:LinkButton id="lbtn" runat="server" Text="show" OnClick="lbtn_Click" />
<asp:UpdatePanel id="upnl" runat="server" UpdateMode="Conditional">
<contenttemplate>
<asp:panel id="pnlContent" runat="server" visible="false">
content initially hidden.
<script>
alert('done!');
</script>
</asp:panel>
</contenttemplate>
<triggers>
<asp:AsyncPostBackTrigger ControlID="lbtn"/>
</triggers>
</asp:UpdatePanel>
You'll probably want to have some sort of end request method that gets called whenever an ajax method is called. this would have to be under the script resource.
<script type="text/javascript">
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_endRequest(function(sender, args){ alert("endRequest"); });
</script>
Rather than doing that, why not use Page.ClientScript.RegisterStartupScript()l to trigger it to run.
Old hand at ASP.NET, new to the UpdatePanel. I have a reporting page which executes a fairly length SQL query... takes about 10 seconds right now. What I would like to do is have my page fully render, with some placeholder text (Loading...) and then have the UpdatePanel kick off the actual time-consuming reporting process and render the report when it's done.
So... my theory is to use RegisterStartupScript() to kick this off and drop the string from GetPostBackEventReference() to trigger the UpdatePanel update. Some problems crop up:
1) Can I actually use GetPostBackEventReference w/ the UpdatePanel or do I need to trigger it some other way? Use this method on a button inside the Update Panel?
2) What event gets triggered when the postback reference is the UpdatePanel? It's not clear to me. I've got to call my databinding code somewhere! Again, maybe I need to use a button inside?
I had to do something very similar recently, here's how i did it (right or wrong):
The trick is a "Hidden Async Postback Trigger".
<asp:UpdatePanel ID="upFacebookImage" runat="server">
<ContentTemplate>
<!-- Your updatepanel content -->
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="hiddenAsyncTrigger" EventName="Click" />
</Triggers>
</asp:UpdatePanel>
<asp:Button ID="hiddenAsyncTrigger" runat="server" Text="AsyncUpdate" style="display:none;" />
Then from JavaScript, whenever you want to trigger the async postback, you do this:
__doPostBack('<%= hiddenAsyncTrigger.ClientID %>', 'OnClick');
In my example, i needed to trigger an async postback from a particular JS event. But you could attach it to doc ready.
I seem to remember trying #Marko Ivanovski's way, but for some reason it didn't work. I think you need to specify a "postback-able" control (ie a button) to trigger the postback.
HTH.
Updating this with my solution, I pieced together mostly from the first answer above.
I need my page to load, then then start loading content for my update panel. The panel calls some webservices and we don't want the whole page to crash in the event that the remote server doesn't respond. We don't want the wait either.
My HTML:
<asp:UpdatePanel ID="udpCheckout" runat="server" UpdateMode="Always">
<ContentTemplate>
<asp:Image ID="imgSpinner" runat="server" Visible="true" ImageUrl="~/images/ajax-loader.gif" />
<br />
<asp:Label ID="lblWait" runat="server" Visible="true" Text="Please wait..."></asp:Label>
<asp:Button ID="hiddenAsyncTrigger" runat="server" Text="AsyncUpdate" style="display:none;" />
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="hiddenAsyncTrigger" EventName="Click" />
</Triggers>
</asp:UpdatePanel>
My Code behind snippets:
In page_load:
ScriptManager.RegisterStartupScript(Me.Page, Me.Page.GetType, "LoadUpdate", GetPostBackEventReference(hiddenAsyncTrigger, String.Empty), True)
And the button handler:
Sub LoadUpdatePanels(ByVal o As Object, ByVal e As EventArgs) Handles hiddenAsyncTrigger.Click
System.Threading.Thread.Sleep(5000) 'wait 5 seconds so I can see the page change
imgSpinner.Visible = False
lblWait.Text = "Content is now loaded."
'udpCheckout.Update()
End Sub
This was my test to see if I could get it working. Now to replace all of this with the real code!
Try something like this (not tested).
Set the UpdateMode of the UpdatePanel to Conditional.
Add this to your <head> section:
<script type="text/javascript">
window.onload = __doPostBack('UpdatePanel1', ''); // Replace UpdatePanel1 with the ID of your UpdatePanel
</script>
Simplifying RPM1984's very helpful earlier answer (thanks ;)) and showing some tweaks & a little more of the surrounding detail that I found necessary:
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:UpdatePanel ID="upFacebookImage" runat="server">
<ContentTemplate>
<asp:PlaceHolder runat="server" ID="PlaceHolderMediaPrompts" />
<asp:Button ID="hiddenAsyncTrigger" runat="server" Text="AsyncUpdate" OnClick="WasPage_Load" style="display:none;" />
</ContentTemplate>
</asp:UpdatePanel>
Note:
The hidden button's vital OnClick= parameter, this is what specifies the server function to call!
No trigger clause or triggers in the Update-panel, I am using the child controls which are automatically triggers - specifically the button Click event.
And to trigger it from client-side Javascript you can use:
document.getElementById("hiddenAsyncTrigger").click();
However, I found it necessary to prevent this being called on subsequent page loads (as it caused unnecessary page load looping & consequent flicker). See the neat little IsPostBack() check below :)
e.g. To invoke this after page load (as per the original question), I just added a call to invoke the above line of code as the onload-parameter to the main Body-tag thus:
<body onload="DoPostLoad();">
...
<script type="text/javascript">
function DoPostLoad()
{
if ( IsPostBack() != true ) // ***This is NEW and ESSENTIAL! ***
document.getElementById("hiddenAsyncTrigger").click();
}
function IsPostBack() { // Ref. https://stackoverflow.com/questions/26978112/execute-javascript-only-on-page-load-not-postback-sharepoint
var ret = '<%= Page.IsPostBack%>' == 'True';
return ret;
}
. . .
</script>
</body>