News

 

This is a part of EXT JS Tutorial

In this part of the Ext JS tutorial I would like to show the Ext.MessageBox class. In the first part, where I showed how to add Ext library into MVC project, I have put there a Ext.Msg.alert to test the installation. Actually the Ext.Msg it is an alias for Ext.MessageBox class. Both can be used interchangeably.

Ext.Msg.prompt

Ok, so let’s create a first dialog to see how it’s look like. Let it be a Ext.Msg.prompt.
This method displays a message box prompting to user for some text.

        Ext.onReady(function()

        {

            Ext.Msg.prompt("Enter your name", "Your name");

        });


And the result on the screen










As you can see, this one line of code creates a window with three buttons and a field for input text.
The prompt method takes six arguments, but only first two are required. The first it is a window title, second this is a message inside the body as you can see above.

Notice that, even you enter your name in this box and press Ok, nothing will happen. First you must specify the callback function (parameter third). Callback this is a function which is called when a specific event occur(in this case, click on one of the buttons). This callback function takes two arguments: first determine the button, which user clicked and second the result, what he’s written in the input field.

Forth is scope of callback function. For more info look here. Next parameter takes the true/false value and is responsible for multiline input. Default is singleline set. The last parameter determine the default value in the input field.

About onReady function I have written here
From this moment I won’t mention about this function again. I hope you will remember that every time when you want to refer to element in DOM hierarchy, this element must be visible. This ensures the onReady function.

Let’s see the parameters in action.

            Ext.Msg.prompt('Enter your name', 'Your name', function(btn, txt)

            {

                if (btn == "ok" && txt.length > 0)

                {

                    Ext.Msg.alert('Result', 'You have set the name to: ' + txt);

                }

            }, this, true, 'Lukasz Kurylo');


And the result












When you click the Ok button you will see the alert method from callback function.









And the result after page load and clicked the Ok button.

Ext.Msg.confirm

This method you can use when user have to choose between confirming or rejecting some action.
Method takes four arguments, which are identical in sequence and significance, as in the Ext.Msg.prompt.
Using the callback function it is possible to distinguish which button was pressed.

Simple example

            Ext.Msg.confirm("Confirmation", "Do you want to create a new account?", function(btn)

            {

                if (btn == 'yes')

                {

                    Ext.Msg.alert("Result", "New account created successfully");

                } else

                {

                    Ext.Msg.alert("Result", "Abort");

                }

            }, this);


Result








Depending on the selected button, the appropriate window will be displayed:







or









Ext.Msg.progress

This is a three-argument method which shows a progress bar that user cannot close. You must use Ext.Msg.updateProgress method to update the progress bar and close it when the process is complete.

Example

            var i = 0;

            Ext.Msg.progress("Progress example", "some message", "progress text");

           

            var x = window.setInterval(function()

            {

                i = i + 0.01;

               

                Ext.Msg.updateProgress(i);

               

                if (i >= 1)

                {

                    window.clearInterval(x);

                    Ext.Msg.hide();

                }

            }, 50);


Using the setInterval method you can update the variable which is passed to the updateProgress. When the end point will be achieved, you must remember to hide the progress bar manually.
Notice that, the expression in if clause must be set as greater or equal (not only equal), otherwise the dialog won’t be hide.
The second parameter passed to setInterval method determines in milliseconds how often the progress bar is updated.

Result







Config object/JSON

Imagine that, a method has a lot of parameters, but you want set up only a few of them. Of course you could pass them all, one by one in required order and these which you are not interested in leave blank, but what if a method has ten or twenty these parameters? And you have to create a few instances of it, every time passing the parameters? Ext provides a nice mechanism, which is a config object. This object is constructed by using JSON to describe all the of the arguments. JSON this is JavaScript Object Notation which is similar to CSS. Using JSON it hasn’t matter, what is the order of arguments passed in this config object. You can very easy add new or delete any of these arguments. As I mentioned above, syntax is similar to CSS. You can see it under this link. Or in the example below.

Ext.Msg.show

This method has only one parameter, which is a config object about which I mentioned above. Let’s look at example.

             Ext.Msg.show({

                title: 'Gender',

                msg: 'Exter your gender',

                width: 300,

                buttons: Ext.MessageBox.OKCANCEL,

                multiline: false,

                icon: Ext.MessageBox.INFO,

                prompt: true,

                fn: function(btn, txt)

                {

                    if (btn == 'ok')

                    {

                        //do sth

                    }

                }

            });


Result










As you can read in documentation: “All display functions (e.g. prompt, alert, etc.) on MessageBox call this function internally, although those calls are basic shortcuts and do not support all of the config options allowed here.”

Ext.Msg.wait

