Announcement

Pagination in MVC4



Pagination in MVC4

This post will explain pagination in MVC4.

You need to install NuGet Package manager named PagedList. You can get the same by clicking NuGet PagedList.
Once this is installed in your project, add a reference to PagedList and PagedList.Mvc dlls. In your view, include the following code at the top as:

@using PagedList;
@using PagedList.Mvc;


The model which your view will be returning should be IPagedList<> rather than IEnumerable<>.

Now you are ready to use the Html Helper for the PagedList. i.e., @Html.PagedListPager() where you can also specify various display options for the pagination.

The view will look like this:

@using PagedList;
@using PagedList.Mvc;
@model IPagedList&ltDistribution.Entities.District&gt
@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<link href="../../Content/PagedList.css" rel="stylesheet" type="text/css" />
<h2>Display</h2>
@Html.ActionLink("Create New", "Create")


The various display options for the PagedList can be found in PagedList.Mvc namespace 
inside the class PagedListRenderOptions.

You can make any changes as per the requirement.


public PagedListRenderOptions()
{
 DisplayLinkToFirstPage = PagedListDisplayMode.IfNeeded;
 DisplayLinkToLastPage = PagedListDisplayMode.IfNeeded;
 DisplayLinkToPreviousPage = PagedListDisplayMode.IfNeeded;
 DisplayLinkToNextPage = PagedListDisplayMode.IfNeeded;
 DisplayLinkToIndividualPages = true;
 DisplayPageCountAndCurrentLocation = false;
 MaximumPageNumbersToDisplay = 10;
 DisplayEllipsesWhenNotShowingAllPageNumbers = true;
 EllipsesFormat = "…";
 LinkToFirstPageFormat = "««";
 LinkToPreviousPageFormat = "«";
 LinkToIndividualPageFormat = "{0}";
 LinkToNextPageFormat = "»";
 LinkToLastPageFormat = "»»";
 PageCountAndCurrentLocationFormat = "Page {0} of {1}.";
 ItemSliceAndTotalFormat = 
"Showing items {0} through {1} of {2}.";
 FunctionToDisplayEachPageNumber = null;
 ClassToApplyToFirstListItemInPager = null;
 ClassToApplyToLastListItemInPager = null;
 ContainerDivClasses = new [] { "pagination-container" };
 UlElementClasses = new[] { "pagination" };
 LiElementClasses = Enumerable.Empty();
}

The Complete View is as:

View


@using PagedList;
@using PagedList.Mvc;
@model IPagedList<distribution .entities.district="">
@{
    ViewBag.Title = "Index";
    Layout = "~/Views/Shared/_Layout.cshtml";
}
<link href="../../Content/PagedList.css" rel="stylesheet" 
type="text/css" />
<h2>Display</h2>
<p>
    @Html.ActionLink("Create New", "Create")
</p>
<table>
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.First()
.State.StateName)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.First()
.DistrictName)
        </th>
        <th></th>
    </tr>
@foreach (var item in Model) {
    <tr>
        <td>
         @Html.DisplayFor(modelItem => item.State.StateName)
        </td>
        <td>
         @Html.DisplayFor(modelItem => item.DistrictName)
        </td>
        <td>
         @Html.ActionLink("Edit", "Edit", new 
{ id=item.DistrictId }) |
         @Html.ActionLink("Details", "Details", new 
{ id=item.DistrictId }) |
         @Html.ActionLink("Delete", "Delete", 
new { id=item.DistrictId })
        </td>
    </tr>
}
</table>
@Html.PagedListPager(Model,page=>
Url.Action("Index",new {page}), 
new PagedListRenderOptions 
{Display=PagedListDisplayMode.IfNeeded, 
DisplayPageCountAndCurrentLocation=true})


Now that your view is ready, you will have to write code for your controller for the pagination. This is as under:

Controller

