Ext.Net - Controlling core css and javascript files rendered on the page

Our designer had created a comprehensive custom theme for ExtJs, and we wanted to use it in our ASP.NET app that leverages Ext.Net and ExtJs extensively.

If you have used Ext.Net, you would know that all ExtJs resources are embedded in Ext.Net.dll assembly that are automatically put on the page whenever you add an <ext:ResourceManager /> to the page. This includes the core ExtJs css and javascript resources (including current ExtJs theme's resources), plus Ext.Net's own resources (providing extensions/enhancements to Ext classes).

In our case, this was not desirable as we had a custom Ext theme and we did not want any of ExtJs css files on the page. After some basic research, I figured out how to do it (prevent default css files being added to the page, and control all css files put on the page manually). The <ext:ResourceManager /> has 2 properties called RenderStyles and RenderScripts each of which is an enum with 5 possible values:

  1. Embedded - the default value which loads resources embedded into the toolkit and put on the page automatically.
  2. CacheFly - setting any of the above properties to this enum value loads the corresponding resources from CacheFly CDN.
  3. CacheFlyAndFly - This value loads Ext core css/script files from CacheFly CDN and rest of them (including Ext.Net's own customizations) locally from the same web-server's disk. Try using this value and see the page's source to figure out which resources would be loaded from CacheFly and which are loaded from local web-server.
    Please note that resources loaded from local web-server are expected to be in a particular directory structure (with Ext.Net as the base directory in your application root). Please view page's source with this option to figure out the directory structure.
  4. File - All resources (including Ext and Ext.Net ones) are loaded from local disk. They are again expected to be in a particular folder structure (see the page's source with this option).
  5. None - The last and the final option is None. Ext.Net won't load any css/script resource with this option and everything has to be put on the page manually. While this is the most flexible option, it's also a bit tricky to manage.

In our case, we had provided our users an option to switch between the basic Ext themes and our custom theme specific to our app. The following server-side code dynamically puts the selected theme's css resources on the page (the theme's name is assumed to be in query-string):

 

{syntaxhighlighter brush: csharp;fontsize: 100; first-line: 1; }protected override void OnInit (EventArgs e) { if (!X.IsAjaxRequest) { string theme = this.Context.Request["theme"]; if (theme == null) theme = ""; theme = theme.ToLower(); ResourceManager resourceManager = X.ResourceManager; switch (theme) { case "blue": resourceManager.Theme = Ext.Net.Theme.Default; break; case "gray": resourceManager.Theme = Ext.Net.Theme.Gray; break; case "slate": resourceManager.Theme = Ext.Net.Theme.Slate; break; case "access": resourceManager.Theme = Ext.Net.Theme.Access; break; default: resourceManager.RenderStyles = ResourceLocationType.None; base.RegisterStyleInclude(this, "~/resources/extjs/resources/css/ext-all-notheme.css"); base.RegisterStyleInclude(this, "~/resources/extjs/resources/css/idesign.css"); base.RegisterStyleInclude(this, "~/resources/extjs/ux/plugins/commandcolumn.css"); base.RegisterStyleInclude(this, "~/resources/extjs/ux/plugins/multiheader.css"); base.RegisterStyleInclude(this, "~/resources/extjs/ux/plugins/ratingcolumn.css"); if (Request.UserAgent.ToLower().Contains("ipad")) { base.RegisterStyleInclude(this, "~/resources/extjs/resources/css/idesign-ipad.css"); } break; } } base.OnInit(e); }{/syntaxhighlighter}

RegisterStyleInclude and RegisterScriptInclude are 2 custom methods that bascially put the passed resource on the page (with some additional facilities to ensure the same resource is not put twice etc). I believe you can easily replace calls to these methods to register css/script files on page from code-behind using typical ASP.NET techniques for the purpose.

One thing you would want to take note of is that "None" is a pretty tricky option to manage if you do opt for it. As it suggests, Ext.Net would not register any resource on the page automatically, you would need to do it manually (and this included Icons).

So the following markup:

 

<ext:Button runat="server" Text="Search" Icon="Zoom" />

 

would although lead to the button showing up on the page, it's icon would not be present. For that, you need to register it manually in code-behind like:

 

Ext.Net.X.ResourceManager.RegisterIcon(Icon.Zoom);

 

This would get troublesome if you are using a large number of icons. An easier approach might be to monitor Ext.Net's directory structure requirements for placing resources when using "File" mode, and use this mode instead (putting files in those locations). We already had a well-defined custom directory structure for resources, so "File" was not flexible enough for us and we opted for "None" resource mode instead.

UPDATE:

  1. Oct 13, 2011 - Please read the comments below. The toolkit has new features to make the process easier.

 

Web 2.0: 

Comments

I think we'll add a 'NoTheme' Theme. Selecting this option will render the ext-all-notheme.css. The result will not be much different that what you have configured, although will be another option instead of setting RenderStyles="None".

I'll check on why the Icon property is not rendering even if RenderStyles="None". I would have expected this to still work. This functionality is more associated to the initialization script, than the .css rendering. 

Thanks for posting the tutorial. We appreciate your support. 

Cheers!

rahul's picture

Hi Geoff, I also think a "NoTheme" option would be great. Another facility you might want to consider is adding a string property for ThemeName which works when RenderStyles="File" or "CacheFlyAndFile". So it will look for the css files for the theme in the same directory structure on disk as it looks for "Slate" or other themes with these RenderStyles modes.

I was surprised when Icons did not work with RenderStyles="None". But then I thought it might be by design (css classes are rendered on page when you register an Icon) and did not bother troubling you on the forums :)

Quick update to let you know the "NoTheme" option has been added to the list of Theme options. The new feature is now available in SVN to subscribers and will be publicly available with the upcoming v1.3 release.

Example
<ext:ResourceManager runat="server" Theme="NoTheme" />

Hope this helps.

rahul's picture

Great, thanks for the update Geoff.. I have updated the blog post to reflect the same.

We've added some extra UserAgent detection to the 'X' class. So now you can easily do the following:

Example

    X.Msg.Notify("UserAgent", X.IsIPad).Show();

These new properties are now available in SVN and will be publicly available with the upcoming v1.3 release. 

Here's full SVN notes from commit #3735:


[NEW] Add new Browser, OS and Device detection properties to 'X'. 

Example

    X.Msg.Notify("UserAgent", X.IsIPad).Show();

Full list of new properties include:

User Agent Detection (browser)

    IsOpera
    IsChrome
    IsWebKit
    IsSafari
    IsSafari3
    IsSafari4
    IsIE
    IsIE6
    IsIE7
    IsIE8
    IsIE9
    IsGecko
    IsGecko3

User Agent Detection (operating system)

    IsWindows
    IsMac
    IsIOS
    IsLinux

User Agent Detection (device)

    IsIPad
    IsIPhone
    IsIPod

rahul's picture

That's also handy Geoff, thanks again for the update.

Hi Rahul

I know this is going to sound a bit odd, but, can you share the theme that your designer created?

I've been looking all over the web for a complete Ext Js theme that can be used with Ext.NET so I can start to customize our application but I haven't found a single example of how to use it.

I'll be glad if you can help me.

Have a great day

rahul's picture

Sorry Luis, can't do that. The theme is proprietary and customized for a particular project we work upon.

Yeah, I knew that would be your answer, but I had to try hehe

I'll keep looking for an example or I will build one by my own.

Thanks a lot for your time

Hi Rahul,

   How to load the javascript files from local machine.  I want the Ext.Net should load the javascript files from the local server instead of the CDN.

   Is there any posibility to do the same.

Regards,
Seshu Kumar.

rahul's picture

Hi Seshu, did you check this portion of the sample code provided:

{syntaxhighlighter brush: csharp;fontsize: 100; first-line: 1; }resourceManager.RenderStyles = ResourceLocationType.None; base.RegisterStyleInclude(this, "~/resources/extjs/resources/css/ext-all-notheme.css");{/syntaxhighlighter}

You can use a similar approach for rendering scripts too from your server.

Hi Rahul,

   Thanks for your fast reply.  But whenever I am develping an application the core extJs and the javascripts related to the Ext.Net are loading from the CDN.  So I want to over ride this behaviour as my application will not exposed to the pulic, ie., intranet application where we do not have the internet connetion.

Thanks & Regards,
Seshu Kumar.

rahul's picture

Seshu, as already advised, set RenderScripts on ResourceManager to None and then manually add them on the page. I believe by default Ext.Net loads from same domain itself using embedded resources, so I can't really imagine why you need to load them manually.

Please be advised setting to None also means you will need to load stylesheets/scripts for plugins etc manually, for each plugin you need on your page.