I am running into an issue with running javascript from an external javascript file inside of an UpdatePanel. I am trying to get a color picker working inside of a ListView. The ListView is inside of an UpdatePanel.
I am using this color picker.
Here is what I have narrowed it down to:
If I use the color picker on a textbox outside of an UpdatePanel
, it works perfectly fine through all postbacks.
If I use the color picker on a textbox inside of an UpdatePanel
, it works, until I do an async postback(clicking on an "EDIT" button in the ListView). Once the UpdatePanel
has done the postback, the textbox will no longer show the color picker when clicked. The same occurs when the textbox is in either the InsertItemTemplate
or EditItemTemplate
of the ListView.
If you would like to replicate it, simply download the color picker(it's free), then add this to a webpage...
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<div>
<asp:UpdatePanel ID="panel1" runat="server">
<ContentTemplate>
<asp:TextBox runat="server" ID="textbox" CssClass="color" />
<asp:Button ID="Button1" runat="server" Text="Button" />
</ContentTemplate>
</asp:UpdatePanel>
</div>
When the page loads, the color picker works fine. When you click on the button(which does a postback), the color picker will no longer work.
Any ideas?
To nest UpdatePanel controlsIn the AJAX Extensions tab of the toolbox, double-click the ScriptManager control to add it to the page. In the toolbox, double-click the UpdatePanel control to add an UpdatePanel control to the page.
UpdatePanel controls are a central part of AJAX functionality in ASP.NET. They are used with the ScriptManager control to enable partial-page rendering. Partial-page rendering reduces the need for synchronous postbacks and complete page updates when only part of the page has to be updated.
The asp:UpdatePanel is a feature in the ASP.NET Ajax components that allows you to get a partial update of your page on postback. You can place all of your old non-AJAX components inside the update panel and they will behave as they were AJAX enabled.
The AsyncPostBackTrigger “wires” up these controls to trigger an asynchronous post back. Conversely, controls declared inside an update panel will trigger an asynchronous call by default. The PostBackTrigger short circuits this, and forces the control to do a synchronous post back.
After an asynchronous roundtrip, any startup scripts will not be run, which is likely why it doesn't work after the AJAX callback. The color picker likely has functions which need to be executed on page load.
I've run into this so many times that I wrote a small method to register my scripts in the code-behind, which handles both async and non-async round trips. Here's the basic outline:
private void RegisterClientStartupScript(string scriptKey, string scriptText)
{
ScriptManager sManager = ScriptManager.GetCurrent(this.Page);
if (sManager != null && sManager.IsInAsyncPostBack)
{
//if a MS AJAX request, use the Scriptmanager class
ScriptManager.RegisterStartupScript(this.Page, this.Page.GetType(), scriptKey, scriptText, true);
}
else
{
//if a standard postback, use the standard ClientScript method
scriptText = string.Concat("Sys.Application.add_load(function(){", scriptText, "});");
this.Page.ClientScript.RegisterStartupScript(this.Page.GetType(), scriptKey, scriptText, true);
}
}
I actually baked the above into a base page class so that any page I'm working with can call this.RegisterClientStartupScript(...)
. To do that, simply create a base page class and include it there (making sure to mark protected not private or your inheriting page classes won't be able access it).
With the above code, I can confidently register client scripts regardless of whether the page is doing a postback or callback. Realizing you are using external script files, you could probably modify the above method to register external scripts rather than inline. Consult the ScriptManager class for more details, as there are several script registering methods...
After looking at the jscolor source code, I noticed that it initializes everything on window load. So, you will probably need to re-init with something like this (inside the UpdatePanel):
function yourInit(){
/* keep in mind that the jscolor.js file has no way to determine
that the script has already been initialized, and you may end
up initializing it twice, unless you remove jscolor.install();
*/
if (typeof(jscolor) !== 'undefined'){
jscolor.init();
}
}
if (typeof(Sys) !== 'undefined'){
Sys.UI.DomEvent.addHandler(window, "load", yourInit);
}
else{
// no ASP.NET AJAX, use your favorite event
// attachment method here
}
If you decide to put the jscolor script inside the UpdatePanel, you will also need to add something like this to the end of the jscolor.js:
if(Sys && Sys.Application){
Sys.Application.notifyScriptLoaded();
}
Have you tried ScriptManager.RegisterStartupScript which allows you to "adding JavaScript from the server to a page when performing an asynchronous postback" ?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With