Creating a master/detail page with modal pop-up and JSON

This recipe is going to be a slight twist on the previous one. Rather than force-feeding our details into the top of our page using a partial view, we will instead display the details in a modal pop-up using JSON and a jQuery plug-in called nyroModal. You will find that two things occur with this method, which are a bit different from our last task. First, the time it takes to display the details after clicking on them is considerably less, as the package of data that is passed is much smaller. Also, there is less processing to be performed on the server-side as the formatting of the data occurs on the client-side, which also adds to the improved performance. Second, the user experience is greatly improved as the list of product data doesn't get pushed and pulled all over the place, this is because the details are cleared from and displayed in the page.

Getting ready

As with the other recipes in this chapter, we need to have some data to work with in order to be able to implement this recipe. We will be using our Product and ProductRepository classes as well as NBuilder. In addition to this, we will also be using the nyroModal jQuery plug-in, which can be downloaded from http://nyromodal.googlecode.com/files/nyroModal-1.6.2.zip (I am using 1.6.2 in this recipe).

How to do it...

  1. The first thing that we need to do is to bring in our Product and ProductRepository classes from the previous recipe.
  2. Then we need to add a reference to NBuilder in the dependencies folder.
  3. Then we need to add the downloaded nyroModal javascript file to our Scripts directory. Also, we have to add the nyroModal.css file to our Content directory.
  4. Now we need to open up the Views/Shared/Site.Master file, so that we can add some script references in. I am adding a reference to the latest jQuery, you might choose to use the jQuery that comes with the MVC template. Then we need to add a reference to jquery.nyroModal-1.6.2.js (the latest version of nyroModal at the time of writing). We also need to add a reference to nyroModal.css.

    Views/Shared/Site.Master:

    <head runat="server">
    <title><asp:ContentPlaceHolder ID="TitleContent" runat="server" /></title>
    <script src=http://code.jquery.com/jquery-1.4.2.min.js type="text/javascript"></script>
    <script src="../../Scripts/jquery.nyroModal-1.6.2.js" type="text/javascript"></script>
    <link href="../../Content/nyroModal.css" rel="stylesheet" type="text/css" />
    <link href="../../Content/Site.css" rel="stylesheet" type="text/css" />
    <asp:ContentPlaceHolder ID="head" runat="server" />
    </head>
    
  5. If you started off with a copy of the previous recipe, then you should already have a Product and ProductRepository class. You should also have a Products.aspx page that iterates over a collection of products for display on the page (if not, grab a copy of those files). In the Products.aspx page, remove the existing JavaScript that writes the product details into the top of the Products page.
  6. We should also have the ProductDetail.aspx and GetProductDetail.ascx files. With these in place and the previous JavaScript removed, you should have a working products page that shows the details on another page.
  7. Now we can start to build up some JavaScript to show our modal window. This script will hide the details div that we used previously, so that when we load data into it in the page, they will not show inline with the rest of the page. It will then set the position to be absolute on the details div, so that when we load data into the details div, hidden or not, it won't shift the contents of the rest of the page.

    Views/Home/Products.aspx

    <script>
    $(function () {
    $("#detail").css('visibility', 'hidden'),
    $("#detail").css('position', 'absolute'),
    });
    </script>
    
  8. Next, we will spotweld a bit of JavaScript onto all of our product links. We are going to use a jQuery selector to iterate over all of the links with a class of list-item. For each link we find, we will override the click event of the link.

    Views/Home/Products.aspx:

    $('a.list-item')
    .click(function () {
    ...
    });
    
  9. Now we can add the real functionality inside of our new click event handler. We need to always make sure that the details div is empty before we try to add something to it. We can do this by selecting the details div by its ID, detail. Then we will access the html property of that div and clear it out.

    Views/Home/Products.aspx:

    $("#detail").html(''),
    
  10. Now that our details div is empty, we can focus on adding the appropriate product details into it. We will do this by posting a request to our GetProductDetail action in the home controller. However, instead of using the GetProductDetail.ascx partial view, we want to return some JSON directly to the calling JavaScript. To do this, we will need to add a new action to our home controller. This action will simply load the appropriate product and serialize it to JSON using a JsonResult. Because we already have an action named GetProductDetail that takes in a product ID, we have two options—we can either add an unused parameter to our action or we can alter the name of the action, allowing us to create a new method signature. I am opting for a slightly different name by prepending an underscore.

    Controllers/HomeController.cs:

    [HttpPost]
    public JsonResult _GetProductDetail(int id)
    {
    Product p = new ProductRepository().GetProductByID(id);
    return Json(p);
    }
    
  11. With this new action in place, we can write some JavaScript to communicate with our new _GetProductDetail action. In this case, we will use jQuery to post a request to our _GetProductDetail action passing along the product ID. This action will then serialize a Product object and pass it back to us. To do something with this data, we will also write a callback function that takes in a data parameter.

    Views/Home/Products.aspx:

    .click(function () {
    $("#detail").html(''),
    $.post('_GetProductDetail', { id: this.id },
    function(data) {
    });
    });
    
  12. The next thing for us to do is handle the callback and process the data that is passed back to us. For this, we will write a couple of new functions to handle formatting and showing our data. We need one function to handle the pushing formatted data into the details div. We will need another one to handle the formatting of each of the properties of the Product class.

    Views/Home/Products.aspx:

    $(function () {
    ...
    .click(function () {
    $("#detail").html(''),
    $.post('_GetProductDetail', { id: this.id },
    function (data) {
    showProduct(data);
    });
    return false;
    });
    });
    function showProduct(data) {
    $("#detail").html(
    formatLine('Id',data.ProductId) +
    formatLine('Name',data.Name) +
    formatLine('Price',data.Price) +
    formatLine('SKU',data.Sku) +
    formatLine('Created',data.CreateDate) +
    formatLine('In Stock',data.InStock) +
    formatLine('Desc',data.Description)
    );
    }
    function formatLine(label, value) {
    return '<div class="display-label">' + label + ':</div><div>' + value + '</div>';
    }
    
  13. With all of this completed, we can now run our Products page. You will see a listing of products, all of which you can click on. Clicking on a link will make a request to get the appropriate product. That product will then be serialized and returned to the client. The product will then be formatted and pushed into our details div, but nothing will show on the page! In order to get our product details to show on the page, we need to hook up the nyroModal window. This is one line of code calling the nyroModalManual function with some display settings right after we call the showProduct function that we just created.

    Views/Home/Products.aspx:

    $.nyroModalManual({ url: '#detail', minHeight: 150, minWidth: 300, width: 300, height: 150 });
    
  14. To finish off this recipe, we need to cancel the navigation request that clicking the link causes to happen. If we don't do this, then we will click on the link, get the details, display the modal window, and then refresh the page as we navigate to the ProductDetails page!

    View/Home/Products.aspx:

    .click(function () {
    $("#detail").html(''),
    $.post('_GetProductDetail', { id: this.id }, function (data) {
    showProduct(data);
    $.nyroModalManual({ url: '#detail', minHeight: 150, minWidth: 300, width: 300, height: 150 });
    });
    return false;
    });
    
  15. Now you can hit F5 and run the site. Clicking on a product should show the product details in a modal pop-up. By commenting out the JavaScript, you can simulate what a client with their JavaScript disabled might see. Specifically, you should be able to click on a product and navigate to the Product Details page.

How it works...

Describing how this process works outside of code is much easier to understand. When the page has loaded, a JavaScript (jQuery) runs and overrides the OnClick event of the appropriate links on the page. In the new click event handler, we then make a request to get some serialized data from our home controller by calling the _GetProductDetail action. Once this data has been returned to the client, we format it and store it in a div. We then call our nyroModal pop-up and tell it to display the data stored in the details div.

See also

  • Master/detail page with inline details via jQuery and a partial view
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset