Tuesday, 21 August 2012

CRUD operation using MVC3 and Jquery


Frnds,
In this post I am gonna write code which is explaining CRUD operation using MVC WebGrid and Jquery.
Below Image Gallary shows Grid Data with Paging and Sorting functionality.
   
In this post I am gonna write code which is explaining CRUD operation using MVC WebGrid and Jquery.
 Before proceeding further we need to have our model class. Here is the our model class.
StateModel.cs
namespace MyMVC3WebApp.Models
{
    public class StateModel
    {
        [ScaffoldColumn(false)]
        public int StateID { get; set; }

        [Required]
        [StringLength(10)]
        [Remote("StateNameExist","State")]
        public string StateName { get; set; }

        [Required]
        [StringLength(10)]
        public string CountryName { get; set; }
    }
}
In our above model class I have implemented basic validation including Custom Remote validation which actually checks
State Name existence into the DB before submitting form. Here Remote attribute has two parameters, first one is action method name and the second one is the Controller name.
Above code will help you to understand the basic CRUD operation for data. Please give your feedback if you really like it or if you have any suggestion here.
Now let’s create our controller class which will have the code for the database operation.
StateController.cs
namespace MyMVC3WebApp.Controllers
{
    public class Country
    {
        public string Name { get; set; }
    }

    public class StateController : Controller
    {

        private TestDataEntities db = new TestDataEntities();
      //Method which returns list of country for dropdown country selection.
        public JsonResult GetCountries()
        {
            List<Country> resultset = new List<Country>() {
                new Country(){Name="India"},
                new Country(){Name="US"},
                new Country(){Name="Australia"},
                new Country(){Name="Rusia"},
            };
            return Json(resultset, JsonRequestBehavior.AllowGet);
        }
//Method to check state name existence being called by Remote attribute implemented in Model class for validation.
        public JsonResult StateNameExist(string stateName)
        {
            int count = (from states in db.StateMasters.AsEnumerable()
                         where states.StateName.ToLower().Trim() == stateName.ToLower().Trim()
                         select states.StateName).Count();
            if (count > 0)
                return Json(string.Format("State name {0} already exists.", stateName), JsonRequestBehavior.AllowGet);
            else
                return Json(true, JsonRequestBehavior.AllowGet);

        }
//Method returns list of states.
        public ActionResult Index()
        {
            IEnumerable<StateModel> states = from st in db.GetAllStates()
                                             select new StateModel() { StateID = st.StateID, StateName = st.StateName, CountryName = st.CountryName };
            return View(states.ToList<StateModel>());
        }

        //
        // GET: /State/Details/5

        public ActionResult Details(int id)
        {
            return View();
        }

        //
        // GET: /State/Create

        public ActionResult Create()
        {
            return View(new StateModel());
        }

        //
        // POST: /State/Create

        [AcceptVerbs(HttpVerbs.Post)]
        public void AddNewState(string stateName, string countryName)
        {
            db.AddState(stateName, countryName);
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public void UpdateState(int id, string stateName, string countryName)
        {
            StateMaster state = db.StateMasters.Single(s => s.StateID == id);
            state.StateName = stateName;
            state.CountryName = countryName;
            db.SaveChanges();
        }

        [HttpPost]
        public ActionResult Create(StateModel stateModel)
        {
            try
            {
                if (ModelState.IsValid)
                {
                    int result = Convert.ToInt32(db.AddState(stateModel.StateName, stateModel.CountryName));
                }

                return RedirectToAction("Index");
            }
            catch
            {
                return View();
            }
        }

        public ActionResult Delete(int id)
        {
            db.DeleteState(id);
            return RedirectToAction("Index");
        }
    }
}
Now this is the right time to create our view as we have ready with our model and controller class.
Index.cshtml

@model IEnumerable<MyMVC3WebApp.Models.StateModel>
@{
    ViewBag.Title = "Index";
}
<h2>
    Index</h2>
<link href="http://1.cdn.blog.com/wp-admin/../../Content/themes/base/jquery.ui.all.css" rel="stylesheet" type="text/css" />
<link href="http://1.cdn.blog.com/wp-admin/../../Content/themes/base/jquery.ui.dialog.css" rel="stylesheet" type="text/css" />
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
<script src="http://1.cdn.blog.com/wp-admin/../../Scripts/jquery-ui-1.8.11.js" type="text/javascript"></script>
<style>
    body
    {
        font-size: 82.5%;
    }
    label, input
    {
        display: block;
    }
    input.text
    {
        margin-bottom: 12px;
        width: 95%;
        padding: .4em;
    }
    fieldset
    {
        padding: 0;
        border: 0;
        margin-top: 25px;
    }
    h1
    {
        font-size: 1.2em;
        margin: .6em 0;
    }
    div#users-contain
    {
        width: 350px;
        margin: 20px 0;
    }
    div#users-contain table
    {
        margin: 1em 0;
        border-collapse: collapse;
        width: 100%;
    }
    div#users-contain table td, div#users-contain table th
    {
        border: 1px solid #eee;
        padding: .6em 10px;
        text-align: left;
    }
    .ui-dialog .ui-state-error
    {
        padding: .3em;
    }
    .validateTips
    {
        border: 1px solid transparent;
        padding: 0.3em;
    }
    .odd
    {
        background-color: #FFF;
    }
    .even
    {
        background-color: #E8E8E8;
    }

