Using jQuery Mobile and ASP.NET to Pass Data from one Page to another

Posted by: Mahesh Sabnis , on 10/7/2013, in Category jQuery and ASP.NET
Views: 47856
Abstract: jQuery Mobile is a lightweight JavaScript framework for developing cross-platform mobile/device Web applications. In this article, we will jQuery Mobile with ASP.NET to transfer data from one page to another

ASP.NET developers working on either Web Forms or ASP.NET MVC can integrate jQuery Mobile into their Web sites to create rich mobile Web apps. jQuery Mobile is a lightweight JavaScript framework for developing cross-platform mobile/device Web applications.

In mobile application development, you as a developer must think about how to utilize available space in the best possible manner. For this purpose sometimes the UI needs to be divided in separate pages. In such cases, you may need to transfer value(s) entered in one page, on the second page for the further processing.

 

Consider a scenario where the end user is asked to select the Product Category on Page 1 and based upon that, Page 2 displays products under that category. To get this done, values must be passed from page 1 to page 2. In jQuery Mobile, $.mobile object provides the changePage() method which accepts the page url as a first parameter and the values to be transferred as a second parameter using JSON based data. In this article, we will see, how values are passed from one page to another in an ASP.NET application.

Step 1: Open Visual Studio and create a new ASP.NET empty web application, name it as ‘ASPNET_Mobile_PassingValuesAcrossPages’. In this application, using the NuGet Package Manager, add the latest jQuery and jQuery Mobile libraries.

Step 2: To the project, add a new class file, name it as ‘ModelClasses.cs’ and add the following classes in it:

public class Category
{
    public int CategoryId { get; set; }
    public string CategoryName { get; set; }
}

public class Product
{
    public int ProductId { get; set; }
    public string ProductName { get; set; }
    public int Price { get; set; }
    public int CategoryId { get; set; }
}

public class CategoryDataStore : List<Category>
{
    public CategoryDataStore()
    {
        Add(new Category() { CategoryId = 1, CategoryName = "Food Items" });
        Add(new Category() { CategoryId = 2, CategoryName = "Home Appliances" });
        Add(new Category() { CategoryId = 3, CategoryName = "Electronics" });
        Add(new Category() { CategoryId = 4, CategoryName = "Wear" });
    }
}

public class CategoryDataSource
{
    public List<Category> GetCategories()
    {
        return new CategoryDataStore();
    }
}

public class ProductDataStore : List<Product>
{
    public ProductDataStore()
    {
        Add(new Product() { ProductId = 111, ProductName = "Apples", Price = 300, CategoryId = 1 });
        Add(new Product() { ProductId = 112, ProductName = "Date",   Price = 600, CategoryId = 1 });
        Add(new Product() { ProductId = 113, ProductName = "Fridge", Price = 34000, CategoryId = 2 });
        Add(new Product() { ProductId = 114, ProductName = "T.V.",   Price = 30000, CategoryId = 2 });
        Add(new Product() { ProductId = 115, ProductName = "Laptop", Price = 72000, CategoryId = 3 });
        Add(new Product() { ProductId = 116, ProductName = "Mobile", Price = 40000, CategoryId = 3 });
        Add(new Product() { ProductId = 117, ProductName = "T-Shirt", Price = 800, CategoryId = 4 });
        Add(new Product() { ProductId = 118, ProductName = "Jeans", Price = 700, CategoryId = 4 });
    }
}

public class ProductDataSource
{
    public List<Product> GetProductsByCategoryId(int catId)
    {
        var Products = from p in new ProductDataStore()
                       where p.CategoryId == catId
                       select p;

        return Products.ToList();
    }
}

The above code provides Category and Product entities with data stored in it. The Product is a child of the Category class.

Step 3: In the project, add a WEB API controller class with the following code:

public class CategoryProductController : ApiController
{
    CategoryDataSource objCatDs;
    ProductDataSource objPrdDs;

    public CategoryProductController()
    {
        objCatDs = new CategoryDataSource();
        objPrdDs = new ProductDataSource();
    }

    public IEnumerable<Category> Get()
    {
        return objCatDs.GetCategories();
    }

    public IEnumerable<Product> Get(int id)
    {
        return objPrdDs.GetProductsByCategoryId(id);
    }
}

Step 4: To define routing for the WEB API class, add a new Global Application Class (Global.asax) in the project and add the following code in the Application_Start method:

protected void Application_Start(object sender, EventArgs e)
{
    RouteTable.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { id = System.Web.Http.RouteParameter.Optional }
    );
}

Step 5: Add two HTML pages, name them as Page_Category.html and Page_Products.html.

Task 6: In both the HTML pages, add the jQuery and jQuery Mobile references:

<link href="Content/jquery.mobile.structure-1.3.1.min.css" rel="stylesheet" />
<link href="Content/jquery.mobile.theme-1.3.1.min.css" rel="stylesheet" />
<script src="Scripts/jquery-2.0.2.min.js"></script>
<script src="Scripts/jquery.mobile-1.3.1.min.js"></script>

