Can't find ReportViewer event for rendering complete - asp.net

I'm trying to fire an event (to remove a custom progress/status indicator) when the ReportViewer control is finished rendering. I've explored the events for the ReportViewer control and I can't seem to find one that actually fires when the report is complete.
I'm using Visual Studio 2010 and ASP.NET 4.
Thanks for your help.

I know this is old, but I wasn't satisfied with the polling approach. You can register a property change listener for changes to isLoading instead (as described here).
In summary, add a bit of javascript to the script manager e.g. in your form element:
<asp:ScriptManager ID="scriptManager" runat="server">
<Scripts>
<asp:ScriptReference Path="~/Reports/ReportViewer.js" />
</Scripts>
</asp:ScriptManager>
<rsweb:ReportViewer ID="reportViewer" runat="server"/>
Then hook it up and add any client-side logic you need in ReportViewer.js:
Sys.Application.add_load(function () {
$find("reportViewer").add_propertyChanged(viewerPropertyChanged);
});
function viewerPropertyChanged(sender, e) {
if (e.get_propertyName() == "isLoading") {
if ($find("reportViewer").get_isLoading()) {
// Do something when loading starts
}
else {
// Do something when loading stops
}
}
};

One option would be to continuously poll the isLoading property of the client side ReportViewer api. If the isLoading property returns true continue showing the progress indicator, if it returns false hide it and stop polling.
I haven't tried it myself but according to the documentation is look like it should work.

I achieve this using JQuery like so:
$(document).ready(function () {
document.getElementById('ctl00_ctl00_DefaultContent_AdminContent_reportViewer').ClientController.CustomOnReportLoaded = function () {
alert('You see this after Report is Generated');
}
});

Try below code snippet:
<script type="text/javascript">
var app = Sys.Application;
app.add_init(ApplicationInit);
function ApplicationInit(sender) {
var prm = Sys.WebForms.PageRequestManager.getInstance();
$('#ReportViewer1_ctl05').css('width', '1047px');
if (!prm.get_isInAsyncPostBack()) {
prm.add_endRequest(EndRequest)
}
}
function EndRequest(sender, args) {
var reportViewerControlId = "ReportViewer1";
if (sender._postBackControlClientIDs[0].indexOf(reportViewerControlId) >= 0) {
// do your stuff
}
}
</script>
EndRequest function will be triggered once report rendering gets completed.

Related

UpdatePanel PageRequestManager. Delay postback