    .grid
    {
        margin: 4px;
        border-collapse: collapse;
        width: 600px;
    }
    .head
    {
        background-color: #E8E8E8;
        font-weight: bold;
        color: #FFF;
    }
    .grid th, .grid td
    {
        border: 1px solid #C0C0C0;
        padding: 5px;
    }
    .alt
    {
        background-color: #E8E8E8;
        color: #000;
    }
    .gridItem
    {
        width: auto;
        font-weight: normal;
        font-style: normal;
    }

    .gridHiddenItem
    {
        visibility: hidden;
    }

    .img
    {
        width: 20px;
        height: 20px;
        text-align: center;
    }
</style>
<script type="text/javascript">
    $(function () {  //$(document).ready(function () {

        //Start-apply css on table data
        $('tr:even').addClass('even');
        $('tr:odd').addClass("odd");
        //End-apply css on table data

        //Start-a workaround for a flaw in the demo system (http://dev.jqueryui.com/ticket/4375), ignore!
        $("#dialog:ui-dialog").dialog("destroy");
        //End-a workaround for a flaw in the demo system (http://dev.jqueryui.com/ticket/4375), ignore!

        //Start-get controls
        var state = $("#stateName"),
   country = $("#countryName"),
            btnDel = $('#deleteRecord'),
   allFields = $([]).add(state).add(country),
   tips = $(".validateTips");
        //End-get controls

        //Start-Json Call to get all country to fill the country dropdown.
        $.getJSON('/State/GetCountries', '',
        function (obj) {
            var html = "";
            for (var i = 0; i < obj.length; i++) {
                html += "<option value='"
                    + obj[i].Name
                        + "'>" + obj[i].Name
                            + "</option>";
            }
            country.html(html);
        }
        );
        //End-Json Call to get all country to fill the country dropdown.

        //Start-apply css for validation error message
        function updateTips(t) {
            tips
    .text(t)
    .addClass("ui-state-highlight");
            setTimeout(function () {
                tips.removeClass("ui-state-highlight", 1500);
            }, 500);
        }
        //End-apply css for validation error message

        //Start-length check validation
        function checkLength(o, n, min, max) {
            if (o.val().length > max || o.val().length < min) {
                o.addClass("ui-state-error");
                updateTips("Length of " + n + " must be between " +
     min + " and " + max + ".");
                return false;
            } else {
                return true;
            }
        }
        //End-length check validation

        //Start-state name existence validation.
        function checkIfStateExist(o) {
            var val = o.val();
            var IsExist = false;
            //synchroneous ajax call
            $.ajax({
                type: 'GET',
                url: '/State/StateNameExist',
                dataType: 'json',
                success: function (obj) {
                    if (obj == true) {
                        IsExist = true;
                    }
                    else {
                        o.addClass("ui-state-error");
                        updateTips(obj);
                        IsExist = false;
                    }
                },
                data: { stateName: val },
                async: false
            });
            return IsExist;
        }
        //End-state name existence validation.

        //Start-Convert div form to model dialog
        $("#dialog-form").dialog({
            autoOpen: false,
            height: 350,
            width: 250,
            modal: true,
            buttons: {
                "Submit": function () {
                    var bValid = true;
                    allFields.removeClass("ui-state-error");
                    //Perform Validation here..
                    bValid = bValid && checkLength(state, "State Name", 3, 45);
                    bValid = bValid && checkIfStateExist(state);
                    if (bValid) {
                        var id = $("#stateID").val();
                        var st = state.val();
                        var ctry = country.val();
                        if (id != "") {
                            url = "/State/UpdateState";
                            $.post(url, { id: id, stateName: st, countryName: ctry }, function (data) {
                                //reload data
                                location.reload();
                            });
                        }
                        else {
                            var url = "/State/AddNewState";
                            $.post(url, { stateName: st, countryName: ctry }, function (data) {
                                //reload data
                                location.reload();
                            });
                        }

                        $(this).dialog("close");
                    }
                },
                Cancel: function () {
                    $(this).dialog("close");
                }
            },
            close: function () {
                allFields.val("").removeClass("ui-state-error");
            }
        });
        //End-Convert div form to model dialog

        //Start-show dialog on create new button click
        $("#create-state")
   .button()
   .click(function () {
       $('#dialog-form').attr('title', 'Create New State');
       $("#dialog-form").dialog("open");
   });
        //End-show dialog on create new button click

        //Start-show dialog on Edit button click
        $("a#editRecord")
   .click(function (obj) {
       $('#dialog-form').attr('title', 'Edit State');
       $("#dialog:ui-dialog").dialog("destroy");
       var trObj = $(this).parents("tr");
       var id = trObj[0].cells[0].lastChild.defaultValue;
       var state = trObj[0].cells[1].innerText.trim();
       var country = trObj[0].cells[2].innerText.trim();
       $("#stateID")[0].value = id;
       $("#stateName")[0].value = state;
       $("#countryName").val(country);
       $("#dialog-form").dialog("open");
   });
        //End-show dialog on Edit button click

    });

