Rewire client side events wired by jQuery on reloading the UpdatePanel - c#

I have a repeater in an updatepanel, in the repeater there are several panels.
The panels are different in ways, but they have one common css class, so I wire their onclick, onmouseover and onmouseout event with jQuery on the $(document).ready
But after a partial postback of the updatepanel update these wires are lost and I cant find a place to put these wires back in.
$(document).ready(function () {
$(".actionicon_normal").click(function () {
ClickActionIcon($(this));
});
$(".actionicon_normal").hover(function () {
HoverActionIcon($(this));
}, function () {
OutActionIcon($(this));
});
$(".actionicon_normal").each(function (i) {
var chk = $(this).find("input");
var backpos = $(this).css("background-position").split(" ");
if (chk.attr("checked")) {
$(this).css("background-position", backpos[0] + " -" + $(this).height() + "px");
}
});
})
as you can see I modify the background position in $(".actionicon_normal").each.
I need a place to run a the same after the updatepanel is updated.
I tried to experiment with .ajaxComplete, but was unable to find a proper solution.
Another way would be to wire these in the codebehind, but I cannot get a hold of all the actionicons, as the ItemDataBind only urns on first load, plus even in ItemCreated I'm not able to get a hold of all these divs having one same css class, plus there is a CheckBox in the div which I need to check for the checked value and I was not able to do that either. So if the server side is a better way, I would need a lot of help on that.

This page might help:
http://msdn.microsoft.com/en-us/library/bb386417.aspx
The following method is triggered by the Script manager every time the page is loaded, you are only concerned about partial postbacks so it also check this
function pageLoad(sender, args) {
if (args.get_isPartialLoad()) {
}
}

Related

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);
});
});
});
});
}

Using jQuery to get data attributes

Now, bear in mind I'm just trying to ensure that the code works by consuming the ready event here. I just want to make sure that the data I expect is getting pulled by jQuery. I've also tried the load event.
In the end I'd want to use the load or ready event to set the image initially and then of course use the hover event to change that image on hover.
I've tried a lot of the answers here on SO and just can't seem to get this working, so hopefully y'all can help me.
JavaScript:
$(document).ready(function () {
$("#submenumain-link").ready(function () {
alert($(this).data()["selectedimage"]);
alert($(this).data()["hoverimage"]);
});
$("#submenumain-link").hover(function () {
alert($(this).data("selectedimage"));
alert($(this).data("hoverimage"));
});
});
HTML:
<li id="submenumain-link"
data-selectedimage="some-image.png"
data-hoverimage="some-other-image.png">
But for whatever reason the alert messages just state undefined. Am I missing something here?
EDIT
Note that if I place those same alert statements in the hover, it works as expected. What event could I use to do the initialization?
$(this).data('selectedimage');
You don't need the brackets []
The real problem is that ready should not be used in this way. The ready event should only be used with making sure the DOM is ready - http://api.jquery.com/ready/
So technically, inside of document.ready, all of the DOM is ready and should be available for these kinds of things. Inside of document.ready, the value of this refers to the document element, so you need to actually grab the li element. Your code should be something like this:
$(document).ready(function () {
var li = $("#submenumain-link");
alert(li.data()["selectedimage"]); // or li.data("selectedimage")
li.hover(function () {
//alert($(this).data("selectedimage"));
//alert($(this).data("hoverimage"));
});
});
http://jsfiddle.net/XN2LV/
The issue is your .ready() call. You should use a load event if you want to wait until something is loaded but in this case it is an li element that will already exist so your code should be:
$(document).ready(function() {
var test = $("#submenumain-link");
alert(test.data('selectedimage'));
alert(test.data('hoverimage'));
test.hover(function() {});
});
It should be alert($(this).data("selectedimage"));
Look here: HTML5 data-* Attributes.

ASP.Net Ajax UpdatePanel to be loaded only after the page is ready

I am using ASP.Net AJAX UpdatePanel to load the right part of the page.
As that part will take some time to load, I would like to load it after the other parts of the page is loaded.
I can use either normal AJAX or ASP.Net AJAX but I chose to use the latter as I want to try it out.
I found out that my UpdatePanel is always loaded.
I want it to be loaded only after the page is ready.
Some says to use the timer, some says to use some javascript.
But I still can't get it done.
So, these are my 2 obstacles, to stop loading when the page starts and to start loading when the page is ready
why don't you enable and disable on page events? for example. try in Page_PreLoad event, set the update panel's enable property to False. While in Page_LoadComplete event, set it back to enabled = true
UpdatePanels use Ajax to update, not on first load.
If you want it to load quickly on first load, avoid any expensive processing, database calls on load. Put them in an
if(IsPostBack)
{
//your long processing
}
Now use an AsyncPostBackTrigger to make your updatePanel postback.
try with this code ( Conditional Mode + Update Method)
<asp:UpdatePanel ID="YourIdPanel" UpdateMode="Conditional" runat="server">
//In order to force loading
YourIdPanel.Update();
<script type="text/javascript">
var currentItemID=$('#<%= labcurrentItemID.ClientID %>').html();
if (currentItemID != null) {
$(document).ready(function () {
$('#main_container').load('/Custom/Going%20Places/PopularRelatedArticle.aspx?currentID=' + currentItemID);
});
}
else {
$(document).ready(function () {
$('#main_container').load('/Custom/Going%20Places/PopularRelatedArticle.aspx?currentID={7F0811A7-D484-4675-8A23-0AEB235B9B5F}');
});
}
</script>

ajax asp.net and jquery conflict