The last dialog which I want to show is Ext.Msg.wait. It can be use when you waiting for completion of certain process and it blocks the user interaction during it. This method takes three arguments:

           - message – the message in body
           - title –the title bar
           - config – the object in JSON format

Example

            Ext.select('.button').on('click', function()

            {

                var wait = Ext.Msg.wait('Installation..', 'Setup');

                var sec = 2;

                setTimeout(actionFunc, 1000);

                function actionFunc()

                {

                    if (sec < 10)

                    {

                        wait.updateText('progress: ' + (++sec)*10 + '%');

                        setTimeout(actionFunc, 1000);

                    } else

                    {

                        wait.hide();

                    }

                }

            });


In this example I have used a Ext.select. In this code, it selects button added manually to the page with css class attribute ‘button’ and fire the specified funcion when the button is clicked.
Ext.select will be cover in one of the next parts of these articles.

To use this example you must must add somewhere in the body this line:

            <input type="button" value="Click Me" class="button">











Summary

In this part I have shown the all major dialogs with examples how to use them. I have explained what it is JSON and the concept of config object which is using by most elements present in the Ext JS library.

 

Ext JS is a very powerful javascript UI library which allows you to create a rich internet applications. Ext JS is very easy in use, in learn and has very intuitive API. Supports all major web browsers (IE, Opera, Firefox, Safari).

 

Starting with this post I would like to initiate a series of articles explaining the nuances of how  to use a basics Ext aspects in web developments with ASP.NET MVC and how to create a great-looking user interfaces in web  apps.

 

Links to all related articles to this tutorial I will be posting below 


- Integration ExtJS and ASP.NET MVC

- Interaction with user. Dialogs.

- Forms with EXT JS new

And remember. Here is very good documentation to Ext JS library created by their authors. If you don’t understand something (e.g. one of the config option) that appears in one of the tutorials, the first place where should you go is the link above.

 

For more powerful examples showing how to use a Ext JS library in a various of situations, look at the official Sample & Demos section.

 

Official forum is located here.

 

I also assume that you know what it is class, method, event and property (since this tutorial is intended for .NET programmers).

 

This is a part of EXT JS Tutorial


To successfully carry out everything that has been described in this article you need:

 

 

-Ext JS library – link

-ASP.NET MVC library – link

-.NET Framework 3.5 SP1 – link

 

 

If you haven’t installed Service Pack  for .NET Framework 3.5 and/or MVC library, do it in this order.

 

At the beginning  we have to create a new ASP.NET MVC Application. Go to the File->New Project and select ASP.NET MVC Web Application. Call it e.g. ExtJSFirstApp like shown in the picture below

 

 

 



















If you have Visual Studio 2008 Professional or higher, you will be asked about creating  a project for unit testing. We won’t be writing tests for javascript applications (at least for now), so select No.

 

Nest step is to add a Ext JS library to the Scripts directory in Solution Explorer. Right click on this directory and select Open folder in Windows Explorer. Now unpack the ext-3.0.0.zip archive there and rename it to ext. You can remove (or move somewhere) the examples and docs directories, because we don’t need them in the project. By the way you can remove the rest of *.js files (jquery and MicrosoftAjax library). We don’t need them too. We will use all the stuff which provide the Ext JS library only.

 

 

When you unpack the archive, in Visual Studio probably you won’t see the ext directory even when you press the refresh button. So click the Show All Files button and you will see the ext directory:

 

 

 


























Now press on the ext directory right mouse button and select Include In Project. On the other *.js files select Remove and click the Show All Files button again.

 

Another step is to place links to relevant *.js files in the master page. If you put the library in Script directory, in master page you should put :

 

    <link href="../../Scripts/ext/resources/css/ext-all.css" type="text/css" rel="Stylesheet" />

    <script type="text/javascript" src="../../Scripts/ext/adapter/ext/ext-base.js"></script>

    <script type="text/javascript" src="../../Scripts/ext/ext-all.js"></script>

    <script type="text/javascript" src="../../Scripts/ext/ext-all-debug.js"></script>

 

The ext-all.css is the main css file for Ext.

The ext-base.js is a default adapter for Ext. Other adapters allow you to use additional javascript libraries, like jQuery or YUI or Prototype.

The ext-all.js or ext-all-debug.js you can be used interchangeably in development. In production you should use only the non-debug version. These files conytains the primary Ext library.

 

 

Visual Studio javascript intellisense

 

In Visual Studio 2008 there is included support for javascript intellisense. When you put a *.js file in your page and click the Ctrl+Shift+J shortcut, you will update the intellisense and from this moment you can use it in your code:

 

 

 














