[CLOSED] Razor, X.Msg.Notify during a DirectEvent and ResourceManager

  1. #1

    [CLOSED] Razor, X.Msg.Notify during a DirectEvent and ResourceManager

    Hi,

    I am trying to create an MVC version of the example page that comes with the NuGet package.

    The bit to create the window with the text area and button is straight forward enough:

    View:

    @{
        Layout = null;
    }
    <!DOCTYPE html>
    <html>
    <head>
        <title>DirectEventExample</title>
    </head>
    <body>
        @Html.X().ResourceManager().Theme(Theme.Gray)
        
        @(Html.X().Window()
            .Title("Welcome to Ext.NET 2.0")
            .Height(215)
            .Width(350)
            .BodyPadding(5)
            .DefaultButton("0")
            .Layout("AnchorLayout")
            .DefaultAnchor("100%")
            .Items(items => items.Add(Html.X()
                .TextArea()
                .EmptyText(">> Enter a Message Here <<")
                .FieldLabel("Test Message")
                .Height(85))
            )
            .Buttons(buttons => buttons.Add(Html.X()
                .Button()
                .Text("Submit")
                .Icon(Icon.Accept)
                .DirectEvents(directEvents => directEvents.Click.Url = "/DirectEventMessage/")
            )
        ))
    </body>
    </html>
    Controller:

    public class DirectEventExampleController : Controller
    {
        //
        // GET: /DirectEventExample/
        public ActionResult Index()
        {
            return View();
        }
    }
    That is all fine and it renders the same message box that your NuGet package installs by default.

    But when I call the direct event, that is when I run into trouble; I can't seem to create the Notify on the server side. First I tried to create a simple strongly typed View which just registered the resource manager again and try to find a @Html.X().Msg or Notify or similar but couldn't see one. So then I tried to create a response script inside the controller action:

    public class DirectEventMessageController : Controller
    {
        //
        // GET: /DirectEventMessage/
    
        public ActionResult Index(string message)
        {
            var config = new NotificationConfig
            {
                Icon = Icon.Accept,
                Title = "Working",
                Html = message
            };
    
            string script = X.Msg.Notify(config).ToScript();
    
            return new AjaxResult(script);
        }
    }
    If I run the above, I get a run time error saying
    Object reference not set to an instance of an object
    at Ext.Net.Notification.ToScript() +47

    This is caused by my instance of Notification doing a .ToScript(); it is looking for a resource manager but can't find one, even if I have a View with just this:

    @{
        Layout = null;
    }
    
    @Html.X().ResourceManager()
    Admittedly what I am trying feels wrong; I shouldn't be recreating another resource manager on the Direct Event click as there is already one on the page, but I guess I need to create a dummy/proxy one just so a script can be created and other server side code relying on it (to use things like RegisterIcon etc) will work... Trying to create it inside the Controller didn't work either (unless I didn't instantiate it properly)

    Of course, I could get around this altogether by not making a Direct Event just to show the message the user typed and keeping it all on the client as it should be, but I am just trying to show the example that comes with NuGet as an MVC/Razor example. Also perhaps more realistically in the future I will want to create more complex layouts, grids, tabs, trees etc all on the fly using Direct Events or Direct Methods so it would still be useful to know where I am going wrong.

    I am probably missing the obvious :)
    Last edited by Daniil; May 14, 2012 at 7:48 AM. Reason: [CLOSED]
  2. #2
    Thank for the report
    It was a bug in Notification code.

    ResourceManager presence (or absence) in the view doesn't affect on controller action code. Action and View are not related between each other
    Therefore ResourceManager is required for controls in the view only. If you create widgets in the controller action (dynamic controls without view) then resource manager will be created dynamically (when you call Render or ToScript)

    By the way, AjaxResult can collect script automatically. You can call Show method for Notification and return AjaxResult
    View
    <%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<dynamic>" %>
    <%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>
    
    
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
     
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head id="Head1" runat="server">
        <title>Ext.Net.MVC v2 Example</title>
    </head>
    <body>
        <ext:ResourceManager ID="ResourceManager1" runat="server" />
        
        <ext:Button runat="server" Text="Show notification">
            <DirectEvents>
                <Click Url="/Examples/Notification" />
            </DirectEvents>
        </ext:Button>
    
    
        <ext:Label ID="Label1" runat="server" />
    </body>
    </html>

    Action

    public ActionResult Notification()
            {
                var config = new NotificationConfig
                {
                    Icon = Icon.ApplicationStop,
                    Title = "Working",
                    Html = "Message"
                };
    
    
                X.Msg.Notify(config).Show();
                X.GetCmp<Label>("Label1").Text = DateTime.Now.ToString();
    
    
                return new AjaxResult();
            }
    Last edited by Daniil; May 11, 2012 at 3:56 PM.
  3. #3
    Many thanks for such a quick response and fix.

    Just to clarify and check: does this look like best practice to you? I've put the Notify direct event handler as another action on the same controller (rather than creating a completely separate controller). More importantly, wanted to check the way I passed the message across was good practice (i.e. via the ExtraParam and setting the value by running some script to get values from something else on the page)?

    View:

    @{
        Layout = null;
    }
    <!DOCTYPE html>
    <html>
    <head>
        <title>DirectEventExample</title>
    </head>
    <body>
        @Html.X().ResourceManager().Theme(Theme.Gray)
        
        @(Html.X().Window()
            .Title("Welcome to Ext.NET 2.0")
            .Height(215)
            .Width(350)
            .BodyPadding(5)
            .DefaultButton("0")
            .Layout("AnchorLayout")
            .DefaultAnchor("100%")
            .Items(items => items.Add(Html.X()
                .TextArea()
                .ID("MessageTextArea")
                .EmptyText(">> Enter a Message Here <<")
                .FieldLabel("Test Message")
                .Height(85))
            )
            .Buttons(buttons => buttons.Add(Html.X()
                .Button()
                .Text("Submit")
                .Icon(Icon.Accept)
                .DirectEvents(directEvents =>
                {
                    directEvents.Click.Url = "/DirectEventExample/Notify";
                    directEvents.Click.ExtraParams.Add(new Parameter
                    {
                        Name  = "message",
                        Value = "App.MessageTextArea.getValue()",
                        Mode  = ParameterMode.Raw
                    });
                })
            )
        ))
    </body>
    </html>
    Controller:

    public class DirectEventExampleController : Controller
    {
        //
        // GET: /DirectEventExample/
        public ActionResult Index()
        {
            return View();
        }
    
        // GET: /DirectEventExample/Notify/
        public ActionResult Notify(string message)
        {
            var config = new NotificationConfig
            {
                Icon = Icon.Accept,
                Title = "Working",
                Html = message
            };
    
            X.Msg.Notify(config).Show();
    
            return new AjaxResult();
        }
    }
    For more complex scenarios, e.g. passing more than one parameter, I'd have to add separate Extra Params parameters and for each one the value may be obtained by calling similar client side code, right?

    Thanks!
    Last edited by anup; May 11, 2012 at 5:35 PM. Reason: Changed the way Notify() returned AjaxResult (i.e. no need to manually set ToScript())
  4. #4
    We are not sure that understand the questions well. But will try to answer.

    Quote Originally Posted by anup View Post
    Just to clarify and check: does this look like best practice to you? I've put the Notify direct event handler as another action on the same controller (rather than creating a completely separate controller).
    It's hard to say definitely. I would not create a separate controller if it is not really required. Though separate controllers are helpful to separate logic. For example, I would define a separate controller to manage data of Stores.


    Quote Originally Posted by anup View Post
    Just to clarify and check: does this look like best practice to you? More importantly, wanted to check the way I passed the message across was good practice (i.e. via the ExtraParam and setting the value by running some script to get values from something else on the page)?
    Well, I can't see any better way to pass parameter to a controller action in DirectEvent case. Can you see any?

    Quote Originally Posted by anup View Post
    For more complex scenarios, e.g. passing more than one parameter, I'd have to add separate Extra Params parameters and for each one the value may be obtained by calling similar client side code, right?
    Yes, confirm.

    Please note that DirectEvent can also automatically submit form values. It might be helpful in many scenarios. In this case you can set up FormCollection parameter for a controller action.

    Also you can manage ExtraParams within DirectEvent Before and ResourceManager BeforeAjaxRequest handlers. There are two examples in this thread.
    http://forums.ext.net/showthread.php?12972
  5. #5
    Thanks for your response.

    Quote Originally Posted by Daniil View Post
    It's hard to say definitely. I would not create a separate controller if it is not really required. Though separate controllers are helpful to separate logic. For example, I would define a separate controller to manage data of Stores.
    Yes, that makes perfect sense. For stores in particular it creates excellent reuse and is easier to unit test etc too. In this particular example, it seems okay to keep it in the same controller as it is quite specific to this example page.

    Quote Originally Posted by Daniil View Post
    Well, I can't see any better way to pass parameter to a controller action in DirectEvent case. Can you see any?
    Another way perhaps is not quite with a Direct Event but a client side click listener that would then call a direct event/direct method manually and just create the URL with appropriate querystings, perhaps. Seems more fiddly, but sometimes may be useful. (But then again, if we are creating the direct request manually, could still populate the extra params; probably cleaner!)

    Quote Originally Posted by Daniil View Post
    Please note that DirectEvent can also automatically submit form values. It might be helpful in many scenarios. In this case you can set up FormCollection parameter for a controller action.

    Also you can manage ExtraParams within DirectEvent Before and ResourceManager BeforeAjaxRequest handlers. There are two examples in this thread.
    http://forums.ext.net/showthread.php?12972
    Thanks for the tip...!
  6. #6
    You can use DirectMethod to call controller's action if you want to manage params on the fly
    <Click Handler="Ext.net.DirectMethod.request({
                    url : '/Examples/Notification',
                    cleanRequest: true,
                    params       : {
                        message : 'Message'
                    }
                });" />
    P.S. We will change DirectMethod/DirectRequest to automatically use 'cleanRequest' under MVC
  7. #7
    Thanks for that. I was thinking that is how it would probably be done; in fact, I do that for our production code; its incredibly powerful as we normally have to generate a lot of complex UI on the fly during various direct requests and quite often from Ext JS code. I was just thinking it might be a bit more fiddly for the very small example I was demonstrating here. But it is good to be in one thread here for future reference :)

    Thanks for the tip on clean request too.

Similar Threads

  1. Razor & ResourceManager
    By darrenarbell in forum 2.x Help
    Replies: 2
    Last Post: Apr 27, 2012, 7:40 PM
  2. X.Msg.Notify show with delay ?
    By xtremexploit in forum 1.x Help
    Replies: 2
    Last Post: Feb 17, 2012, 10:00 PM
  3. Ext.Msg.notify
    By threewonders in forum 1.x Help
    Replies: 4
    Last Post: Mar 10, 2011, 6:00 PM
  4. [CLOSED] [1.0] X.Msg.Notify bug?
    By alliedwallet.com in forum 1.x Legacy Premium Help
    Replies: 3
    Last Post: Oct 29, 2010, 5:43 PM
  5. X.Msg.Notify with DirectEvent
    By csharpdev in forum 1.x Help
    Replies: 1
    Last Post: Oct 28, 2010, 2:21 PM

Posting Permissions