The following lines of code are in a user control in a SharePoint website.
ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "jquery144", "<script type=\"text/javascript\" src=\"/_layouts/Unicre.Web.RUOnline.Controlos/Scripts/jquery-1.4.4.min.js\"></script>", false);
ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "javascriptgeral", "<script type=\"text/javascript\" src=\"/_layouts/Unicre.Web.RUOnline.Controlos/Scripts/javascript.js\"></script>", false);
Why doesn't it work? I also can't find the respective script tags in the HTML generated in the response.
The problem has to do with an update panel. After the partial postback, the Javascript stops working. Shouldn't it work with the above code?
(I also tried the RegisterClientScriptInclude method but with the same result.)
This isn't going to work on a partial postback. You need to register the scripts on Page_Load. In the user control, attach to the Load event and call ScriptManager.RegisterClientScriptBlock() from that handler.
After the partial postback, the Javascript stops working
An UpdatePanel partial postback is DOM update of the UpdatePanel <div> contents. This means the previous contents are lost, so the state of inline script contained within that <div> loses its state.
See here for more information:
UpdatePanel does its work on the client through the innerHTML DOM property. A delta is retrieved from the server, finds itself in the existing DOM, disposes of the contents, and then assigns the new content via innerHTML. ... But inline script doesn't work this way. Setting the innerHTML of a DOM element to HTML which contains a script block does not cause that script to execute.
Likewise, calling ScriptManager.RegisterClientScriptBlock() on an UpdatePanel update is not going to act like a page load. You could add the <script> elements directly to the UpdatePanel contents, but it won't execute.
Update
You can call javascript code after a partial postback by adding an endRequest handler to the PageRequestManager:
<script>
function load() {
//register the handler
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);
}
//this handler will execute after a partial postback
function EndRequestHandler(){
//...arbitrary code...
}
window.onload = load;
</script>
Related
I have a master page where I am importing a script file that has a function named ShowNotifyErrorFor(). This method is called from child pages that are using this master page when some error occurs during form validation. I am calling this function like this from C#:
double flatRate;
if (double.TryParse(flateRateTxt.Text, out flatRate) == false)
{
Page.ClientScript.RegisterStartupScript(this.GetType(), "ShowNotifyErrorFor", "ShowNotifyErrorFor(document.getElementById('" + flateRateTxt.ClientID + "'),'Invalid Rate')", true);
return;
}
When I call the same JavaScript function from Browser's console with same arguments then it is executing correctly. But it's not executing when called from C#.
The same code is working on pages that are not using any master page.
What I tried:
I checked if the page is rendering the form tag because one of the SO questions suggested this solution. But the form tag is being rendered.
I tried not to add script tags by passing false to RegisterStartupScript as the third argument. But it didn't work.
I checked if ClientScript object contains the rendered scripts and found that it has the script and I copied and pasted that script on the Browser console and it's working fine there.
Background
I have a client-side button click that triggers a server-side function. Before the server side function is called, a loading panel is displayed (div).
The loading panel needs to be removed once the server-side function has completed.
My Solution
After the server-side function is complete I will call a JavaScript function that will remove the div. So as a test i'm calling an alert script. I'm trying to do this from the master page.
Client-Side Code
My PopUp Function
<script>
function PopUp() {
debugger;
alert('TEST');
}
</script>
My Script Manager
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
Server-Side Code
My Call after server side functions have completed.
//Add the script after <form> tag
bool isClientScriptBlockRegistered = ClientScript.IsClientScriptBlockRegistered("ShowStatus");
if (!isClientScriptBlockRegistered)
{
ScriptManager.RegisterClientScriptBlock(this.Page, this.GetType(), "ShowStatus", "PopUp();", true);
}
Problem
My script isn't called by the server. No alert window is created. When I try to do this from any page other that the master page it works. However on the master page it does not.
Questions
Is there something I'm missing?
Does there need to be a callback or some kind of refreshing of the page for the alert to appear, or can the server just call the script without any action from the client?
Change
ScriptManager.RegisterClientScriptBlock(this.Page, this.GetType(), "ShowStatus", "PopUp();", true);
into
ScriptManager.RegisterClientScriptBlock(this.Page, this.GetType(), "ShowStatus", "setTimeout(function () { PopUp(); }, 10);", true);
or into
ScriptManager.RegisterStartupScript(Page, Page.GetType(), "ShowStatus", "PopUp();", true);
RegisterClientScriptBlock adds the JavaScript code at the top of the page just after the ViewState tag while RegisterClientScriptBlock adds it to the bottom. So if you use RegisterClientScriptBlock and your PopUp() is somewhere lower on the page you'll get an error.
Or by setting a setTimeout you ensure that all the contents is generated and then PopUp() will also be found even is the script block is at the top.
I am trying to fix some issues in an old asp.net application which uses ASP GridView. There are several events bound to the grid. Say sort, row click etc. I want to execute some js function after load/reload completes, (like after sort using header click etc.).
I tried
JQuery's ready function, which fires only on page load.
Placed a script block next to the grid
Placed a RegisterStartupScript in grid_sort (where DataBind happens)
none of them fires on grid reload after sort.
Server-side events always cause a full page lifecycle. But if there are UpdatePanels in the mix then you may get a partial page postback which won't trigger a page load event. Keep in mind the full page lifecycle happens regardless.
When you want to execute some client side code after handling some sort of server side event, you need a way to pass some information to the JS/jQuery after the page fully renders. Usually this is done by using 1 or more <asp:HiddenField> controls.
Typically I will set its ClientIDMode to static to make life easier on the JS side of things. So for example if you have this:
<asp:HiddenField ID="hfSomeData" runat="server" ClientIDMode="Static"
Value="Something set after handling some gridview event"
then you can do this on the javascript side to access the value:
$("#hfSomeData").val();
The following code will execute PostBackHandler based on either the jquery ready event or call from endRequest as issued by an UpdatePanel partial page update
// Handle Full Page postbacks
$(function () {
PostbackHandler(0);
});
// Handle Partial Page postbacks
// i.e. when Gridview embedded in an UpdatePanel
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_endRequest(function(sender, args){
PostbackHandler(1);
});
//PostBackType : 0 for Full Postback
// : 1 for Partial Postback
function PostbackHandler(PostBackType) {
var passed_in_data = $("#hfSomeData").val();
if (PostBackType === 0)
// do postback stuff
else
// do partial postback stuff
}
A $ function (which is a DOM ready function) will be only be executed when the page loads for the first time. Any further AJAX call (which is a partial loading/rendering) will not fire DOM ready function. Which is the reason, I were not able to get it working.
In you case, this function binds my anchor link (button) with the lighbox behavior the first time the page loads. so, it works. The next time when I refresh the update panel (which is a partial render) the button is not bound to lightbox again. Unless this binding is achieved it will not show up.
it work fine first time when page is loaded.
<script type="text/javascript">
$('body').flipLightBox();
</script>
If you need to call Javascript/jQuery function in an UpdatePanel you need place them inside the pageLoad() function:
<script type="text/javascript">
function pageLoad() {
$('body').flipLightBox();
}
</script>
This will call it on every update of the UpdatePanel.
I load this javascript file dynamically in the <head/> of my document like this
<script type="text/javascript">
if (window.screen.width <= 1600)
{
console.log("start");
var jsref1 = document.createElement('script');
jsref1.setAttribute("type", "text/javascript");
jsref1.setAttribute("src", "/javascript/mobileFunction.js");
document.getElementsByTagName("head")[0].appendChild(jsref1);
}
console.log(end)
</script>
In my all my javascript file I have this custom event called which is at the end of $(document).ready
$(document).on("xsltready", function () {
...more code....
console.log("event alled here " + a variable);
The problem is that I see the output for the two console from the dynamically loaded javascript and when I check the resource folder under the script folder in web-inpector(I am using mobile safari and remote web inspector) the file is there. The problem is that sometimes when I refresh the page it looks like the file is not loaded since none of the console.log() from inside the script is executed and. But if I refresh a few times again it comes back. Is this a behavior with loading javascript dynamically?
Note
I can still call the method inside the dynamically loaded JS file, but the custom event I trigger at the end of $(document).ready is not executed at all.
Thanks to #Levi, his comment is above he helped me go in the right direction. He was correct in that the the $(docuemnt).ready is fired before the script has loaded. the DOM does not wait for the script to load, before it is ready. ~ Levi. So what I did was instead of firing my custom event in the $(docuemnt).load it is fired in the $(window).load event, which solve the problem. But now I have a performance issue.