I am trying to add some JQuery animations before and after every postback request is made inside my UpdatePanel. What I have so far is something like this:
<script type="text/javascript">
$(document).ready(function () {
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);
Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(BeginRequestHandler);
function EndRequestHandler(sender, args) {
if (args.get_error() == undefined) {
// End Request (1)
}
}
function BeginRequestHandler(sender, args) {
// Start Request (2)
}
$('.MyButtons').live('click', function () {
// Before request (3)
});
});
</script>
<asp:UpdatePanel runat="server">
<ContentTemplate>
<asp:Button runat="server" CssClass="MyButtons"/>
</ContentTemplate>
</asp:UpdatePanel>
Let say I want to put some animation code at (3) that will be executed and then proceed with BeginRequestHandler function. How should I do that? Because right now the whole process executes 3,2,1 and I dn't know how to add that delay between steps 3 and 2. In other words I want to execute step 2 manually at step 3. Don't really want to use hidden buttons to do that.
Okay, I ended up using the following:
$('.MyButtons').live('click', function () {
var element = this;
$('#hideMe').hide('slow', function () {
__doPostBack(element.id.replace(/_/g, '$'), ''); // This will trigger a postback on a clicked server control
});
return false; // This will prevent asp.net click event on the server control
}

Button, changing CommandName and CommandArgs on the client side

Is there a way to change the values for these two attributes on the client side and have it reflected on the server side after the postback. I tried it but it does not seem to work. I wanted to have one button on the page that I would delegate submits too, and assign these two arguments on the client side. Seems like not possible. Any idea?
Assuming there is a button named "cmd" in the form
<script type="text/javascript" language="javascript">
$(document).ready(function () {
$("#<%=cmd.ClientID %>").click(function () {
$(this).attr("CommandName", "do").attr("CommandArgument", "arg2");
});
});
</script>
If one checks the value after postback they are still the same as they were before postback.
I tried you're code and it works fine.
Just make sure you're button is not generating a postback by adding OnClientClick="return false;":
<asp:Button ID="cmd" runat="server" Text="Button" OnClientClick="return false;"></asp:Button>
Also you won't see the difference in "view source" on your browser. But the change has been made in the DOM. Use firebug and add the console.log to see for yourself:
$("#<%=cmd.ClientID %>").click(function () {
$(this).attr("CommandName", "do").attr("CommandArgument", "arg2");
console.log(this);
});
The console.log(this) gave me the following:
EDIT:
If you think about it. If the button creates a postback, then the button will reset itself to normal once the page loads again.
EDIT #2:
I don't need the change on the client
side, I need it on the server side.
That was the whole point of the
question. I need to see the change on
the server side, and it does not seem
to be possible. – epitka
Okay... Well, in that case. It is not possible. "CommandArgument" and "CommandName" means nothing to the client and is not accessible.
However there are work arounds. But depending on the context of your application they might not be useful to you.
You could try using your own attributes like the answer suggested here.
Or you could execute the __doPostBack on the client side and pick up the __EVENTARGUMENT on the code behind.
(The link button is there to generate the __doPostBack function by asp.net.)
Like such:
<script type="text/javascript" language="javascript">
function DoPostBack() {
__doPostBack('cmd', 'thesearemyarguments');
}
</script>
Page:
<asp:Button ID="cmd" runat="server" Text="Button"
OnClientClick="DoPostBack(); return true;"
onclick="cmd_Click" ></asp:Button>
<asp:LinkButton ID="LinkButton1" runat="server" Visible="false">LinkButton</asp:LinkButton>
Code Behind:
protected void cmd_Click(object sender, EventArgs e)
{
Response.Write(Request.Params["__EVENTARGUMENT"]);
}
I was having the same problem here, I found the solution was to use an ajax call to send my buttons id to a function where i can set it as a session variable. Because the asp control I wanted to update could not be accessed from within a static call. On success of the ajax call I click a hidden button which uses a non static click event to manipulate the session variable i set and update the control
My links were generated within a repeater, and they correspond to different rooms of a house. When you click on the link there is another repeater that has to update to show products that are sold which are relevant to the room of the house that was clicked on
my link that is generated from the repeater
<%#Eval("DocumentName") %>
my client side method
$('.changeroom').each(function () {
$(this).on('click', function () {
var id = $(this).attr('data-id');
var object = { 'sender': id };
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "/App/Page Templates/FindByRoom.aspx/UpdateRoomID",
data: JSON.stringify(object),
success: function() {
$('#btnID').click();
}
});
});
});
btnID is a simple aspButton with a server side click event
and finally my server side methods
protected void btnChangeRoom_OnClick(object sender, CommandEventArgs e)
{
int id = 0;
if (Session["RoomID"] == null) return;
Int32.TryParse(Session["RoomID"].ToString(), out id);
if (id == 0) return;
//do something with your buttons id
//i updated the path of a repeater and reloaded the data
}
[System.Web.Services.WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public static void UpdateRoomID(string sender)
{
HttpContext.Current.Session["RoomID"] = sender;
}

How to call a client-side method from an asp.net method?

I have the following javascript:
<script type="text/javascript">
function showjQueryDialog() {
$("#dialog").dialog("open");
}
$(document).ready(function() {
$("#dialog").dialog({
autoOpen: false,
modal: true,
buttons: { "Renew Membership": function() { $(this).dialog("close"); } }
});
});
</script>
I have an asp:Button on the page which logs the user it. This is the sample of what I want to occur when the button is clicked on the server-side:
protected void LoginButton_OnClick(object sender, EventArgs e)
{
UserProfile profile = UserProfile.GetUserProfile(txtUserName.Text);
TimeSpan ts = profile.Expiration.Subtract(DateTime.Now);
if(ts.Days <= 30)
//call showJQueryDialog() to open the dialog box
Page.ClientScript.RegisterStartupScript(typeof(Login2), "showjquery",
"showJQueryDialog();", true);
else
//log the user in as normal.
}
Also is how would I attach a method such as the following to the Renew Button on the Dialog
public void Renew()
{
Response.Redirect("Renew.aspx");
}
As calling client side function is not possible I would suggest to emit in javascript the information required for the decision and make everything happen on the client side.
Alternatively you can do need a page reload, as suggested from previous commenter.
if(ts.Days <= 30)
ScriptManager.RegisterStartupScript(
typeof(MyPage), "showjquery",
"$(document).ready(function() { showJQueryDialog(); };",
true
)
else
//log the user in as normal.
Put that right where you have: //call showJQueryDialog() to open the dialog box
Update 1: You seem to be using an update panel, in that case you need to use ScriptManager.RegisterStartupScript
Update 2: You also want to wrap the js call in a jquery .ready call, so it isn't triggered before the dialog has been configured. This is better than hooking up the body onload because onload waits for images to be loaded so .ready will show sooner (depending on the images and other bits of info loaded).
I really don't understand Freddy's approach to this at all. I am misunderstanding something maybe. The way I see it, there are only two possibilities here, as devdimi point out. Either:
a) Do all the logic in the client-side onClick javascript. You could call an AJAX method that performs the action in the server-side OnClick, then call your jQuery popup in the AJAX callback.
b) Do a postback, handle the server-side OnClick, then attach javascript for the page that runs in the body onLoad event:
body.Attributes.Add("onLoad", "showJQueryDialog();")
I would keep a hidden LinkButton and then call the __doPostBack method in javascript.
<asp:LinkButton runat="server" ID="Renew" OnClick="Renew_Click" style="display:none" />
jQuery
$(document).ready(function() {
$("#dialog").dialog({
autoOpen: false,
modal: true,
buttons: { "Renew Membership": function() {
$(this).dialog("close");
__doPostBack('Renew', '');
// or if inside a master page something like this
__doPostBack('ctl00$ContentPlaceHolder1$Renew', '');
} }
});
});
I have a somewhat similar issue with IE8.
We're using ASP.NET and anytime we do a Response.Redirect within the PageLoad/Control-Events IE8 sets all the base DOM objects to undefined (Image, window, document)
But if we do the redirect during the PreInit event then IE8 is fine.. Lovely

