Animation Extender Problems - c#

I have just started working with the AnimationExtender. I am using it to show a new div with a list gathered from a database when a button is pressed. The problem is the button needs to do a postback to get this list as I don't want to make the call to the database unless it's needed. The postback however stops the animation mid flow and resets it. The button is within an update panel.
Ideally I would want the animation to start once the postback is complete and the list has been gathered. I have looked into using the ScriptManager to detect when the postback is complete and have made some progress. I have added two javascript methods to the page.
function linkPostback() {
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_endRequest(playAnimation)
}
function playAnimation() {
var onclkBehavior = $find("ctl00_btnOpenList").get_OnClickBehavior().get_animation();
onclkBehavior.play();
}
And I’ve changed the btnOpenList.OnClientClick=”linkPostback();”
This almost solves the problem. I’m still get some animation stutter. The animation starts to play before the postback and then plays properly after postback. Using the onclkBehavior.pause() has no effect. I can get around this by setting the AnimationExtender.Enabled = false and setting it to true in the buttons postback event. This however works only once as now the AnimationExtender is enabled again. I have also tried disabling the AnimationExtender via javascript but this has no effect.
Is there a way of playing the animations only via javascript calls? I need to decouple the automatic link to the
buttons click event so I can control when the animation is fired.
Hope that makes sense.
Thanks
DG

The flow you are seeing is something like this:
Click on button
AnimationExtender catches action and call clickOn callback
linkPostback starts asynchronous request for page and then returns flow to AnimationExtender
Animation begins
pageRequest returns and calls playAnimation, which starts the animation again
I think there are at least two ways around this issue. It seems you have almost all the javascript you need, you just need to work around AnimationExtender starting the animation on a click.
Option 1: Hide the AnimationExtender button and add a new button of your own that plays the animation. This should be as simple as setting the AE button's style to "display: none;" and having your own button call linkPostback().
Option 2: Re-disable the Animation Extender once the animation has finished with. This should work, as long as the playAnimation call is blocking, which it probably is:
function linkPostback() {
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_endRequest(playAnimation)
}
function playAnimation() {
AnimationExtender.Enabled = true;
var onclkBehavior = $find("ctl00_btnOpenList").get_OnClickBehavior().get_animation();
onclkBehavior.play();
AnimationExtender.Enabled = false;
}
As an aside, it seems your general approach may face issues if there is a delay in receiving the pageRequest. It may be a bit weird to click a button and several seconds later have the animation happen. It may be better to either pre-load the data, or to pre-fill the div with some "Loading..." thing, make it about the right size, and then populate the actual contents when it arrives.

With help from the answer given the final solution was as follows:
Add another button and hide it.
<input id="btnHdn" runat="server" type="button" value="button" style="display:none;" />
Point the AnimationExtender to the hidden button so the firing of the unwanted click event never happens.
<cc1:AnimationExtender ID="aniExt" runat="server" TargetControlID="btnHdn">
Wire the javascript to the button you want to trigger the animation after the postback is complete.
<asp:ImageButton ID="btnShowList" runat="server" OnClick="btnShowList_Click" OnClientClick="linkPostback();" />
Add the required Javascript to the page.
function linkPostback() {
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_endRequest(playOpenAnimation)
}
function playOpenAnimation() {
var onclkBehavior = ind("ctl00_aniExt").get_OnClickBehavior().get_animation();
onclkBehavior.play();
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.remove_endRequest(playOpenAnimation)
}

Related

ASP.NET WebForms Confirm