public ActionResult Index(int? page)
{
return View(db.Districts.ToList()
.ToPagedList(page ?? 1,4));
}



Validations in MVC 4


There are two ways to add custom validations in MVC 4:
  1. Using Data Annotations with Model Binder.
  2. Using Data Annotations in Entity Framework.
Let us see:
  1. Using Data Annotations with Model Binder
Inorder to use DataAnnotation with Model Binder, you need to add references to the following dlls:


How to find if radio button is checked or not?

This post will explain how to get the checked item from radio button. It will determine if radio button is checked or not.

This is done using jquery as follows:

$('#RadioButtonId').is(':checked')

How to include favicon in your website in MVC?

Inorder to include favorite icon in your website you just have to provide a reference in the link tag to the favorite icon (provided you have a favorite icon).

It is also known as Shortcut icon, Tab icon, Website icon or Bookmark icon.

<link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />

If you do not have a favorite icon than you can create your own favorite icon by importing the image. Just visit favicon generator.

Deleting records using ajax and updating the content after deletion

This post will explain how to delete records from table and updating the content after deletion using ajax.

We will delete records based on the user's choice i.e., user will be given the option to select or deselect the record or records using check boxes.

We will take an example of deleting graphics from the clips that are already allocated to the clips in GraphicsClipsMap table.

For each graphics, check box will be displayed adjacent to it. One delete button is provided for deleting those selected graphics.

1. Write a function that will be called when the delete button is clicked.

2. Within this function write the code to check whether the checkbox is checked or not when the delete button is clicked. If there is no single check box checked and the user clicked the delete button, then display an error in alert to select atleast one checkbox for deletion.

  function DeleteGraphicsFromClip(playoutcode) {
            var checkedIds = [];
            var flag = 1;
            $('input[class=' + playoutcode + ']:checked').each(function () {
                if ($('input[class=' + playoutcode + ']:checked').length <= 0) {
                    alert($(this).attr("id"));
                    flag = 1;
                }
                else {
                    checkedIds.push($(this).attr("id"));
                    alert($(this).attr("id"));
                    flag = 0;
                }
            });

3. Now, pass the selected checkbox ids- the ids are the primary key associated with the graphics to be deleted, to the controller using ajax. These ids are stored in the array using javascript.

4. Flag is set to zero. Now we will pass the checked ids to the controller.

 if (flag == 0) {
                if (confirm('Do you really want to delete the checked graphics?')) {
                    alert('checked: ' + checkedIds);
                    /* pass this array of GraphicClipMap ids to controller's Delete Action Method
                    for deleting the mapped graphics from the clip */
                    $.ajax({
                        url: '@Url.Action("DeleteGraphicsFromClips", "GraphicsClipMap")',
                        data: JSON.stringify({ graphicsClipMapIds: checkedIds }),
                        dataType: 'json',
                        type: 'POST',
                        contentType: "application/json",
                        async: true,
                        success: function (result) {
                            if (result == "3") {
                                alert('You are not allowed to delete graphics form this clip. It is about to scheduled within 2 weeks time.');
                                return false;
                            }
                            if (result == "2") {
                                alert("Graphics already deleted.");
                                return false;
                            }
                            else if (result == "1") {
                                alert('Problem deleting graphics from clip.');
                                return false;
                            }
                            else {
                                /* successfully deleted: now get all graphics after deletion from the clips */
                                $.ajax({
                                    url: '@Url.Action("GetAllClips", "GraphicsClipMap")',
                                    data: JSON.stringify({ ScheduledProgrammeCode: $('#ddlProgramme :selected').val() }),
                                    dataType: 'json',
                                    type: 'POST',
                                    contentType: "application/json",
                                    async: true,
                                    success: function (clips) {
                                        showClipGraphics(clips);
                                        $('.label').show();
                                        $('#clipGrid').show();
                                    },
                                    Error: function () {
                                        alert("Unable to retrive clips due to unsuccessful ajax call.");
                                    }
                                })
                                alert('Graphics successfully deleted from this clip.');
                            }
                        },
                        Error: function () {
                            alert("Unable to delete graphics from clips due ajax call unsuccessfull.");
                        }
                    });
                }
                flag = 1;
            }
            else {
                alert('Please select graphics to delete from this clip.');
                flag = 1;
            }
    }     //finally delete function is closed here.