Check what control initiated AJAX Request

asp.net 2.0 / jQuery / AJAX
<script type="text/javascript">
//updated to show proper method signature
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_endRequest(hideMessage);
function hideMessage(sender, args)
{
var ctl = args.get_postBackElement();
//check if ctl is the disired control
//hide user notification message
}
</script>
i have several controls on the page that might initiate the AJAX request, but i only want my js to fire when i click one particular button. how do i check what control initiated the request so i can fire JS accordingly.
EDIT: I worked around it, but I'd still like to know if I can do it this way.
Clarification: I can't call the JS from onclick event, because the page is inside of the UpdatePanel, and i only want the JS to execute when AJAX Request ends and it was triggered by one particular button on the page. On server side, i set the myLabel.Text to some text, and then js checks if the $(myLabel.CliendID)'s innerHTML is not blank and fires the js. checking the innerHTML is my work-around since i can't figure out how to check the "sender" of AJAX Request. Hope this makes more sense now.
edit2: I've read some documentation, and turns out you CAN check the "sender" control.
Thank you.
This is what I am doing in my code to identify what control has initialized the request. All javascript code.
function pageLoad() {
if (!Sys.WebForms.PageRequestManager.getInstance().get_isInAsyncPostBack()) {
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(endRequestHandler);
Sys.WebForms.PageRequestManager.getInstance().add_initializeRequest(initializeRequest);
}
}
function endRequestHandler(sender, args) {
if (sender._postBackSettings.sourceElement.id == '<%= gvResults.ClientID %>') {
//do something because of this...
}
}
function initializeRequest(sender, args) {
if (CheckForSessionTimeout()) {
args.set_cancel(true);
}
else {
if (sender._postBackSettings.sourceElement.id == '<%= gvResults.ClientID %>') {
//do something because of this
}
}
}
EDITHere is the method of checking for timeout on the client side.
var sessionTimeoutDateTime = new Date();
var sessionTimeoutInterval = <%= this.SesstionTimeoutMinutes %>;
function CheckForSessionTimeout() {
var currentDateTime = new Date()
var iMiliSeconds = (currentDateTime - sessionTimeoutDateTime);
if (iMiliSeconds >= sessionTimeoutInterval) {
ShowSessionTimeout();
return true;
}
return false;
}
I would recommend that you do not have each control execute the same javascript function. OR, if they do, pass a parameter that indicates which one executed it.
Then, you can include your ajax in the js function that the control executes.
And, if I'm not understanding the issue correctly, perhaps you could explain it in more detail or post some code.
I've read some documentation, and turns out you CAN check the "sender" control. JS in the question is updated to show the proper method signature.
This article gives even better explanation.

JQuery ajaxStart event not being captured in ASP.net AJAX

I have an asp.net page with a save button within an updatepanel and contenttemplate. The save works nicely, but I am trying to add a "wait" gif while the save is happening using JQuery, but the ajaxStart event is not firing. I put a simple catch shown below:
$(document).ajaxStart(function () {
alert('starting');
}).ajaxStop(function () {
alert('done');
});
No alerts show when I click the save. Is there a problem when trying to capture ASP.net Ajax events, is asp doing some funky type of Ajax calls that can't be captured by Jquery?
Thanks, let me know if you have any ideas about this,
Mark.
The ASP.NET update panels seem to do their own thing... Tap into the PageReuqestManager and setup your own calls here...
EDIT
I simplified the functions a bit below to match your sample a little more...
<script type="text/javascript">
function pageLoad() {
if (!Sys.WebForms.PageRequestManager.getInstance().get_isInAsyncPostBack()) {
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(AjaxEnd);
Sys.WebForms.PageRequestManager.getInstance().add_initializeRequest(AjaxBegin);
}
}
function AjaxEnd(sender, args) {
alert("I am done...");
}
function AjaxBegin(sender, args) {
alert("I am about to start...");
}
</script>

Resources