I'm new to web programming with .NET.
I am developing a web page with webforms, and I want at a certain moment to programmatically show a modal window, for the user to accept or cancel, according to a question. Exactly what does the "confirm" function of JavaScript.
I tried to get it calling a JavaScript function:
Page.ClientScript.RegisterStartupScript (this.GetType (), "CallMyFunction", "MyFunction()", true);
But I need to do it without reloading the page, and I also need to control if the user has accepted or canceled and I do not know how to do it.
I've also tried getting it using the ModExPopupExtender control from DevExpress.
Can someone tell me a simple way to get what I want?
I can not understand how something so usual in web programming, and that PHP + javascript would not pose any problem can be so complicated.
All start in a one-button event on the code behind:
protected void btn1_Click(object sender, EventArgs e)
{
//I make a series of checks
//If certain conditions I want to show the confirm
//According to the user has chosen ok or cancel will perform a certain action
}
Onclientclick does not help me because before launching the "confirm" I have to do some checks on the server side.
Thank you very much.
You can use OnClientClick which is a property on most web controls.
I like to just bring up a simple confirm() dialog which executes the server code if the user clicks OK and does nothing if the user cancels the action:
<asp:Button runat="server" ID="btnSave" Click="btnSave_Click" Text="Save"
OnClientClick="return confirm('Are you sure you want to do this thing?');" />
You can do other things with it as well, but the key thing to remember is that anything you do in OnClientClick will happen before the page gets posted back to the server.
This is also perfectly valid:
<asp:Button runat="server" ID="btnSave"
OnClientClick="showModalConfirm('some message goes here');" ... />
<script>
function showModalConfirm(msg)
{
$(".modal .message").innerHtml(msg);
$(".modal").Show();
}
</script>
You can set the action that OnClientClick should perform in your codebehind in exactly the same way:
protected void Page_Load(object sender, EventArgs e)
{
btnSave.OnClientClick = "return confirm('Are you sure you want to do this thing?');";
}
You can use below code in c# to call javascript function. Below code will execute afterpostback() javascript function:
ClientScript.RegisterStartupScript(GetType(), Javascript, "javascript:afterpostback();", true);
And you can write code in javascript function to display any div or popup:
<script language="javascript" type="text/javascript">
function afterpostback() {
//Here you can write javascript to display div/modal
}
</script>
One way I've handled this previously was to have 2 buttons on the page. The first would be initially visible and labeled "Submit". The second would be initially hidden and labeled "Confirm". The "Submit" button would postback upon click and perform your server side checks/validation. If those checks failed, an appropriate error message would be displayed. If those checks passed, an appropriate "Please confirm your submission"-type message would be displayed, the "Submit" button would become hidden, and the second "Confirm" button would become visible. When that Confirm button was clicked, it would postback again and fully submit.
EDIT: I forgot to mention, there's a bit more to this that occurred to me after I initially posted. You'll have to protect the fields from being edited in the event the server-side verification is successful as you obviously don't want the user changing values and then clicking the Confirm button. That means disabling all the input controls - which could be a pain if you have a lot. You also have to give them a way to (intentionally) Edit in case the server side verification passes, you display the Confirmation, and they change their minds - so basically you'd need a third "Cancel/Edit"-type button that would put the form back in edit mode and show your initial Submit button.

Run Javascript when Asp.net page is loading

I wonder if there is way to run JS code whenever a asp.net page is contacting the server.
I.e. I'm looking for a general event handler that is triggered whenever a call to the server is made for runat="server" components.
I know there's a way to get jQuery.ajax() to run JS code before and after a call to the server is made, but I'm not sure how to do it in asp.net. Especially, since this projects uses a lot of custom components.
The goal here is to show some kind of loading image when a button is clicked, to prevent the user to click a button twice and also to show the user that the system is working.
If the click causes the page or an updatepanel to refresh, I'd only like to display the loading image before the refresh, eg. User clicks, "loading" is shown, page/update panel is refreshed (causing the "loading" to disappear), the new page/content is displayed as normal.
Update 1:
I can't use UpdateProgress because some of the buttons aren't inside UpdatePanels. What I really want to do is to fire a JS as soon as any button/control that will contact the server is clicked. I.e. if the user clicks a dropdown which doesn't contact the server, nothing should happend. But if that dropdown has any connection to the server, a JS should be run.
I understand that this is ASP.NET Ajax and not jQuery Ajax, I only used jQuery as an example. Because I've used a jQuery method before (with jQuery Ajax) to trigger JS before the server call was made. Eg. to lock the element that was clicked or to display a "Loading..." screen.
I could of course add a bit of a JS hack to every page which adds a "onclick" event to every button manually, but I thought it would be better if there was a general solution for this (since I've got lots of pages, each with a few buttons that contact the server on them).
Update 2:
When I think about it, it doesn't necessarily need to be a JS that is triggered. It would be good enough if the page somehow only made sure that the same button wasn't clicked twice. Either by disabeling the button or by adding something in front of it (like a "Loading..." screen).
You can use an UpdateProgress for this to use with update panels, but if you are doing a full page postback (i.e. not ajax) the only loading animation you can have is the browsers own.
UpdateProgress:
<asp:UpdateProgress ID="UpdateProgress1" runat="server">
<ProgressTemplate>
Shiny loading aninmation
</ProgressTemplate>
</asp:UpdateProgress?
Here is how you can do it using jquery:
$(function() {
$('a[href]').on('click', function(e) {
var self = this;
e.preventDefault();
loadAsync($(self).attr('href'));
});
});
function loadAsync(url) {
$('div#result').fadeOut(200, function() {
$('div#loader').fadeIn(200, function() {
$.get(url, function(data) {
$('div#result').html($(data));
}).done(function() {
console.log('done');
}).fail(function() {
$('div#result').html('Error');
}).always(function() {
$('div#loader').fadeOut(200, function() {
$('div#result').fadeIn(200);
});
});
});
});
}

Show a loading animation while function completes

I have a function inside my .aspx.cs code which takes wuite a long time to do the processing until when I want to display a cool loading animation. I looked some of the earlier posts but either these didn't work for me, or were having solution specific to Page loading scenario (not loading a while a function completes).
I guess the right approach would be to fire a Javascript startLoader() function just before the the main function starts (which takes a long time), and then call a stopLoader() from the .aspx.cs itself to stop the loader when the function ends. Any suggestions how to implement this?
Yes, I've done this in ASP.NET Web From (not a ASP.NET MVC solution). You need to provide OnSubmit client side event handler. It basically break down to three parts: Javascript, HTML Div, and one line code behind:
Javscript:
function ShowLoading(e) {
// var divBg = document.createElement('div');
var divBg = document.getElementById('blockScreen');
var divLoad = document.createElement('div');
var img = document.createElement('img');
img.src = 'images/ajax-loader.gif';
divLoad.setAttribute("class", "blockScreenLoader");
divLoad.appendChild(img);
divBg.appendChild(divLoad);
document.getElementById('blockScreen').style.display = 'block';
// These 2 lines cancel form submission, so only use if needed.
//window.event.cancelBubble= true;
//e.stopPropagation();
}
function HideLoading() {
//alert('hideloading');
document.getElementById("form1").onsubmit = null;
document.getElementById('blockScreen').style.display = 'none';
//alert('done');
}
Add following DIV
<div id="blockScreen" class="blockScreen" style="display:none"> </div>
Finally, add the following to Page_Load in code behind.
Page.ClientScript.RegisterOnSubmitStatement(this.GetType(), "submit", "ShowLoading()");
Now, all of your page postbacks are essentially have to call onsubmit event. It will display the animation before the page postback finishes.
if you really want to do, then the only way is webworkers. You've probably heard about them, or if not, i seriously recommend to have a look.
Yes, fire startLoader() on OnCliencClick of your button or whatever element you are using to fire the server-side event and call stopLoader() from the server-side at the end of your process. Something like this:
//rest of the server-side code above ...
Page.ClientScript.RegisterStartupScript(this.GetType(), "someKey", "stopLoader();", true);
If you don't mind that the browser is not responsive in the meantime, the simplest way of doing this is using an animated gif:
Activity indicators
ajaxload.info
webscriptlab
The trick is showing the image when starting your processing, and hiding it when finished. You can show it in an img, and use jQuery or whatever you want to show/hide it.
If you need the browser to keep responsive, use Web Workers. But be aware that some of the older browsers don't support it. See this reference

C# Selenium RC - How to test a jQuery button click?

What is the correct way to run a jQuery .click() in a selenium test? The element being clicked is a hyperlink.
HTML:
<div id="buttons">
<a class="button" id="btnRun" href="javascript:void(0)">Run</a>
</div>
<div id="output" />
jQuery
$(document).ready(function () {
$('#btnRun').click(function () {
$("#output").html("hello world");
});
})
Selenium:
[Test]
public void TestOutput()
{
selenium_local = new DefaultSelenium("localhost", 4444,
"*firefox", "https://localhost");
selenium_local.Start();
selenium_local.Open("/TestPage");
selenium_local.WaitForPageToLoad("30000");
Assert.That(selenium_local.IsElementPresent("id=btnRun"), Is.True);
selenium_local.Click("id=btnRun");
Thread.Sleep(5000);
// also tried without success:
// selenium_local.FireEvent("id=btnRun","click");
// selenium_local.Click("xpath=//a[#id='btnRun']");
// selenium_local.Click("dom=document.getElementById('btnRun')");
Assert.That(selenium.GetValue("id=output"), Is.EqualTo("hello world"));
}
When I run the test the button click does not occur, and after the 2nd WaitForPageToLoad, the test finishes and reports failure (because the text hello world was not found, because the button click never occurred)
(Note: I use selenium with java, so there might be a difference, but I strongly doubt it)
I have similar problems sometimes, but we're using plain-ol'-javascript in some places, gwt in others, and mootools in some other places (don't ask why so many) for our different ajax calls so it's possible our problems are completely unrelated. But, maybe I can help regardless.
I have to sometimes use mouseOver then click. Sometimes I even have to do mouseDown and then mouseUp. Or a combination of the two. And even in some cases we have to retry the click.
(Also, unless clicking the link/button causes a full page load, the WaitForPageToLoad is going to cause issues because it waits for a page loaded event. Here's how I ended up waiting for Ajax calls to finish, however you should be able to come up with a cleaner solution if you're only using JQuery)
Some JavaScript libraries respond to the mouse-up event as indicating a "click". If so, MouseDown() followed by MouseUp() ought to do the job.

Disable an asp.net dynamic button click event during postback and enable it afterwards

I am creating a button dynamically in my code and attaching a click event to it. However I have to prevent people to click it while there is a process going on. So when it is clicked once, it should be disabled and when the process ends it should be enabled. How can I do that?
Thanks.
onclick="this.enabled=false" add this from your code behind to your control
btnAdd.Attributes.Add("onclick", "this.enabled=false;");
This link explains in detail http://encosia.com/2007/04/17/disable-a-button-control-during-postback/
If you are processing via ajax when the button is clicked-
1. Disable the button when processing starts
2. Enable the button after processing completes
If the button postbacks, the best way is to disable the button when it is clicked via javascript [I won't suggest jquery just for this particular task]. Since after postback the button will be enabled as it was earlier, you don't need to worry about enabling.
<asp:Button ID="btn" runat="server" OnClientClick="disable(this)"
Text="Click me!" OnClick="btn_Click" />
<script type="text/javascript">
function disable(control)
{
control.disabled="disabled";
//added alert to give the snapshot of what happens
//when the button is clicked
alert(100);
}
</script>
Hope this helps.
I would use an UpdatePanel arround the button. On click you can serverside disable the button. Use a trigger on the updatepanel that looks every x seconds if your extern process has returned a result. And I would advise you to source out long running processes into a windows service.

Categories