PDA

View Full Version : [CLOSED] Problem changing the Theme on the client side



vadym.f
Aug 01, 2013, 6:41 PM
Hi,

I'm trying to port 1.7 code changing the Theme dynamically on the client. Somehow, I can't seem to get the correct Theme URL from the server as the call always returns the currently set theme URL. I've noticed a fix referenced as r4269 in the Ext.NET.CHANGELOG.txt file:


[r4269] GetThemeurl returns incorrect url

Please consider the code sample below reproducing the issue for me. Am I missing anything here?

Update: It looks like the implementation of the ResourceManager GetThemeUrl() method explicitly makes use of the instance ResourceManager Theme property and ignores the Theme parameter passed to the method. I wonder if there's any other method, possibly static, to return the correct Theme URL.



[Description("")]
public virtual string GetThemeUrl(Theme theme)
{
ResourceLocationType type = this.RenderStyles;

string themeFolder = "ext_theme_" + (this.Theme == Ext.Net.Theme.Default ? "classic" : this.Theme.ToString().ToLowerInvariant());
string themeName = themeFolder + ".ext-theme-" + (this.Theme == Ext.Net.Theme.Default ? "classic" : this.Theme.ToString().ToLowerInvariant()) + "-all";
string fileThemeName = themeName.Replace("ext_theme_", "ext-theme-");

switch (type)
{
case ResourceLocationType.Embedded:
return this.GetWebResourceUrl(ResourceManager.ASSEMBLYSLU G + ".extjs.resources." + themeName + (this.RTL ? "-rtl" : "") + (this.ScriptMode != Ext.Net.ScriptMode.Release ? "-debug" : "") + "-embedded.css");
case ResourceLocationType.File:
return this.ConvertToFilePath(ResourceManager.ASSEMBLYSLU G + ".extjs.resources." + fileThemeName + (this.RTL ? "-rtl" : "") + (this.ScriptMode != Ext.Net.ScriptMode.Release ? "-debug" : "") + ".css");
#if ISPRO
case ResourceLocationType.CDN:
return ResourceManager.CDNPath.ConcatWith("/extjs/resources/" + fileThemeName + (this.RTL ? "-rtl" : "") + (this.ScriptMode != Ext.Net.ScriptMode.Release ? "-debug" : "") + ".css");
#endif
}

return "";
}



<%@ Page Language="C#" %>

<%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>
<script runat="server">
private object[] TestData
{
get
{
var now = DateTime.Now;
return new object[]
{
new object[] { "3m Co", 71.72, 0.02, 0.03, now },
new object[] { "Alcoa Inc", 29.01, 0.42, 1.47, now },
new object[] { "Altria Group Inc", 83.81, 0.28, 0.34, now },
new object[] { "American Express Company", 52.55, 0.01, 0.02, now },
new object[] { "American International Group, Inc.", 64.13, 0.31, 0.49, now },
new object[] { "AT&T Inc.", 31.61, -0.48, -1.54, now },
new object[] { "Boeing Co.", 75.43, 0.53, 0.71, now },
new object[] { "Caterpillar Inc.", 67.27, 0.92, 1.39, now },
new object[] { "Citigroup, Inc.", 49.37, 0.02, 0.04, now },
new object[] { "E.I. du Pont de Nemours and Company", 40.48, 0.51, 1.28, now },
new object[] { "Exxon Mobil Corp", 68.1, -0.43, -0.64, now },
new object[] { "General Electric Company", 34.14, -0.08, -0.23, now },
new object[] { "Government Motors Corporation", 30.27, 1.09, 3.74, now },
new object[] { "Hewlett-Packard Co.", 36.53, -0.03, -0.08, now },
new object[] { "Honeywell Intl Inc", 38.77, 0.05, 0.13, now },
new object[] { "Intel Corporation", 19.88, 0.31, 1.58, now },
new object[] { "International Business Machines", 81.41, 0.44, 0.54, now },
new object[] { "Johnson & Johnson", 64.72, 0.06, 0.09, now },
new object[] { "JP Morgan & Chase & Co", 45.73, 0.07, 0.15, now },
new object[] { "McDonald\"s Corporation", 36.76, 0.86, 2.40, now },
new object[] { "Merck & Co., Inc.", 40.96, 0.41, 1.01, now },
new object[] { "Microsoft Corporation", 25.84, 0.14, 0.54, now },
new object[] { "Pfizer Inc", 27.96, 0.4, 1.45, now },
new object[] { "The Coca-Cola Company", 45.07, 0.26, 0.58, now },
new object[] { "The Home Depot, Inc.", 34.64, 0.35, 1.02, now },
new object[] { "The Procter & Gamble Company", 61.91, 0.01, 0.02, now },
new object[] { "United Technologies Corporation", 63.26, 0.55, 0.88, now },
new object[] { "Verizon Communications", 35.57, 0.39, 1.11, now },
new object[] { "Wal-Mart Stores, Inc.", 45.45, 0.73, 1.63, now }
};
}
}

