By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,098 Members | 1,895 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,098 IT Pros & Developers. It's quick & easy.

Register external style sheet during asynchronous postbacks

Frinavale
Expert Mod 5K+
P: 9,731
So a while ago I created a Tab Strip Control (before the AjaxToolkit had theirs otherwise I would have probably just used theirs).

When I looked at the AjaxToolkit control to see how they got around this problem I discovered that they're using Animations. I don't want to bloat my control with the Ajaxtoolkit's Animation stuff though.

I guess I should tell you what the problem is.

I have a TabStrip custom control. It's a Table that has JavaScript attached to it so that when the user clicks one of the <td>'s (that is the tab) it makes the Panel that's associated with the tab visible.

The TabStrip lets developers apply custom styles for highlighted and unhiglighted tabs...it's very customizable.

For simplicity sake I have the developer pass the name of a CSS Class which is applied the the tabs.

I (being the developer using the TabStrip control) have placed these styles in an external style sheet (this style sheet is embedded into the web application and the appropriate style sheet is loaded according to the application's settings).

Here's the problem:

On the first page load, and during full page postbacks, the JavaScript for the tabs and external style sheet are sent to the browser. The browser loads them and the tabs work perfectly.

The page has an UpdatePanel on it.

The UpdatePanel causes an asynchronous postback to the server and returns with updated stuff for the contents of the UpdatePanel.

After this point the JavaScript for the TabStrip controls on the page works (it displays the associated Panels when tabs are clicked) BUT the highlight style is not applied to the highlighted tabs when they're clicked on.

I've been trying to find a way to make sure that my external style sheets are sent to the browser on asynchronous postbacks as well but I haven't had much luck with finding a valid answer to this problem.

I'm wondering if this is even the problem. The controls within the UpdatePanel use the same external style sheet as the TabStrip and the style is properly applied to these controls.

It's the JavaScript controlling the TabStrip that's having the problem accessing the style.

The TabStrip (at this time) is not in the UpdatePanel.

Any recommendations on how to solve this problem would be great!

Thanks,

-Frinny
Sep 4 '09 #1
Share this Question
Share on Google+
4 Replies


Frinavale
Expert Mod 5K+
P: 9,731
I'm starting to really run out of ideas on what to try next.

My latest attempt was to actually register a script that creates the link to the external style sheet in the browser...

JavaScript that creates the link:
Expand|Select|Wrap|Line Numbers
  1. function createStyleLink(obj) {
  2.     var link = document.createElement('link');
  3.     link.href = obj.href;
  4.     link.rel = obj.rel;
  5.     link.type = obj.type;
  6.     document.getElementsByTagName('head')[0].appendChild(link);
  7. }
VB Code that "registers" the script that should be registered every time an asyncpostback occurs:
Expand|Select|Wrap|Line Numbers
  1. Dim href As String
  2.  
  3. Dim styleSheet As New HtmlGenericControl("link")
  4. styleSheet.Attributes.Add("type", "text/css")
  5. styleSheet.Attributes.Add("rel", "stylesheet")
  6.  
  7. #If SysBuild="A" Then
  8.   href = Page.ClientScript.GetWebResourceUrl(GetType(MyNamespace.SomePage), "MyNamespace.SysBuildAStyle.css")
  9.   styleSheet.Attributes.Add("href", href)   
  10. #End If
  11.  
  12. #If SysBuild="B" Then
  13.   href = Page.ClientScript.GetWebResourceUrl(GetType(MyNamespace.SomePage), "MyNamespace.SysBuildBStyle.css")
  14.   styleSheet.Attributes.Add("href", href)   
  15. #End If
  16.  
  17. If (MyScriptManager.IsInAsyncPostBack) Then
  18.   Dim linkValues As New Dictionary(Of String, String)
  19.   linkValues.Add("rel", "stylesheet")
  20.   linkValues.Add("type", "text/css")
  21.   linkValues.Add("href", href)
  22.  
  23.   Dim jsSerializer As New JavaScriptSerializer
  24.  
  25.   Dim registerScript As New StringBuilder
  26.   registerScript.Append("registerLink(")
  27.   jsSerializer.Serialize(linkValues, registerScript)
  28.   registerScript.Append(");")
  29.   ScriptManager.RegisterStartupScript(Me, _
  30.     GetType(MyNamespace.SomePage), _
  31.     "registerStyleScript", _
  32.     registerScript.ToString, _
  33.     True)
  34. Else
  35.   Me.Page.Header.Controls.Add(styleSheet)
  36. End If
  37.  
No such luck!
Sep 4 '09 #2

Frinavale
Expert Mod 5K+
P: 9,731
So the JavaScript that creates the link wasn't being called in the browser during the onload event.

I went to all the trouble of adding an AnimationExtender to the page...and calling the script from the animation's OnLoad event.

Expand|Select|Wrap|Line Numbers
  1. Private Sub ApplyStyle()
  2.  
  3. Dim href As String
  4.  
  5. Dim styleSheet As New HtmlGenericControl("link")
  6. styleSheet.Attributes.Add("type", "text/css")
  7. styleSheet.Attributes.Add("rel", "stylesheet")
  8.  
  9. #If SysBuild="A" Then
  10.   href = Page.ClientScript.GetWebResourceUrl(GetType(MyNamespace.SomePage), "MyNamespace.SysBuildAStyle.css")
  11.   styleSheet.Attributes.Add("href", href)   
  12. #End If
  13.  
  14. #If SysBuild="B" Then
  15.   href = Page.ClientScript.GetWebResourceUrl(GetType(MyNamespace.SomePage), "MyNamespace.SysBuildBStyle.css")
  16.   styleSheet.Attributes.Add("href", href)   
  17. #End If
  18.  
  19. 'If (MyScriptManager.IsInAsyncPostBack) Then
  20.   Dim linkValues As New Dictionary(Of String, String)
  21.   linkValues.Add("rel", "stylesheet")
  22.   linkValues.Add("type", "text/css")
  23.   linkValues.Add("href", href)
  24.  
  25.   Dim jsSerializer As New JavaScriptSerializer
  26.  
  27.   Dim registerScript As New StringBuilder
  28.         registerScript.Append("function registerStyle(){" + vbLf)
  29.         registerScript.Append("    createStyleLink(")
  30.         jsSerializer.Serialize(linkValues, registerScript)
  31.         registerScript.Append(");" + vbLf)
  32.         registerScript.Append("}")
  33.  
  34.   ScriptManager.RegisterStartupScript(Me, _
  35.     GetType(MyNamespace.SomePage), _
  36.     "registerStyleScript", _
  37.     registerScript.ToString, _
  38.     True)
  39.  
  40.  generalAnimation.Animations = GenerateOnloadAnimation("registerStyle()")
  41. 'Else
  42.   Me.Page.Header.Controls.Add(styleSheet)
  43. 'End If
  44. End Sub
  45.  
  46.  
  47. Private Function GenerateOnloadAnimation(ByVal script As String) As String
  48.         Dim str As New StringBuilder
  49.         str.Append("      <OnLoad>" + vbLf)
  50.         str.Append("            <Sequence>" + vbLf)
  51.         str.Append("                <ScriptAction Script=""" + script + "; """ + " />" + vbLf)
  52.         str.Append("            </Sequence>" + vbLf)
  53.         str.Append("       </OnLoad>" + vbLf)
  54.         Return str.ToString
  55.     End Function
  56.  

So, now what happens is the style sheet is not loaded the first time the page is sent down. When I cause an asynchronous postback the style is loaded in the browser.

I removed the comments that prevented the style sheet from loading the first time in the page and tested the tab control.

I was not pleased to discover that this whole process did not fix the problem.

I'm stuck.

-Frinny
Sep 8 '09 #3

Frinavale
Expert Mod 5K+
P: 9,731
I have been going crazy over a problem with my tab control.

It has to do with something messing up during ajax requests in ASP.NET and it's driving me crazy because I think I've gone through at least 50 different possible solutions to try to fix this problem.

Let me explain. I have a Tab control (a TabStrip). Its simply a table that has one row and each column (each <td> element) is a "tab". Whenever a tab is clicked a corresponding <div> is displayed.

This works, the corresponding <div> is displayed because I'm setting the div's style property to display:block.

The problem I'm having has to do with the styles applied to the <td> elements. There are 2 styles, one that indicates that the tab is selected, and the other is to indicate that the tab is not selected.

So when this user selects a tab, the corresponding <div> is displayed and it loops through the <td>s in the TabStrip and applies the "unselected" style to all of the tabs except the currently selected tab.

This works awesome unless an Ajax request has ever occurred on the page.

For some crazy reason the css classes are no longer available to the JavaScript that controls the tabs. The tabs work (as in they display the corresponding <div>s) when clicked on except the styles are not applied to the tabs any more.

I've tried just about everything to get around this. I even created a JavaScript function that dynamically adds the <link> to the style sheet with the tab's styles in it to ensure that the style sheet was being loaded even during Ajax requests.

This did not help and I'm now considering a completely different approach but I have no idea how I'm going to do this.

What I want to do is set the style property of the <td>s instead of setting the className property.

The styles are stored in the external style sheet and I would like to keep them there so that I can easily change the style of the TabStrip using the style sheet whenever I want to without having to edit server code.

So...how do you get the style out of the styleSheet to parse it and apply the appropriate style properties to the element?

Do you have any other recommendations...because this idea seems to be quite difficult and at this point I'm wondering if I'm over looking some much simpler solution to this ugly problem.

Thanks for your help,

-Frinny
Sep 8 '09 #4

Frinavale
Expert Mod 5K+
P: 9,731
I found the answer to the problem.

It had nothing to do with reloading the style sheet. It ended up being a problem with the way I was registering the JavaScript arrays used for tabbing purposes in my .NET code with the ScriptManager.

It's long and complicated for me to explain so I'll just sum it up to this note:

The ScriptManager.RegisterArrayDeclaration() method will add elements to any already existing array...if the array doesn't exist it'll create one and then add elements to it. You should only call this function if you need to insert new elements into the array.

I got around my problem by using the Page.ClientScript.RegisterArrayDeclaration() method instead. This doesn't have the same behaviour.

Thanks for your time!

-Frinny
Sep 8 '09 #5

Post your reply

Sign in to post your reply or Sign up for a free account.