5. Now its time to delete Graphics from the Clips that are selected in the view using checkboxes.

   public JsonResult DeleteGraphicsFromClips(string[] graphicsClipMapIds)
        {
            string query = string.Empty;
            foreach (var graphicsClipMapId in graphicsClipMapIds)
            {
                int gmId = Convert.ToInt32(graphicsClipMapId);
                /* check if graphics Id exists or not in the graphics clip map, if
                 *  not then it is already deleted. If present, enter its history in 
                 *  the history table then delete it. */
                int deletegmIdexists = Convert.ToInt32(context.GraphicsClipMaps.Where(a => a.GraphicsClipMapId == gmId).Select(b => b.GraphicsId).SingleOrDefault());
                if (deletegmIdexists > 0)
                {
                    //string playoutCode = context.GraphicsClipMaps.Where(a => a.GraphicsClipMapId == gmId).Select(b => b.playoutcode).FirstOrDefault();
                    query = bizGraphicsClipMap.DeleteGraphicsFromClips(gmId);
                    //query = query.Replace("0",playoutCode);
                    //GetScheduledGraphics(playoutCode);
                }
                else
                {
                    //Already deleted.
                    query = "2";
                }
            }
            return Json(query, JsonRequestBehavior.AllowGet);
        }

6.  Now, get all the scheduled graphics for the selected clip i.e., playout.

  public JsonResult GetScheduledGraphics(string pc)
        {
            dynamic graphics;
            /* check for graphics whether it exists for any of the playout, if 
             * it exists, then display all graphics for that clip.*/
            List<GraphicsMaster> scheduledGraphics = new List<GraphicsMaster>();
            List<int> graphicClipMapId = new List<int>();
            List<int> graphicsCode = new List<int>();
            List<GraphicsClipMap> graphicsId = new List<GraphicsClipMap>();
            List<string> graphicsOffset = new List<string>();
            List<string> graphicsDuration = new List<string>();

            List<int> clipMapId = new List<int>();
            graphicsId = context.GraphicsClipMaps.Where(y => y.playoutcode.Equals(pc)).ToList();
            if (graphicsId.Count > 0)
            {
                foreach (var gId in graphicsId)
                {
                    int id = Convert.ToInt32(gId.GraphicsId);
                    graphicsCode.Add(id);
                    clipMapId.Add(gId.GraphicsClipMapId);
                }
                for (int i = 0; i < clipMapId.Count; i++)
                {
                    int id = Convert.ToInt32(clipMapId[i]);
                    int gcode = Convert.ToInt32(graphicsCode[i]);
                    graphicClipMapId.Add(Convert.ToInt32(context.GraphicsClipMaps.Where(p => p.GraphicsId == id).Select(b => b.GraphicsClipMapId).FirstOrDefault()));
                    scheduledGraphics.Add(context.GraphicsMasters.Where(c => c.GraphicsId == gcode).FirstOrDefault());
                    graphicsOffset.Add(context.GraphicsClipMaps.Where(a => a.GraphicsClipMapId == id).Select(b => b.GraphicsOffset).FirstOrDefault().ToString());
                    graphicsDuration.Add(context.GraphicsClipMaps.Where(a => a.GraphicsClipMapId == id).Select(b => b.GraphicsDuration).FirstOrDefault().ToString());
                }
            }
            graphics = (new { PlayoutId = pc, GraphicsName = scheduledGraphics.Select(a => a.GraphicsName), GraphicStartTime = graphicsOffset, GraphicEndTime = graphicsDuration, GraphicsMapId = clipMapId });
            return Json(graphics, JsonRequestBehavior.AllowGet);
        }