protected void Page_Load(object sender, EventArgs e)
{
if (!X.IsAjaxRequest)
{
this.Store1.DataSource = this.TestData;
this.Store1.DataBind();
}
}

[DirectMethod]
public string GetThemeUrl(string theme)
{
var temp = (Theme)Enum.Parse(typeof(Theme), theme);
return this.ResourceManager1.GetThemeUrl(temp);
}
</script>
<!DOCTYPE html>
<html>
<head id="Head1" runat="server">
<title>Local Data Paging - Ext.NET Examples</title>
<script type="text/javascript">
var onThemeItemClick = function (menuItem, e) {
var theme = null;
this.items.each(function (item) {
if (item.checked) {
theme = item.text;
}
});

X.GetThemeUrl(theme,
{
eventMask: { showMask: true },
success: function (result) {
Ext.net.ResourceMgr.setTheme(result, theme);
}
}
);
};
</script>
</head>
<body>
<form id="Form1" runat="server">
<ext:ResourceManager ID="ResourceManager1" runat="server" DirectMethodNamespace="X" />
<ext:Viewport runat="server" Layout="FitLayout">
<Items>
<ext:GridPanel ID="GridPanel1" runat="server" Flex="1">
<Store>
<ext:Store ID="Store1" runat="server" RemoteSort="false" AutoLoad="true" PageSize="10">
<Model>
<ext:Model ID="Model1" runat="server" IDProperty="company">
<Fields>
<ext:ModelField Name="company" />
<ext:ModelField Name="price" Type="Float" />
<ext:ModelField Name="change" Type="Float" />
<ext:ModelField Name="pctChange" Type="Float" />
<ext:ModelField Name="lastChange" Type="Date" />
</Fields>
</ext:Model>
</Model>
</ext:Store>
</Store>
<ColumnModel ID="ColumnModel1" runat="server">
<Columns>
<ext:Column ID="Column1" runat="server" Text="Company" DataIndex="company" Width="200">
<Editor>
<ext:TextField ID="TextField1" runat="server" />
</Editor>
</ext:Column>
<ext:Column ID="Column2" runat="server" Text="Price" Width="75" DataIndex="price">
<Editor>
<ext:TextField ID="TextField2" runat="server" />
</Editor>
</ext:Column>
<ext:Column ID="Column3" runat="server" Text="Change" Width="100" DataIndex="change" />
<ext:Column ID="Column4" runat="server" Text="Change" Width="100" DataIndex="pctChange" />
<ext:DateColumn ID="DateColumn1" runat="server" Text="Last Updated" Width="120" DataIndex="lastChange"
Format="HH:mm:ss" />
</Columns>
</ColumnModel>
<SelectionModel>
<ext:RowSelectionModel ID="RowSelectionModel1" runat="server" Mode="Multi" />
</SelectionModel>
<BottomBar>
<ext:PagingToolbar ID="PagingToolbar1" runat="server">
<Items>
<ext:Button ID="ButtonTheme" runat="server" Icon="Paintcan" Text="Select Theme..."
AutoDataBind="true" Cls="button-left" ToolTip="<nobr>Select Application Theme</nobr>">
<Menu>
<ext:Menu ID="MenuSkin" runat="server">
<Items>
<ext:CheckMenuItem ID="MenuItemDefault" runat="server" Text="Default" Group="theme" />
<ext:CheckMenuItem ID="MenuItemGray" runat="server" Text="Gray" Group="theme" />
<ext:CheckMenuItem ID="MenuItemNeptune" runat="server" Text="Neptune" Group="theme" />
<ext:CheckMenuItem ID="menuItemAccess" runat="server" Text="Access" Group="theme" />
</Items>
<Listeners>
<Click Fn="onThemeItemClick" />
</Listeners>
</ext:Menu>
</Menu>
</ext:Button>
</Items>
</ext:PagingToolbar>
</BottomBar>
</ext:GridPanel>
</Items>
</ext:Viewport>
</form>
</body>
</html>