    function ConfirmDelete() {
        return confirm('Do you want to delete this record');
    }

</script>

<p>
    <a id="create-state" href="#">Create New</a>
</p>
<div>
    <table>
        <tr>
            <td>
                @{
                    var grid = new WebGrid(Model, canPage: true, rowsPerPage: 5);
                }
                <div id="grid">
                    @grid.GetHtml(
                 tableStyle: "grid",
                headerStyle: "head",
                alternatingRowStyle: "alt",
                columns: grid.Columns(
                    grid.Column(null, null, format: @<input type="hidden" name="ID" value="@item.StateID"/>),
                    grid.Column("StateName", "State", style: "gridItem", canSort: true),
                    grid.Column("CountryName", "Country", style: "gridItem", canSort: true),
                    grid.Column("Edit", format: @<text><a id="editRecord" href="#"><img alt="" src="../../Content/images/Edit.jpg"
                        style="height: 20px; width: 20px" /></a></text>, style: "imgstyle"),
                    grid.Column("Delete", format: @<text><a href="@Url.Action("Delete", "State", new { id = item.StateID })" onclick="javascript:return ConfirmDelete();"><img
                        alt="" src="../../Content/images/delete.png" style="height: 20px; width: 20px" /></a></text>, style: "imgstyle")
)
                )
                </div>
            </td>
        </tr>
    </table>
</div>
<div>
    <div id="dialog-form" title="State">
        <p>
            All form fields are required.</p>
        <form>
        <fieldset>
            <input id="stateID" type="text" style="visibility: hidden" />
            <label for="stateName">
                State</label>
            <input type="text" name="stateName" id="stateName" />
            <label for="country">
                Country</label>
            <select id="countryName" style="width: 95%">
            </select>
        </fieldset>
        </form>
    </div>
</div>
Above view has style, script and html code for the view. starting of this post, post has the output images for the above code. Enjoy!

No comments:

Post a Comment