Add the following HTML in the Page_Category.html page:

<div data-role="page" id="catpage">
    <div data-role="header">
        <h1>Select Category from List</h1>
    </div>
    <div data-role="content">
        <div>
            <select  id="lstcat" data-native-menu="false">
                <option>List of Categories.....</option>
            </select>
        </div>
        <br />
        <br />
        <input type="button" data-icon="search"
           value="Get Products"  data-inline="true" id="btngetproducts" />
    </div>
</div>

The above code defines a page using <div>  whose data-role attribute is set to page. This page contains a <select> for displaying list of categories in it and an <input> button with a click event on which the control will be transmitted to Page_Products.html page.

In the age_Category.html add the following script. The method loadlistview will make a call to WEB API and retrieve categories. These categories will be added into the <select> with id as lstcat. This method will be executed when the pageinit event is executed. On the click event of the button, the Category Value and Name will be passed to the Page_Products.html.

<script type="text/javascript">
$(document).on("pageinit", "#catpage", function () {

//Pass the data to the other Page
$("#btngetproducts").on('click', function () {
    var categoryId = $("#lstcat").val();
    var categoryName = $("#lstcat").find(":selected").text();
    $.mobile.changePage("Page_Products.html", { data: { "catid": categoryId ,"catname":categoryName}});
});


loadlistview();

///Function to load all categories
function loadlistview() {
   
    $.ajax({
        type: "GET",
        url: "/api/CategoryProduct",
        contentType: "application/json; charset=utf-8",
        dataType: "json"
    }).done(function (data) {
        //Convert JSON into Array
        var array = $.map(data, function (i, idx) {
            return [[i.CategoryId, i.CategoryName]];
        });

        //Add each Category Name in the ListView
        var res = "";
        $.each(array, function (idx, cat) {
            res += '<option value="' + cat[0] + '">' + cat[1] + '</option>';
        });
        $("#lstcat").append(res);
        $("#lstcat").trigger("change");

    }).fail(function (err) {
        alert("Error " + err.status);
    });
}
});
</script>

Just look at this piece of code:

$.mobile.changePage("Page_Products.html", { data: { "catid": categoryId ,"catname":categoryName}});

This code is responsible for passing the CategoryId and Name using JSON expression to the Page_Products.html.

Step 7: Open Page_Products.html and add the following HTML markup:

<div data-role="page" id="prodpage" data-add-back-btn="true">
<div data-role="header">
        <h1>Products in Category</h1>
        <span id="catName"></span>
    </div>
    
    <table style="border:double" data-role="table" id="tblprd">
        <thead>
            <tr>
                <td style='width:100px'>
                    ProductId
                </td>
                <td style='width:100px'>
                    ProductName
                </td>
                <td style='width:100px'>
                    Price
                </td>
            </tr>
        </thead>
        <tbody>
        </tbody>
    </table>
</div>

Here the <div> with id as prodpage is set with the attribute as data-role=page. The attribute data-add-back-btn=true, will add the BACK button on the page. On click of this button, we can move back to the Page_Category.html. This is the default style set in jQuery Mobile.

Now here the important thing is how to read values which are send from Page_Category.html in the URL, on the Page_Product.html page. Unlike ASP.NET, in jQuery there is no simple way to read the values passed from one page to another. To read these values we will create a readUrlHelper helper method. This method reads the URL and using JavaScript string functions, reads the Key/Value pairs passed from the Page_Category.html. On the Page_Products.html, add this method using <script> inside the page created using <div> with id as prodpage.

//This helper function will read the URL as
//string and provides values for parameters
//in the URL
function readUrlHelper(pageurl, queryParamName)
{
    var queryParamValue = "";

    //Get the Total URL Length
    var stringLength = pageurl.length;

    //Get the Index of ? in URL
    var indexOfQM = pageurl.indexOf("?");

    //Get the Lenght of the String after ?
    var stringAfterQM = stringLength - indexofQM;

    //Get the remaining string after ?
    var strBeforeQM = pageurl.substr(indexofQM + 1, stringAfterQM);

    //Split the remaining String based upon & sign
    var data = strBeforeQM.split("&");

    //Iterate through the array of strings after split
    $.each(data, function (idx, val) {
        //Split the string based upon = sign
        var queryExpression = val.split("=");

        if (queryExpression[0] == queryParamName)
        {
            queryParamValue = queryExpression[1];
            //If the Query String has Data in Concatination then replace the
            //'+' by blank space ' '
            queryParamValue =  queryParamValue.replace('+', ' ');
        }
    });

    return queryParamValue

}

To retrieve the Products based upon the CategoryId, add a new method loadproducts inside the prodpage. This methods makes a call to the WEB API service and passes the CategoryId. This method also makes a call to the generatetable helper method to generate HTML table to display products in it based upon the JSON data received by the loadproducts method:

//Method to make call to WEB API and retrieve
//Products based upon the CategoryId.
function loadproducts(id) {

    $.ajax({
        type: "GET",
        url: "/api/CategoryProduct/" + id,
        contentType: "application/json; charset=utf-8",
        dataType: "json"
    }).done(function (data) {
        generatetable(data);
    }).fail(function (err) { });
}
//Method to generate HTML table rows from the JSON data
function generatetable(data)
{

    //Convert JSON into Array
    var array = $.map(data, function (i, idx) {
        return [[i.ProductId, i.ProductName,i.Price]];
    });
    var tblbody = $("#tblprd > tbody");

    var tblhtml = "";
    //Generate the Table for each Row
    for (var i = 0; i < array.length; i++) {
        tblhtml = tblhtml + "<tr>";
        for (var j = 0; j < array[i].length; j++) {
        tblhtml = tblhtml + "<td style='width:100px'>" + array[i][j] + "</td>";
       }
        tblhtml = tblhtml + "</tr>";
    }

    tblbody.append(tblhtml);
    $("#tblprd").table("refresh");

}

Now inside the prodpage subscribe to the pageshow event which will make a call to the readUrlHelper method and loadproducts method

var catId;
$("#prodpage").on("pageshow", function (e) {
    var pgurl = $("#prodpage").attr("data-url");
    //Read the value for catid passed from the Page_Category.html
    catId = readUrlHelper(pgurl, "catid");
    //Read the value for catname passed from the Page_Category.html
   var catName = readUrlHelper(pgurl,"catname");

   $("#catName").text(catName);

   loadproducts(catId);

});

The above code read the CategoryId and CategoryName passed by the Page_Category.html and based upon it the Products are displayed on the page.

Make the Page_Category.html as a startup page and run the application (IE9, FireFox or Chrome) or in Opera Mobile Emulaor.

On Page-Category.html select Categories as below:

jquery-mob-categories

When you click on Get Products , you will be navigated to the Page_Products.html with the following url:

http://localhost:5506/Page_Products.html?catid=1&catname=Food+Items

The URL contains key and value for CategoryId (catid=1) and CategoryName (catname=Food+Items)

In the Page_Products.html, the readUrlHelper method will read CategoryId and CategoryName and based upon this data, Products will be displayed as below:

jquery-transfer- values

Conclusion: In a Mobile application it is very important for the developer to manage the UI and take care of data communication across these pages. If the data passed is complex (more than one key/value pair) then the URL must be read very carefully. In this article, we saw how we can use jQuery Mobile and ASP.NET to transfer values from one page to another.

This article has been editorially reviewed by Suprotim Agarwal.

Absolutely Awesome Book on C# and .NET

C# and .NET have been around for a very long time, but their constant growth means there’s always more to learn.

We at DotNetCurry are very excited to announce The Absolutely Awesome Book on C# and .NET. This is a 500 pages concise technical eBook available in PDF, ePub (iPad), and Mobi (Kindle).

Organized around concepts, this Book aims to provide a concise, yet solid foundation in C# and .NET, covering C# 6.0, C# 7.0 and .NET Core, with chapters on the latest .NET Core 3.0, .NET Standard and C# 8.0 (final release) too. Use these concepts to deepen your existing knowledge of C# and .NET, to have a solid grasp of the latest in C# and .NET OR to crack your next .NET Interview.

Click here to Explore the Table of Contents or Download Sample Chapters!

What Others Are Reading!
Was this article worth reading? Share it with fellow developers too. Thanks!
Share on LinkedIn
Share on Google+

Author
Mahesh Sabnis is a DotNetCurry author and a Microsoft MVP having over two decades of experience in IT education and development. He is a Microsoft Certified Trainer (MCT) since 2005 and has conducted various Corporate Training programs for .NET Technologies (all versions), and Front-end technologies like Angular and React. Follow him on twitter @maheshdotnet or connect with him on LinkedIn


Page copy protected against web site content infringement 	by Copyscape




Feedback - Leave us some adulation, criticism and everything in between!
Comment posted by steven on Tuesday, October 8, 2013 12:41 PM
Can you provide with the source code?TKS
Comment posted by steven on Tuesday, October 8, 2013 12:41 PM
Can you provide with the source code?TKS
Comment posted by Bhaskar Reddy on Wednesday, February 5, 2014 1:01 AM
How to connect sql server 2008 Database with Visual Studio Extension Iceniun
Please Reply Code to My EmailId.

Thanks,
Bhaskar Reddy.
Comment posted by santosh kumar sharma on Tuesday, October 7, 2014 2:59 AM
hi, dnc is best mag.
Comment posted by Bala on Friday, December 19, 2014 4:50 AM
Sir,When i tryed it's not working.Can i have Source Code Of the  Project.. Thanks in advance.