I have multiple jquery files in my project.
Yesterday googled this problem and find solution. I edited this
$(document).ready(function () {
with this
function pageLoad() {
Now problem is that if i will use this in all my jquery files. Every scripts will stops working.
That is two different things. The
$(document).ready(function () {
is from and to jquery, it tells when the DOM is loaded and it start executing the code inside.
The
function pageLoad() {
is from ASP.NET and it is one of handler of Application.Load (client-side)
The reason why it will stop working is because in the same page you can only have one event with the same name, by default pageLoad will be the handler of Application.Load but you can associate another name. I don't see why you have problems between the two, can you explain it better?
EDIT:
After your comment, if you want/need to use Sys.Application.add_load (by default pageLoad) you should add a different name for each js file you need.
From msdn:
// Attach a handler to the load event.
Sys.Application.add_load(applicationLoadHandler);
function applicationLoadHandler() {
// Redirect to alternate page if not business hours.
var d = new Date();
if (!(8 < d.getHours() < 17)) {
window.location = "AfterHours.aspx";
}
As you can see, you can give a different name to add_load and you should give a different name to use more than one for the same page/request.
}
Replace pageLoad with something like this:
$(function() {
// This will be executed when the page is loaded
});
or to avoid name collisions...
(function($) {
// This will be executed when the page is loaded
})(jQuery);
Edit: As rich.okelly pointed out the second example will run as soon as the script is loaded.

Executing a Javascript function from an asp.net codebehind?

OK, this feels like a question that should be easy to answer, but as with so much mixing of asp.net and jQuery, it's a bit of a nightmare.
What I want to do is be fading a div in and out at various times during the client's viewing of my asp.net page; I fade it out using jQuery's fadeTo() before triggering an UpdatePanel update (to indicate that the data there is not fresh) and I want to fade it in again once the UpdatePanel has been updated. I've gotten as far as updating the UpdatePanel in the codebehind, and this results in the div's content changing... but how do I fade the div back in again?
The way I see it, there are 2 ways; register an event handler on page load to detect when the div's content has been changed and fade it back in, or call a function from the asp.net codebehind when I've updated the div to fade it back in.
In the first case, there doesn't seem to be any event triggered by the div's content changing, so I can't seem to do that. If anyone knows how I could get a client event to trigger when I update the div, that would be a nice solution.
In the second case, I thought that this was what ClientScriptManager was for, but it doesn't quite do what I want. I want to be able to register a particular Javascript function with ClientScriptManager and then tell ClientScriptManager to execute it in the client, from my codebehind. You can't seem to do that. ClientScriptManager.RegisterClientScriptBlock() simply inserts some <script> into the HTML output, rather than calling a function. Presumably this would work if I kept registering things like:
<script>fadeBackIn();</script>
because the Javascript would be immediately evaluated and run, but this feels messy, and that feeling is intensified by the fact that I'd have to keep randomly generating a new unique value for the key argument of ClientScriptManager.RegisterClientScriptBlock(), because it's specifically designed to stop this kind of repeated code. However, I'm struggling to see an alternative. Can anyone come up with a good idea as to a better mechanism to get this to work?
I'd really like something along the lines of:
ClientScriptManager.RegisterClientScriptFunction("fadeBackIn", "function fadeBackIn(){ ... }");
[...]
ClientScriptManager.ExecuteClientScriptFunction("fadeBackIn");
but I don't see that functionality available. :-(
You can attach to the page loaded event. The pageLoaded handler recieves an argument of type PageLoadedEventArgs which contains a get_panelsUpdated method that you can call to enumerate all the UpdatePanels whose content was just updated.
Example:
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_pageLoaded(pageLoaded);
function pageLoaded(sender, args)
{
var panels = args.get_panelsUpdated();
if (panels.length > 0)
{
for (var i in panels)
{
if (panels[i].id == "DesiredUpdatePanelId")
{
fadeBackIn();
}
}
}
}
Because html is stateless, you'll need an asynchronous way of determining if the content has changed in your div. I would try using the window.setInterval to check if your content has changed every 500ms or so.
If your div looks like this:
<div id="mycontent">Blah, blah.</div>
Then this might be a solution:
$(function(){
var $mycontent = $('#mycontent');
var myContentHtml = $mycontent.html();
var intervalId;
function checkIfDivChanged()
{
window.clearInterval(intervalId);
if (myContentHtml != $mycontent.html())
{
myContentHtml = $mycontent.html();
// run update here..
fadeBackIn();
// if you want to stop the check then uncomment next line..
// return;
}
intervalId = window.setInterval(checkIfDivChanged, 500);
}
checkIfDivChanged();
});
If you are using, or are willing to use the ASP.NET Ajax Control Toolkit, it contains a control that does exactly what you are looking for: UpdatePanelAnimation.
Take a look here for more information on that control, and here for more information on using animations.
I have written small script with pure JavaScript (no jQuery required), you can just have this script in your page and change the alert part.. plus of course the ID of the div element.
<script type="text/javascript">
var _watchTimer = 0;
window.onload = function WindowLoad(evt) {
_watchTimer = window.setInterval("WatchForChange();", 100);
}
function WatchForChange()
{
var oDiv = document.getElementById("MyDivToWatch");
if (oDiv == null)
{
window.clearInterval(_watchTimer);
return;
}
var prevHtml = oDiv.getAttribute("prev_html") || "";
var curHtml = oDiv.innerHTML;
if (prevHtml != curHtml)
{
if (prevHtml.length > 0)
{
alert("content changed");
}
else
{
//first run, ignore
}
oDiv.setAttribute("prev_html", curHtml);
}
}
</script>
<div id="MyDivToWatch">I can be changed..</div>
<button type="button" onclick="document.getElementById('MyDivToWatch').innerHTML += ' like this..';">Change</button>
Added the whole code used to test, used a button to dynamically change the contents but it should work with changing it via AJAX call aka UpdatePanel.

Categories