asp.net usercontrol won't fire javascript inside updatepanel - javascript

I've seen similar issues to this and answers but none seem to fix the issue.
I have a user control inside an update panel. Inside my user control I output javascript.
The javascript will not fire when triggered. If I move the javascript to the parent page outside of the usercontrol/updatepanels then it fires. This doesn't make sense to do this as I can't use this usercontrol on another page without either duplicating code...by either duplicating the entire javascript (different site) or adding references to a .js file in every page it's used on (same site). It's just less portable
I merely want to output the javascript with the control (inside the update panel).
The updatepanel is mentioned for accuracy of what I'm doing. It doesn't work even if I place the usercontrol outside of updatepanels.
Keeping it simple (This does not work for me):
USERCONTROL:
<%# Control Language="C#" AutoEventWireup="true" CodeFile="_location.ascx.cs" Inherits="_location" %>
<script type="text/javascript">
function test() {
alert('Hello World!');
}
</script>
<a href="javascript:void(0);" onclick="javascript:test();">
Find For Me
</a>
PARENT:
<uc1:_location runat="server" ID="_location" />
Debugging in chrome tells me "Uncaught ReferenceError: test is not defined"
If I add the javascript directly to the onclick as below, it works:
onclick="alert('Hello World!');"
And as stated above, moving the function to the parent page ALSO works.
It's as if the browser ignores the script output from the user control.
Any ideas?

When you have an UpdatePanel and that UpdatePanel updates it's content, it treats it's content as simple text/html (not code), it does not have any parser available to run the script and make it available for the page.
So this content,
<script type="text/javascript">
function test() { alert('Hello World!'); }
</script>
<a href="javascript:void(0);" onclick="javascript:test();">
Find For Me
</a>
after client side code of update panel runs and updates content of the page, the script part is not parsed - its simple text/html for the page.
This part however runs
Find For Me
because the parse of the onclick attribute is done when you click on it.
There are following workarounds available:
Move your javascript into external file
Move you script outside of the UpdatePanel
Register the script in the code behind with RegisterClientScriptBlock or alternative functions.

In Addition to the solution that Adam Wood posted, I should say that you must use ScriptManager to register the script when using update panel, at least in .net 4.0 because otherwise it won´t work.
So you can put on the PageLoad event of the usercontrol:
string script = #" alert('this is a test');
alert('it worked')";
ScriptManager.RegisterStartupScript(Page,Page.GetType(),"scriptMelhoria",script,true);

Thanks to Aristos for sending me down the right path... Though his solution works, it did not answer the question of outputting the javascript from inside the usercontrol but instead suggested moving it outside. This was not the desired outcome, as stated, as it's not kept inside the control for easier portability.
Here is my solution that accomplishes this:
CS file:
String script = "<script type=\"text/javascript\">";
script += "function test() {";
script += "alert('Hello World!');";
script += "</script>";
Page.ClientScript.RegisterClientScriptBlock(Page.GetType(), "locationScript", script);
One might use a stringbuilder if script is longer, but eitherway works.
This keeps the code entirely inside the usercontrol and it works from the onclick event of the a tag.

Try this;
You can find your script elements after udpdate panel callback and evaluate them.
Add a special attribute to your inline script tag to select elements after callback request.
<script type="text/javascript" data-tag='myscript'>
function test() {
alert('Hello World!');
}
</script>
And add this script to your update panel container aspx file.
<script>
if (Sys !== undefined) {
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_endRequest(endPostbackRequest);
}
function endPostbackRequest(sender, args) {
$("script[data-tag='myscript']:not([data-run])").each(
function () {
eval.apply(window, [$(this).text()]);
$(this).attr('data-run', '1');
});
}
</script>

Preferred way of dealing with javscript code that is bound to DOM elements within UpdatePanel is to subscribe to endRequest event of PageRequestManager and execute your code here. For instance you want to set click event handlers here.
// that is standard way for asp.net to execute JS on page load
// pretty much the same as $(function(){ ...}) with jquery
function pageLoad() {
// find PRM instance and subscribe to endRequest
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(endRequest);
}
function endRequest() {
// set all handlers to DOM elements that are within UpdatePanel
$('<%= myButton.ClientID %>').on('click', test)
}
function test(e) {
alert('Hi')
}
Alternative solution will be to use event delegation like so:
function pageLoad() {
// delegate click event on .myButton inside .container
// to the .container DOM element
$('.container').on('click', '.myButton', test)
}
And have div with a class named container around your update panel. In this case your div.container is never removed from DOM so all event handlers on it will hold after partial postbacks.
Same code without jquery and using only asp.net ajax will look like this:
function pageLoad() {
Sys.UI.DomEvent.addHandler($("myContainer"), "click", delegatedTest);
}
function delegatedTest(e) {
// since asp.net ajax does not support event delegation
// you need to check target of the event to be the right button
if (e.target.id == "myButton") test(e)
}
function test(e) {
alert("HI")
}