Baidaly
Aug 02, 2013, 12:58 AM
Hello!

Thank you for your investigation. We'll discuss it.

For now, please, use the following:


[DirectMethod]
public string GetThemeUrl(string theme)
{
var temp = (Theme)Enum.Parse(typeof(Theme), theme);
this.ResourceManager1.Theme = temp;
return this.ResourceManager1.GetThemeUrl(temp);
}

Or your can use SetTheme method:



[DirectMethod]
public void GetThemeUrl(string theme)
{
var temp = (Theme)Enum.Parse(typeof(Theme), theme);
this.ResourceManager1.SetTheme(temp);
}

vadym.f
Aug 02, 2013, 3:30 AM
Thanks for your suggestions Daulet! I think using SetTheme() as opposed to assigning the Theme property appears preferable. Property assignment visibly messes the bottom bar layout. Also, there's an independent bottom bar layout disturbance when switching for the Neptune theme in IE9 I'm testing under. The paging toolbar "sinks" after the theme is changed. The way around it is to call doLayout() on the Viewport object but it would be highly unfortunate if one had to do it manually in a real life scenario on multiple frames.


<%@ Page Language="C#" %>

<%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>
<script runat="server">
private object[] TestData
{
get
{
var now = DateTime.Now;
return new object[]
{
new object[] { "3m Co", 71.72, 0.02, 0.03, now },
new object[] { "Alcoa Inc", 29.01, 0.42, 1.47, now },
new object[] { "Altria Group Inc", 83.81, 0.28, 0.34, now },
new object[] { "American Express Company", 52.55, 0.01, 0.02, now },
new object[] { "American International Group, Inc.", 64.13, 0.31, 0.49, now },
new object[] { "AT&T Inc.", 31.61, -0.48, -1.54, now },
new object[] { "Boeing Co.", 75.43, 0.53, 0.71, now },
new object[] { "Caterpillar Inc.", 67.27, 0.92, 1.39, now },
new object[] { "Citigroup, Inc.", 49.37, 0.02, 0.04, now },
new object[] { "E.I. du Pont de Nemours and Company", 40.48, 0.51, 1.28, now },
new object[] { "Exxon Mobil Corp", 68.1, -0.43, -0.64, now },
new object[] { "General Electric Company", 34.14, -0.08, -0.23, now },
new object[] { "Government Motors Corporation", 30.27, 1.09, 3.74, now },
new object[] { "Hewlett-Packard Co.", 36.53, -0.03, -0.08, now },
new object[] { "Honeywell Intl Inc", 38.77, 0.05, 0.13, now },
new object[] { "Intel Corporation", 19.88, 0.31, 1.58, now },
new object[] { "International Business Machines", 81.41, 0.44, 0.54, now },
new object[] { "Johnson & Johnson", 64.72, 0.06, 0.09, now },
new object[] { "JP Morgan & Chase & Co", 45.73, 0.07, 0.15, now },
new object[] { "McDonald\"s Corporation", 36.76, 0.86, 2.40, now },
new object[] { "Merck & Co., Inc.", 40.96, 0.41, 1.01, now },
new object[] { "Microsoft Corporation", 25.84, 0.14, 0.54, now },
new object[] { "Pfizer Inc", 27.96, 0.4, 1.45, now },
new object[] { "The Coca-Cola Company", 45.07, 0.26, 0.58, now },
new object[] { "The Home Depot, Inc.", 34.64, 0.35, 1.02, now },
new object[] { "The Procter & Gamble Company", 61.91, 0.01, 0.02, now },
new object[] { "United Technologies Corporation", 63.26, 0.55, 0.88, now },
new object[] { "Verizon Communications", 35.57, 0.39, 1.11, now },
new object[] { "Wal-Mart Stores, Inc.", 45.45, 0.73, 1.63, now }
};
}
}

protected void Page_Load(object sender, EventArgs e)
{
if (!X.IsAjaxRequest)
{
this.Store1.DataSource = this.TestData;
this.Store1.DataBind();
}
}