If you have these script lines in the master page and want to write javascript code in the view pages (also do not want to add them again in views), you can set a references for them, which looks like that:

 

    ///<reference path="ext/adapter/ext/ext-base.js" />

    ///<reference path="ext/ext-all.js" />

    ///<reference path="ext/ext-all-debug.js" />

 

 

Now, after Ctrl+Shift+J combination, intellisense is available in this file.

Notice that, this trick with ///references you can also use in *.js files.

 

Except intellisense in VS2008 there is also available stuff to show a documentation for javascript classes/functions which is held in *.js files with vsdoc phrase in the name. I know nothing about vsdoc for Ext JS library, but maybe someone create some in the future. So remember about it. Up to this day, I know only about documentation for jQuery library. At this point it is worth to add that, to use this vsdoc  you need a hotfix for VS2008. For more info look here

 

 

Testing

 

 So it’s the time to test if everything works properly

 

In the <head></head> section on the master page add this code with the immortal “Hello world!” phrase

 

    <script type="text/javascript">

        Ext.onReady(function()

        {

            Ext.Msg.alert("Alert", "Hello world!");

        });

    </script>

 

 

The onReady function is automatically called when the DOM is fully loaded. It ensures that any page elements that you may want to reference in your functions will be available when the script runs.

 

The result should look like:

 

 






You may wonder why this button is around decorated with the white frames. Guilty  is the default css file(exactly the css type selector for table and descendant selector table td)which comes with MVC. If you remove the file (or these selectors), the result looks like below

 

 

 





 

Summary


This is all in the first part of Ext JS Tutorial. I have shown how to integrate Ext JS with ASP.NET MVC application and how you can use a intellisense to javascript in Visual Studio 2008.

Instead of doing all the steps described in this article, you can also download the finished project which contains all the files here (click the blue button called "Pobierz plik").


 

Create a rss or atom feed is very simple in asp.net mvc. In V1.0 there isn’t a build-in mechanism to work with feeds, however we can very quickly build our own. All we have to do is create a xml structure accordance with their specification and new ActionResult derived class to handle the result.  But let’s start form beginning.

 

The first of all, we need to create a new MVC project and call it e.g. RssFeed. The data for feeds will be taken from database, so we have to build model. Let’s create a new database called SampleDB with one table Article, like shown below and add some records for testing.

 

 









Next step is to create a DataContext class. Select the Model catalog from Soluction Explorer,  add a new item called LINQ to SQL Classes with name SampleDB.dbml and drag from Server Explorer  the Article table to it.

 

 








The data taken from database we need to handle somewhere, so we can create a two classes. One for channel data, like title or description, and second one for information described ours articles:

 

    public class Feed

    {  

        //channel informations

        public string Title { set; get; }

        public string Description { set; get; }

        public string Link { set; get; }

        public string Author { set; get; }

        public List<FeedItem> Items { set; get; }

        public DateTime Updated { set; get; }

    }

 

    public class FeedItem

    {  

        //feed informations

        public string Title { set; get; }

        public string Description { set; get; }

        public DateTime PublicDate { set; get; }

        public Guid Id { set; get; }

    }

 

We will fill these classes in the controller, so add a new controller called FeedController. In this class we create a action method(s) to handle the RSS and/or Atom feeds with the data provided in the ActionResult constructor.

 

    public class FeedController : Controller

    {

        SampleDBDataContext db = new SampleDBDataContext();

 

        [NonAction]

        private Feed GetData()

        {

            Feed rss = new Feed()

            {

                Description = "Site description",

                Link = "link",

                Title = "Simple rss/atom feed",

                Author = "Author name",

                Updated = DateTime.Now

            };

 

            //get articles

            var articles = from a in db.Articles

                           select new FeedItem

                           {

                               PublicDate = a.PublicDate,

                               Title = a.Title,

                               Description = a.Content,

                               Id = a.ArticleId                            

                           };

 

            rss.Items = articles.ToList();

 

            return rss;

        }

 

        public ActionResult RSS()

        {

            Feed rss = GetData();

 

            return new RssResult(rss);

        }

 

        public ActionResult Atom()

        {

            Feed atom = GetData();

 

            return new AtomResult(atom);

        }

    }

 

 

At the end we need to create a new ActionResult derived classes. One for Atom and one for RSS.  In these classes we will use a LINQ to XML to build a xml file structure with the data provided in constructor and send the result to the user in ExecuteResult method.

 

