[CLOSED] [#675] ComponentLoader loading component with plugins

  1. #1

    [CLOSED] [#675] ComponentLoader loading component with plugins

    Hi,

    I am struggling to use ComponentLoader when the component has plugins.

    Here is a sample text page:

    <%@ Page Language="C#" %>
    
    <!DOCTYPE html>
    <html lang="en">
        <head runat="server">
            <title>Component loader view MVC Controller</title>
        </head>
        <body>
            <ext:ResourceManager runat="server" />
            
            <ext:Panel runat="server" Width="400" Height="400" Layout="fit">
                <Loader Mode="Component" Url="~/Loader/PanelContent">
                    <AjaxOptions Method="POST" />
                    <LoadMask ShowMask="true" />
                </Loader>
            </ext:Panel>
        </body>
    </html>
    Here is an example of an MVC Controller that works

    public class LoaderController : Controller
    {
        public ActionResult PanelContent()
        {
            return Json(ComponentLoader.ToConfig(new Panel
            {
                Title = "Panel with random plugin",
                Html = "Some content"
            }));
        }
    }
    The above works fine (for me, if I added some icon to the Icon property it doesn't show up, but I can live with that - it might be related to a separate thread we are tracking about modules/handlers etc, which I still need to look into). The main thing for me is that the AJAX response is like this (in its raw form according to the browser console)

    "[{html:\"Some content\",xtype:\"panel\",title:\"Panel with random plugin\"}]"

    Now, if I try to add any random plugin, I get a problem:

    public class LoaderController : Controller
    {
        public ActionResult PanelContent()
        {
            return Json(ComponentLoader.ToConfig(new Panel
            {
                Title = "Panel with random plugin",
                Html = "Some content",
                Plugins =
                {
                    new ClearButton()
                }
            }));
        }
    }
    With the above, all is the same, except the addition of a plugins configuration. Now, the response returns with HTTP 200 (ok), but nothing is rendered on the screen.

    Notice in this case the JSON response is quite different with various escape characters etc (unencoded/raw)

    (I have replaced the value of the webresource.axd querystring with [snip] just for clarity

    "{\u0027x.res\u0027:{res:[{url:\"/WebResource.axd?d=[snip]\u0026amp;t=635574427442910000\"}]},config:\"[{html:\\\"Some content\\\",plugins:[{ptype:\\\"clearbutton\\\"}],xtype:\\\"panel\\\",title:\\\"Panel with random plugin\\\"}]\"}"

    The first character (\u0027x) is unicode for apostrophe. And then further along is a number of not just single escaped quotes, \" but with double slashes, \\" etc.

    I see some overloads for the ToConfig method but I am not clear how to use the overloads that take a component prerenderer as I could not see any uses of those in the Ext.NET code or examples (unless I missed it). And I am not clear if I am meant to use those overrides or not. I would expect I just call ToConfig as I am doing right now.

    The only alternative I can see to this is to use a DirectMethod (which I normally do instead) but it would be nice to get ComponentLoader to work.

    Any suggestions to what I am missing here?
    Last edited by Daniil; Feb 04, 2015 at 11:32 AM. Reason: [CLOSED]
  2. #2
    Hi Anup,

    Thank you for pointing out the problems. Personally, I would also expect it should work with an Icon and a ClearButton. I will be investigating it.
  3. #3
    By the way, the only workaround I can think of at the moment for this would be to unfortunately discard this approach for complex components that may have plugins (come to think of it, I don't know if features on GridPanels are also impacted?) etc, and instead use an alternative such as DirectMethods/DirectEvents etc, instead?

    Any other thoughts about alternatives (if this will take a while to resolve, that is)?

    If my questions here take too much time away from resolving the problem itself, then please ignore :) I am happy to wait for this one!

    However, if you do think it will take some time to resolve, then do let me know so that I can implement some workarounds in the meanwhile.

    Thanks!
  4. #4
    1. An Icon appears to be working for me.
    public ActionResult PanelContent()
    {
        return this.Json(ComponentLoader.ToConfig(new Panel
        {
            Icon = Ext.Net.Icon.Accept,
            Title = "Panel",
            Html = "Some content"
        }));
    }
    The Accept icon shows up in the Panel's Header.

    2. As for auto registration of resources in your scenario, then, unfortunately, it is not supported. A ComponentLoader's ToConfig method supports registering of resources (i.e. it produces a response with resources), but a native ExtJS Component Renderer (Mode="Component") cannot register it dealing with a response.

    We can suggest two approaches.

    Approach #1

    Using a Loader's DirectMethod. In this case it could register the resources.

    View
    <%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage" %>
    
    <!DOCTYPE html>
    <html>
    <head runat="server">
        <title>Ext.Net.MVC v3 Example</title>
    </head>
    <body>
        <ext:ResourceManager runat="server" />
    
        <ext:Panel runat="server" Width="200" Height="100" >
            <Loader runat="server" Mode="Component" DirectMethod="App.direct.PanelContent">
                <LoadMask ShowMask="true" />
            </Loader>
        </ext:Panel>
    </body>
    </html>
    Controller
    [DirectController]
    public class ExampleController : System.Web.Mvc.Controller
    {
        public ActionResult Index()
        {
            return View();
        }
    
        [DirectMethod]
        public ActionResult PanelContent()
        {
            return this.Json(ComponentLoader.ToConfig(new Panel
            {
                Icon = Ext.Net.Icon.Accept,
                Title = "Panel",
                Items = 
                {
                    new TextField
                    {
                        Plugins =
                        {
                            new ClearButton()    
                        }
                    }
                }
            }));
        }
    }
    Approach #2

    Update from SVN and retest:)

    Created an Issue - Loader's with Mode="Component" and Url: support of registering custom resources.

    Added in the revision #6303 (trunk). It goes to 3.1.0 beta.

    View
    <%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage" %>
    
    <!DOCTYPE html>
    <html>
    <head runat="server">
        <title>Ext.Net.MVC v3 Example</title>
    </head>
    <body>
        <ext:ResourceManager runat="server" />
    
        <ext:Panel runat="server" Width="200" Height="100" >
            <Loader runat="server" Mode="Component" Url="~/Aspx/PanelContent">
                <LoadMask ShowMask="true" />
            </Loader>
        </ext:Panel>
    </body>
    </html>
    Controller
    public class ExampleController : System.Web.Mvc.Controller
    {
        public ActionResult Index()
        {
            return View();
        }
    
        public ActionResult PanelContent()
        {
            return this.Json(ComponentLoader.ToConfig(new Panel
            {
                Icon = Ext.Net.Icon.Accept,
                Title = "Panel",
                Items = 
                {
                    new TextField
                    {
                        Plugins =
                        {
                            new ClearButton()    
                        }
                    }
                }
            }), JsonRequestBehavior.AllowGet);
        }
    }
  5. #5
    Thanks once again for an amazingly quick response! Really appreciated.

    I've confirmed icons also load (I think that was related to the other issue we have been tracking which I resolved:
    http://forums.ext.net/showthread.php...l=1#post243341

    Regarding your solution, I got latest from SVN. So far it works great.

    Here is a more complex set of examples I put together to try a variety of scenarios.

    <%@ Page Language="C#" %>
    
    <!DOCTYPE html>
    <html lang="en">
        <head runat="server">
            <title>Component loader view MVC Controller</title>
        </head>
        <body>
            <ext:ResourceManager runat="server" />
            
            <ext:TabPanel runat="server" Width="800" Height="400">
                <Items>
                    <ext:Panel runat="server" Title="Non Ajax" Html="Some content" />
                    <ext:Panel runat="server" Title="Ajax Load Accordion" Layout="Accordion">
                        <Loader Mode="Component" Url="~/Loader/Accordion">
                            <AjaxOptions Method="POST" />
                            <LoadMask ShowMask="true" />
                        </Loader>
                    </ext:Panel>
                    <ext:Panel runat="server" Title="Ajax Load Nested TabPanel" Layout="Fit">
                        <Loader Mode="Component" Url="~/Loader/TabPanel">
                            <AjaxOptions Method="POST" />
                            <LoadMask ShowMask="true" />
                        </Loader>
                    </ext:Panel>
                    <ext:Panel runat="server" Title="Ajax Load BorderLayout" Layout="Border">
                        <Loader Mode="Component" Url="~/Loader/BorderLayout">
                            <AjaxOptions Method="POST" />
                            <LoadMask ShowMask="true" />
                        </Loader>
                    </ext:Panel>
                </Items>
            </ext:TabPanel>
            
            <p>This panel has a loader and will load contents immediately:</p>
            <ext:Panel runat="server" Width="400" Height="200" Layout="fit">
                <Loader Mode="Component" Url="~/Loader/Accordion">
                    <AjaxOptions Method="POST" />
                    <LoadMask ShowMask="true" />
                </Loader>
            </ext:Panel>
        </body>
    </html>

    Controller:
    using System.Collections.Generic;
    using System.Web.Mvc;
    using Ext.Net;
    
    namespace Ext.Net3.Tests.Controllers
    {
        public class LoaderController : Controller
        {
            public ActionResult Accordion()
            {
                return Json(ComponentLoader.ToConfig(new List<AbstractComponent>
                {
                    new Panel { Title="Panel1", Icon=Icon.UserBrown },
                    new Panel { Title="Panel2", Icon=Icon.UserGray },
                    new Panel { Title="Panel3", Icon=Icon.UserGreen }
                }));
            }
    
            public ActionResult TabPanel()
            {
                return Json(ComponentLoader.ToConfig(GetTabPanel()));
            }
    
            public ActionResult BorderLayout()
            {
                var tabPanel = GetTabPanel();
                tabPanel.Region = Region.Center;
                tabPanel.TabPosition = TabPosition.Bottom;
    
                var treePanel = GetTreePanel();
                treePanel.Region = Region.West;
                treePanel.Width = 200;
                
                var components = ComponentLoader.ToConfig(new List<AbstractComponent>
                {
                    tabPanel,
                    treePanel,
                    new Panel { Title="Panel1", Icon=Icon.UserBrown, Html="North", Region = Region.North, Height=50 },
                    new Panel { Title="Panel2", Icon=Icon.UserGray, Html="East", Region = Region.East, Width=200 },
                    new Panel { Title="Panel3", Icon=Icon.UserGreen, Html="South", Region = Region.South, Height=50 }
                });
    
                return Json(components);            
            }
    
            private TabPanel GetTabPanel()
            {
                return new TabPanel
                {
                    Title = "Tab Panel",
                    Items =
                    {
                        new Panel {Title = "Panel1", Html="Panel1", Icon = Icon.UserBrown},
                        new Panel {Title = "Panel2", Html="Panel2", Icon = Icon.UserGray},
                        new Panel {Title = "Panel3", Html="Panel3", Icon = Icon.UserGreen}
                    },
                    Plugins =
                    {
                        new BoxReorderer(),
                        new TabCloseMenu(),
                        new TabScrollerMenu()
                    }
                };
            }
    
            private TreePanel GetTreePanel()
            {
                return new TreePanel
                {
                    Title = "Online Users",
                    RootVisible = false,
                    Tools =
                    {
                        new Tool(ToolType.Refresh, X.Msg.Alert("Message", "Refresh Tool Clicked!").ToScript(), "")
                    },
                    Root =
                    {
                        new Node
                        {
                            NodeID = "root",
                            Expanded = true,
                            Children =
                            {
                                new Node
                                {
                                    Text = "Friends",
                                    Expanded = true,
                                    Children =
                                    {
                                        new Node { Text = "Jack", Icon = Icon.User, Leaf = true },
                                        new Node { Text = "Brian", Icon = Icon.User, Leaf = true },
                                        new Node { Text = "Jon", Icon = Icon.User, Leaf = true }
                                    }
                                },
                                new Node
                                {
                                    Text = "Family",
                                    Expanded = true,
                                    Children =
                                    {
                                        new Node { Text = "Kelly", Icon = Icon.UserFemale, Leaf = true },
                                        new Node { Text = "Sara", Icon = Icon.UserFemale, Leaf = true },
                                        new Node { Text = "Louise", Icon = Icon.UserFemale, Leaf = true },
                                    }
                                }
                            }
                        }
                    }
                };
            }
        }
    }
    The main scenario missing (for me) is a complex grid. I will try to incorporate this into my main code. Assume it will work and close this thread. If not, I will follow up.

    Again, many thanks!

Similar Threads

  1. ComponentLoader and Explicit Id
    By ETICS in forum 2.x Help
    Replies: 0
    Last Post: Jun 26, 2013, 4:21 PM
  2. Replies: 5
    Last Post: May 17, 2013, 4:54 PM
  3. [CLOSED] Generated Code (loading plugins)
    By peter.campbell in forum 1.x Legacy Premium Help
    Replies: 5
    Last Post: Mar 21, 2013, 11:52 AM
  4. [CLOSED] ComponentLoader inconsistency
    By RCN in forum 2.x Legacy Premium Help
    Replies: 10
    Last Post: Jun 07, 2012, 12:24 PM
  5. [CLOSED] Mask delay and when component is ready loading?
    By state in forum 1.x Legacy Premium Help
    Replies: 2
    Last Post: Jul 15, 2009, 6:59 PM

Posting Permissions