Related

Alternative to hide/show content with JS?

is there a better way to replace this kind of js function by simply collapse/toggle a div and show/hide its content?
$(function() {
$('#destselect').change(function(){
$('.dest').hide();
$('#' + $(this).val()).show();
});
});
The reason this is happening is because your js file is called on the head of your page.
Because of this, when you document.getElementsByClassName('collapsible');, colls result in an empty array, as your elements in body are not yet created.
You could either create a separate js file and add it at the end of your body (in that way you make sure your colls are created when your javascript is executed), or just wrap your code on a DOMContentLoaded event listener that will trigger your code once the document has completely loaded.
My guess would be that you are loading your script before browser finishes loading dom conetent and so when it runs the elements it is trying to add event listeners to, don't yet exist.
Try wrapping all you javascript in that file in this:
document.addEventListener("DOMContentLoaded", function(event) {
// all your code goes here
});
The above makes sure that your script is run after loading all elements on the page.
You could add a script tag to the header of your HTML file, this will import the JS file into your current page as follows
<script src="File1.js" type="text/javascript"></script>
Then call the function either in onclick in a button or in another script (usually at the bottom) of your page. Something like this:
<body>
...
<script type="text/javascript">
functionFromFile1()
</script>
</body>
Seems like your script is not executing properly due to a missing variable.
In this script https://www.argentina-fly.com/js/scripts.js
Naves variable in function UpdateDetailsDestination() is not defined.
I think you should resolve this first and then check your further code is working on not.
Please take a look into Console when running page. You'll see all JavaScript related errors there.

How to bind event Jquery to page?

I have Jquery function that executes AJAX query to server.
How can I call this after load page in the specified url page? May I bind this to element HTML, I mean:
<div id="graph" onload="function()"></div>
jQuery handles the HTML file with a variable called document.
Document has two popular event states
load when the page has been loaded
ready when the page has been loaded and all other decorations to the HTML have been applied.
jQuery provides hooks for these states.
To run javascript code after each of the events listed above, you have to put the function within the appropriate event scope.
For loading, this would be…
$(document).load(function() {
// javascript code you want to execute
})
After the page has been ready, but not yet rendered, you can apply some other javascript code using
$(document).ready(function() {
// javascript code you want to execute
})
One way using jQuery:
$(document).ready( function() {
//do whatever you need, you can check if some element exists and then, call your function
if($("#graph").length > 0)
callfunction();
});
No jQuery, only vanilla js:
window.onload = function() {
if(document.getElementById("graph"))
callfunction();
}

How to bind a future event when using jQuery Mobile external page linking?