[DirectMethod]
public string GetThemeUrl(string theme)
{
var temp = (Theme)Enum.Parse(typeof(Theme), theme);
this.ResourceManager1.SetTheme(temp);
return this.ResourceManager1.GetThemeUrl(temp);
}
</script>
<!DOCTYPE html>
<html>
<head id="Head1" runat="server">
<title>Local Data Paging - Ext.NET Examples</title>
<script type="text/javascript">
var onThemeItemClick = function (menuItem, e) {
var theme = null;
this.items.each(function (item) {
if (item.checked) {
theme = item.text;
}
});

X.GetThemeUrl(theme,
{
eventMask: { showMask: true },
success: function (result) {
Ext.net.ResourceMgr.setTheme(result, theme);
//App.Viewport1.doLayout();
}
}
);
};
</script>
</head>
<body>
<form id="Form1" runat="server">
<ext:ResourceManager ID="ResourceManager1" runat="server" DirectMethodNamespace="X" />
<ext:Viewport runat="server" ID="Viewport1" Layout="FitLayout">
<Items>
<ext:GridPanel ID="GridPanel1" runat="server" Flex="1">
<Store>
<ext:Store ID="Store1" runat="server" RemoteSort="false" AutoLoad="true" PageSize="10">
<Model>
<ext:Model ID="Model1" runat="server" IDProperty="company">
<Fields>
<ext:ModelField Name="company" />
<ext:ModelField Name="price" Type="Float" />
<ext:ModelField Name="change" Type="Float" />
<ext:ModelField Name="pctChange" Type="Float" />
<ext:ModelField Name="lastChange" Type="Date" />
</Fields>
</ext:Model>
</Model>
</ext:Store>
</Store>
<ColumnModel ID="ColumnModel1" runat="server">
<Columns>
<ext:Column ID="Column1" runat="server" Text="Company" DataIndex="company" Width="200">
<Editor>
<ext:TextField ID="TextField1" runat="server" />
</Editor>
</ext:Column>
<ext:Column ID="Column2" runat="server" Text="Price" Width="75" DataIndex="price">
<Editor>
<ext:TextField ID="TextField2" runat="server" />
</Editor>
</ext:Column>
<ext:Column ID="Column3" runat="server" Text="Change" Width="100" DataIndex="change" />
<ext:Column ID="Column4" runat="server" Text="Change" Width="100" DataIndex="pctChange" />
<ext:DateColumn ID="DateColumn1" runat="server" Text="Last Updated" Width="120" DataIndex="lastChange"
Format="HH:mm:ss" />
</Columns>
</ColumnModel>
<SelectionModel>
<ext:RowSelectionModel ID="RowSelectionModel1" runat="server" Mode="Multi" />
</SelectionModel>
<BottomBar>
<ext:PagingToolbar ID="PagingToolbar1" runat="server">
<Items>
<ext:Button ID="ButtonTheme" runat="server" Icon="Paintcan" Text="Select Theme..."
AutoDataBind="true" Cls="button-left" ToolTip="<nobr>Select Application Theme</nobr>">
<Menu>
<ext:Menu ID="MenuSkin" runat="server">
<Items>
<ext:CheckMenuItem ID="MenuItemDefault" runat="server" Text="Default" Group="theme" />
<ext:CheckMenuItem ID="MenuItemGray" runat="server" Text="Gray" Group="theme" />
<ext:CheckMenuItem ID="MenuItemNeptune" runat="server" Text="Neptune" Group="theme" />
<ext:CheckMenuItem ID="menuItemAccess" runat="server" Text="Access" Group="theme" />
</Items>
<Listeners>
<Click Fn="onThemeItemClick" />
</Listeners>
</ext:Menu>
</Menu>
</ext:Button>
</Items>
</ext:PagingToolbar>
</BottomBar>
</ext:GridPanel>
</Items>
</ext:Viewport>
</form>
</body>
</html>

Daniil
Aug 02, 2013, 5:43 AM
Hi,

1. The GetThemeUrl method has been fixed to take the theme parameter into account instead of this.Theme. Thank you for the report.

2. Layout issues. Yes, changing the theme causes changing of sizes. So, relayouting is required and there is, actually, no way to avoid it. We do it in our Examples Explorers as well.

3. As for the Neptune theme. Unfortunately, due to the Neptune implementation it requires hard page reload. Switching to Neptune and from Neptune requires it. We do it in our Examples Explorers. You could look at how we do it. See the GetThemeUrl method of Default.aspx of WebForm Examples Explorer.

4. Personally, I would avoid to switch the theme on the fly without page reload between non-Neptune themes as well. Yes, we do it in our Examples Explorers and it is good enough for it. Though, there might be issues. So, I would avoid it for a real business world application. Generally speaking, it should not be a highly usable operation to switch the theme. Commonly, a user picks up some theme and go with it for years.

vadym.f
Aug 02, 2013, 1:41 PM
Thanks for the fix and the detailed explanation Daniil! I agree to your points. You may mark this thread as closed.