7. Now, Update the Clip Details in the div to show graphics after deleting selected graphics. This is achieved using another ajax call within the delete ajax call i.e., showClipGraphics(clips);. Where in we pass the updated clips object after deleting the graphics from the clip.

This is achieved as under...

 function showClipGraphics(clips) {
        $('#clipDetails').empty();
        $('#clipDetails').append('<tr style="background-color:#20ff00"><th>Select</th><th>'
                    + 'Start Time</th><th>End Time</th><th>Duration</th><th>Title</th><th>File Server '
                    + 'Programme Id</th></tr>');
        for (var i = 0; i < clips.PlayoutId.length; i++) {
            if (clips.Prefix[i] == "FF" || clips.Prefix[i] == "MB" || clips.Prefix[i] == "SO") {
                $('#clipDetails').append('<tr style="background-color:#01ACFE"><td><input type="radio" class="rdoClip" name="rdoClipDetail" id="'
                 + clips.PlayoutId[i] + '" value="' + clips.PlayoutId[i] + '" onclick="selectedClip(this)" /></td><td>'
                 + clips.ClipStartTime[i].toString() + '</td><td>' + clips.ClipEndTime[i].toString() + '</td><td>'
                 + clips.ClipDuration[i].toString() + '</td><td>' + clips.ClipName[i].toString()
                 + '</td><td>' + clips.FileServerProgrammeId[i].toString() + '</td><td>'
                 + clips.Prefix[i].toString() + '</td></tr>');
                /* ajax call for getting all scheduled graphics within a clip */
                var playoutcode = clips.PlayoutId[i];
                if (playoutcode != null) {
                    var options = {};
                    options.url = '@Url.Action("GetScheduledGraphics", "GraphicsClipMap")';
                    options.data = JSON.stringify({ pc: playoutcode });
                    options.type = "POST";
                    options.dataType = "json";
                    options.contentType = "application/json";
                    options.async = false;
                    options.success = function (graphics) {
                        if (graphics.GraphicsName.length > 0) {
                            $('#clipDetails').append('<tr style="background-color:#F9FF00"><th colspan="3">Graphic for this clip</th><th>Graphics Name</th><th>Graphics Offset</th><th>Graphics Duration</th><th><input type="button" class="delButton" value="Delete" id="' + playoutcode + '" onclick=DeleteGraphicsFromClip('+playoutcode+')></th>');
                            for (var i = 0; i < graphics.GraphicsName.length; i++) {
                                $('#clipDetails').append('<tr style="background-color:#00FF9F"><td colspan="3">&nbsp</td><td>' + graphics.GraphicsName[i] + '</td><td>' + graphics.GraphicStartTime[i] + '</td><td>' + graphics.GraphicEndTime[i] + '</td><td><input type="checkbox" name="chkDelete" class="' + playoutcode + '" value="' + graphics.GraphicsMapId[i] + '" id=' + graphics.GraphicsMapId[i] + ' /></td></tr>');
                            }
                        }
                    };
                    options.error = function () { alert("Error retrieving scheduled graphics due to problem in ajax call!"); };
                    $.ajax(options);
                }
            }
            else {
                $('#clipDetails').append('<tr><td></td><td>' + clips.ClipStartTime[i].toString() + '</td><td>' + clips.ClipEndTime[i].toString() + '</td><td>' + clips.ClipDuration[i].toString() + '</td><td>' + clips.ClipName[i].toString() + '</td><td>' + clips.FileServerProgrammeId[i].toString() + '</td><td>' + clips.Prefix[i].toString() + '</td></tr>');
            }
        }
    }

In the above function, we retrieve all the clips and the graphics under that clip, if any, using ajax. Then we update the clipDetails div with the newly retrieved clip details.