RSS feed

 

    public class RssResult : ActionResult

    {

        public Feed RssFeeds

        {

            set;

            get;

        }

 

        public RssResult(Feed f)

        {

            RssFeeds = f;

        }

 

        private XDocument CreateXmlDoc()

        {

            //create the rss xml structure

            XDocument doc = new XDocument(

                new XDeclaration("1.0", "UTF-8", ""),

                new XElement("rss",

                    new XAttribute("version", "2.0"),

                    new XElement("channel",

                        new XElement("title", RssFeeds.Title),

                        new XElement("link", RssFeeds.Link),

                        new XElement("description", RssFeeds.Description)

                        )));

 

            foreach (FeedItem item in RssFeeds.Items)

            {

                XElement i = new XElement("item",

                      new XElement("title", HttpUtility.HtmlEncode(item.Title)),

                      new XElement("link""http://localhost:3563/Article/" + item.Id),

                      new XElement("pubDate", item.PublicDate),

                      new XElement("description", HttpUtility.HtmlEncode(item.Description)));

 

                doc.Element("rss")

                    .Element("channel")

                    .Add(i);

            }

 

            return doc;

        }

 

        public override void ExecuteResult(ControllerContext context)

        {

            context.HttpContext.Response.ContentType = "application/rss+xml";

 

            using (System.Xml.XmlWriter writer =

                System.Xml.XmlWriter.Create(context.HttpContext.Response.Output))

            {

                CreateXmlDoc().Save(writer);

            }

 

        }

    }

 

Atom feed


    public class AtomResult : ActionResult

    {

        public Feed AtomFeeds

        {

            set;

            get;

        }

 

        public AtomResult(Feed f)

        {

            AtomFeeds = f;

        }

 

        private XDocument CreateXmlDoc()

        {

 

            XNamespace ns = "http://www.w3.org/2005/Atom";

 

            XDocument doc = new XDocument(

                new XDeclaration("1.0", "UTF-8", ""),

                new XElement(ns + "feed",

                    new XElement(ns + "title", AtomFeeds.Title),

                    new XElement(ns + "link",

                        new XAttribute("href", "http://localhost:3563/Feed/Atom"),

                        new XAttribute("rel", "self")),

                    new XElement(ns + "updated",

                    //updated element must be in

                    //year-month-dayThour:minuts:secondsTimeZone format

                        AtomFeeds.Updated.ToString("yyyy-MM-dd\\THH:mm:ss%K")),

                    new XElement(ns + "author",

                        new XElement(ns + "name", AtomFeeds.Author)),

                    //id must be constant and unique for this channel

                    //if uri address is used, it hasn't be real

                    new XElement(ns + "id", "http://localhost:3563/MyAtomFeedId")

                    ));

 

            foreach (FeedItem item in AtomFeeds.Items)

            {

                XElement i = new XElement(ns + "entry",

                      new XElement(ns + "title", item.Title),

                      new XElement(ns + "link",

                          new XAttribute("href", "/Article/" + item.Id)),

                      //id must be constant and unique, otherwise each update

            //by feed readers will be duplicating all entries

                      new XElement(ns + "id", item.Id),

                      new XElement(ns + "updated",

                          item.PublicDate.ToString("yyyy-MM-dd\\THH:mm:ss%K")),

                      new XElement(ns + "summary",

                          item.Description.Length > 255 ?

                                item.Description.Substring(0, 254).Insert(254, "...")

                                    : item.Description));

 

                doc.Element(ns + "feed")

                    .Add(i);

            }

 

            return doc;

        }

 

        public override void ExecuteResult(ControllerContext context)

        {

            context.HttpContext.Response.ContentType = "application/atom+xml";

 

            using (System.Xml.XmlWriter writer =

                System.Xml.XmlWriter.Create(context.HttpContext.Response.Output))

            {

                CreateXmlDoc().Save(writer);

            }

        }

    }

 

At the really end we can add a link(s) for the channel(s) in the master page. Thanks to them, in the address bar e.g. in Firefox we will have a small icon which we can add subscribe to our channel.

Link for RSS:


<link href="<%= Url.Content("/Feed/RSS") %>" type="application/rss+xml" rel="alternate" title="RSS Feed" />


Link for Atom:


<link href="<%= Url.Content("/Feed/Atom") %>" type="application/atom+xml" rel="alternate" title="Atom Feed" />


Full source code for this example can be found here (click the blue button called "Pobierz plik").

 

Implementing a new ActionResult classes is only one of the ways to build this stuff. Other is using the standard View engine. It is possible to derive new class from ViewPage which is strongly-typed with model.

Beyond generation the xml file structure manually in our ActionResult classes, there is also possibility to use a build-in in .NET Framework classes: Atom10FeedFormatter and Rss20FeedFormatter. This keeps us from knowing the structure of xml files for each channel.

 

Examples for that are available here:

 

- Guy Burstein's blog post (strongly-typed ViewPage) 

- Rss20FeedFormatter class

- Atom10FeedRormatter class


A RSS/Atom documents structures are described here


http://cyber.law.harvard.edu/rss/rss.html

http://www.ietf.org/rfc/rfc4287.txt