In jQuery Mobile, the external page is linked via Ajax (i.e. the content of the external page is loaded into current page via Ajax).
The problem is: How to bind a event on the future (i.e. to be loaded) content?
Let say the content to be loaded has the following HTML input
<input type='text' id='foo' name='foo'>
How to bind a input event on it?
With just static HTML, the following code would work
$('#foo').on('input', function () {
...
Now it didn't work now since the DOM is loaded dynamically, I tried to use delegation but also not work
$(document).on('#foo', 'input', function () {
...
Any idea?
You can include the script in the external page as long as the script tag is within the data-role="page" div (Only the content of the first found data-role="page" element is loaded into the current page.
$(document).on("pagecreate", "#extpagedivid", function(){
$(document).on("input", "#foo", function(){...});
});
You can also include this code in the pagecreate handler of the main page as long as you are using event delegation. Make sure the ID of the input is unique across all pages that will be loaded into the main page.
How about using var
var myFunc = function() { ... }
$(document).ready(function() {
$('#foo').on('input', myFunc );
});

Reload? Javascript after Jquery .live/.load

I wanted to load some fragments of external content inside a div, through a menu.
Found "load" and "live", found a tutorial used it = success!
Except, like what's explicit in the documentation, it doesn't load JavaScript.
The thing is, the destination page already loads, inside the header, that same JavaScript, 'cause Wordpress loads it in every page. In this particular page, I'm only using the plugin (nextgen gallery) through the jQuery AJAX call.
So, what I believe is my problem is that I somehow need to alert/reload the JavaScript, right?
And how can I do this?
<script type="text/javascript" charset="utf-8">
jQuery(document).ready(function(){
// ajax pagination
jQuery('#naveg a').live('click', function(){ // if not using wp-page-numbers, change this to correct ID
var link = jQuery(this).attr('href');
// #main is the ID of the outer div wrapping your posts
jQuery('#fora').html('<div class="loading"><h2>Loading...</h2></div>');
// #entries is the ID of the inner div wrapping your posts
jQuery('#fora').load(link+' #dentro')
return false;
});
}); // end ready function
</script>
PS: I've substituted "live" with "on" but didn't work either.
I'm not sure if I understand... your load() command is puling in some Javascript that you want executed? I'm not sure if you can do that. But if you just need to call some JS upon load() completion, you can pass it a function like so:
jQuery('#fora').load(link+' #dentro', function() {
console.log("load completed");
// JS code to be executed...
});
If you want to execute Javascript code included in the loaded page (the page you retrieve via .load()), than you have to use the url-parameter without the "suffixed selector expression". See jQuery documentation for (.load()):
Note: When calling .load() using a URL without a suffixed selector expression, the content is passed to .html() prior to scripts being
removed. This executes the script blocks before they are discarded. If
.load() is however called with a selector expression appended to the
URL, the scripts are stripped out prior to the DOM being updated,
which is why they are never executed. An example of both cases can be
seen below:
Here, any JavaScript loaded into #a as a part of the document will
successfully execute.
$('#a').load('article.html');
However in this case, script blocks in the document being loaded into
#b are stripped out prior to being executed:
$('#b').load('article.html #target');
I think that's your problem (although I have no solution for you, sorry).
Proposal: Maybe you can load the whole page (including the Scripts) and remove (or hide) the parts you don't need?
Cheers.

Bad timing issue, Telerik RadEditor control's client side events and jquery's on page ready event

I have an object that I initialize, and I pass in a parameter that is a radeditor control.
I think set some client side events of the radeditor using my object like this:
<telerik:RadEditor ...
OnClientLoad="My_Object.SomeFunction" ... />
The problem is, my object isn't wired up correctly unless I put it in jquery's ready function, but that seems to fire AFTER the RadEditor event, and as a result I get the error message:
My_Object is undefined
I am doing this:
<script type="text/javascript">
$(document).ready(function () {
editor = $find("<%=RadEditor1.ClientID %>");
My_Object = new MYOBJECT(editor);
});
</script>
The call to $find("<%=RadEditor1.ClientID %>"); is always null if I try and set it outside of ready function.
But when I put it inside the ready function, My_Object is being instantiated too late and when I set the client side events on the RadEditor control it says the method is null.
How can I solve this timing issue?
I have had this same issue with telerik controls as well. You need to put the logic you have in your $(doucment).ready into a client side page_load instead. $(document).ready happens before the ASP.Net client side page_load life cycle has happened so the telerik controls won't be available yet client side.
function pageLoad(sender, e)
{
editor = $find("<%=RadEditor1.ClientID %>");
My_Object = new MYOBJECT(editor);
}
This method will be called every time the ASP.Net page goes through a full life cycle via full page load or partial postback.
You can also check to see if a partial postback is currently happening before the running the logic if you only want this event to happen on the initial page load but not inside any partial loads.
function pageLoad(sender, e)
{
if (!e.get_isPartialLoad())
{
editor = $find("<%=RadEditor1.ClientID %>");
My_Object = new MYOBJECT(editor);
}
}
You could put the script block that initializes your object at the very end of the <body>. You'd not need to rely on the "ready()" handler, but you'd also ensure that the DOM element for your editor were ready to be found and manipulated. (That's why it's not working, probably, when you don't use the "ready" handler in a script in the <head> — the DOM doesn't exist when it runs.)
the $(document).ready() will fire before the editor is initialized. The editor will be available after the init event of the ASP.NET AJAX client framework fires. This happens after the jQuery .ready() code. You should create the My_Object without using a dependence on the editor object, because you will get a reference from the handler of the OnClientLoad function anyway:
<script type="text/javascript">
$(document).ready(function () {
My_Object = new MYOBJECT();
});
</script>
the SomeFunction() code will have a reference to the editor passed as a parameter:
MYOBJECT.prototype.SomeFunction = function(editor){
//editor is a reference to the RadEditor client-side object
}

Categories

Resources