Image navigator using jquery in MVC3 Razor


  • In this article we will see how to develop a simple image navigator.
  • We have used jQuery, ajax, jSon and MVC3 Razor to accomplish this.
  • The best thing about this image navigator is that, the page do not postback for rendering next image.

Approach :

We are loading an image from database on first load of view. On click of next and previous we are quering database to get the next or previous image and rendring it on the UI. We are using jQuery, ajax and jSon to GET and update image which prevents postback of page.

View:
    @model RenderImage.ViewModel.ImageNavigatorViewModel

@{
    ViewBag.Title = "ImageNavigator";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>ImageNavigator</h2>


<style type="text/css">
#imgDiv
{
    width:500px;
    height:500px;
    background-color:Orange;
    position:absolute;
}
#mainDiv
{
    margin-left:400px;
}
.absoluteClass
{
    position:absolute;
}
</style>

<div id="mainDiv">
<div id="imgDiv">
<img  style="height:inherit;width:inherit;" src="data:image/jpg;base64,@(Html.Raw(Convert.ToBase64String(Model.Image.ImageBytes)))" id="renderingImage" alt="players"/>
</div>
<div>
<input type="hidden" name="hiddenImageId" id="hiddenImageId" value="@Model.Image.ImageId" />
<input class="absoluteClass" title="Previous" style="margin-top:250px;" type="submit" id="previous" value="<" />
<input class="absoluteClass" title="Next" style="margin-left:474px;margin-top:250px;" type="submit" id="next" value=">" />
</div>
</div>

<script type="text/javascript">
    $(document).ready(function () {
        $(document).tooltip();
        $("#previous").click(function () {
            GetImage("previous");
        });
        $("#next").click(function () {
            GetImage("next");
        });
    });
    function GetImage(operation) {
        var ImageId = $("#hiddenImageId").val();
        $.ajax({
            url: '@Url.Action("GetNextPreviousImage", "ImageNavigator")',
            type: 'GET',
            data: { "operation": operation, "ImageId": ImageId },
            dataType: 'json',
            success: function (response) {
                if (response != undefined && response != "true") {
                    $("#renderingImage").attr("src", "data:image/jpg;base64," + response.result);
                    $("#hiddenImageId").val(response.imageId);
                }
            },
            error: function (error) {
                alert("Error" + error);
            }
        });
    }
</script>

The view accepts a View Model which carries the image bytes of load of the view. We have created a div element inside which we are rendering an image. We have created two buttons each for next and previous. On click of this button we use jQuery ajax method to get the next image from database. The bytes from database are then updated to the image source.

Controller :
    public ActionResult ImageNavigator()
        {
            ImageNavigatorViewModel model = new ImageNavigatorViewModel();
            RenderImage.Service.RenderImage service = new Service.RenderImage();
            model.Image = service.GetImageByImageId(2);
            return View(model);
        }

        [HttpGet]
        public JsonResult GetNextPreviousImage(string operation, int ImageId)
        {
            RenderImage.Service.RenderImage service = new Service.RenderImage();
            if(operation == "next")
                ImageId = ImageId + 1;
            else
                ImageId = ImageId - 1;
            byte[] imageBytes = service.GetImageBytesByImageId(ImageId);
            if (imageBytes == null)
                return Json("true", JsonRequestBehavior.AllowGet);
            else
                return Json(new { result = Convert.ToBase64String(imageBytes), imageId = ImageId }, JsonRequestBehavior.AllowGet);
        }

The first Action method renders the view. This action method also renders the first image. As you can see we have hard coded the imageId. Initially we are rendering any image from database, then we are rendering successive images on click of next and previous button.
The second JsonResult method is called on next and previous click, which gets the next or prevous image fro database and returns the bytes. The image bytes are converted to base 64 string format. If the database returns null for particular imageId then true is returned as jSon result instead of bytes. In this case nothing happens in success section of ajax post.

ViewModel :

We have used View Model for first load only. This is a class which is passed as model to the view. It looks like below :
    public class ImageNavigatorViewModel
    {
        public Image Image { get; set; }
    }

Service :
This is a class which interacts with database to get the images. It has two methods.
    public Image GetImageByImageId(int ImageId)
        {
            using (RenderImageEntities dataContext = new RenderImageEntities())
            {
                return dataContext.Image.Where(query => query.ImageId == ImageId).SingleOrDefault();
            }
        }

        public byte[] GetImageBytesByImageId(int ImageId)
        {
            Image image = null;
            using (RenderImageEntities dataContext = new RenderImageEntities())
            {
                image = dataContext.Image.Where(query => query.ImageId == ImageId).SingleOrDefault();
            }
            if (image != null)
                return image.ImageBytes;
            else
                return null;
        }

The first method returns the Image using ImageId and second method returns the image bytes.

jQuery Tooltip :

We have also used jQuery tooltip for better UI effects. In order to use tooltip you need to include following referenced js files in application and also need to refer in Layout file.
    <!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>@ViewBag.Title</title>
    <link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
    <link href="@Url.Content("~/Content/jquery.ui.all.css")" rel="stylesheet" type="text/css" />
    <script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/modernizr-1.7.min.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/jquery-1.8.3.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/jquery.ui.core.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/jquery.ui.widget.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/jquery.ui.position.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/jquery.ui.tooltip.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/jquery.ui.effect.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/jquery.ui.effect-explode.js")" type="text/javascript"></script>
</head>

<body>
    @RenderBody()
</body>
</html>

The above is the Layout file which is finally referred in View.

Database:


We need to have a simple database for this code to test. We need a table consisting of image bytes.  We have following table in database.




Snapshots:






0 comments:

Post a Comment