Adding Category/Subcategories In MVC Using jQuery

Introduction

 
Hi guys. In this article I am going to explain to you how to add a subcategories list under the main category & display them into the table on the same view, then submit to the controller in MVC using jquery.
 
Like this:
 
 
Here I first add Jewelry Name (which is a category). If I check on the Have SubCategory? checkbox then subcategory panel displays for adding subcategories one by one under this category.
 
And on click of the plus button, a subcategory is added to the below table immediately and then we submit this data to the controller for saving into the database.
For this process, I am using jquery so my page does not need to be refreshed and data stores locally while being added, after submission of its stores into the database.
 
Let's do it.
 
First create AddEditController.cs to your mvc application then create AddEditJewelry() action method:
  1. public ActionResult AddEditJewelry(int ? id) {  
  2.     JewelryDto model = new JewelryDto();  
  3.     if (id.HasValue) {  
  4.         //write get  category by id code here     
  5.         model.subcategories = xyz.ToList(); // get SubCategoryFromDb    
  6.     } else {  
  7.         model = new JewelryDto();  
  8.     }  
  9.     return View(model);  
  10. }   
  Now, add AddEditJewelry.cshtml view
  1. @model ALS.Services.JewelryDto    
  2. <div id="frm-create-edit-Jewelry" class="cmxform">    
  3.     @using (Html.BeginForm())    
  4.     {    
  5.         @Html.AntiForgeryToken()    
  6.            
  7.           
  8.     <div id="validation-summary" style="display:none" class="alert alert-danger alert-dismissable"></div>  
  9.     <div class="modal-body form-horizontal">  
  10.         <div class="form-group">    
  11.                 @Html.HiddenFor(model => model.JewelryId)    
  12.                 @Html.LabelFor(model => model.Name, new { @class = "col-lg-3 col-sm-3 control-label" })    
  13.                   
  14.             <div class="col-lg-9 col-sm-9">    
  15.                     @Html.TextBoxFor(model => model.Name, truenullnew { @class = "form-control ", @maxlength = 100, @onchange = "CheckJewelryName(this)" })    
  16.                 </div>  
  17.         </div>  
  18.         <div class="form-group">  
  19.             <div class="col-lg-3 col-sm-3"></div>  
  20.             <div class="col-lg-9 col-sm-9" id="divhavesubcat" style="display:@(Model.JewelryId > 0?"block":"none")">  
  21.                 <div class="checkbox icheck">    
  22.                         @Html.CheckBoxFor(model => model.IsSubCat, new { @class = "form-checkbox" })    
  23.                           
  24.                     <label id="lblehavesub"> Have SubCategory?</label>  
  25.                 </div>  
  26.             </div>  
  27.         </div>    
  28.     
  29.             @if (Model.JewelryId > 0 && Model.subcategories != null)    
  30.                 {    
  31.                   
  32.         <table id="grdsubcatupdate" class="table table-bordered table-striped table-responsive-md">  
  33.             <thead>  
  34.                 <tr>  
  35.                     <td>Name</td>  
  36.                     <td>Action</td>  
  37.                 </tr>  
  38.             </thead>  
  39.             <tbody>    
  40.                         @foreach (JewelrySubCategory item in Model.subcategories)    
  41.                     {    
  42.                               
  43.                 <tr>  
  44.                     <td>@item.Name </td>  
  45.                     <td>  
  46.                         <a data-toggle="modal" data-target="#modal-delete-subJewelry" href="@Url.Action("DeleteSubCategory", "Jewelry", new { id = item.JsubId })">  
  47.                             <i class="fa fa-trash-o"></i>  
  48.                         </a>  
  49.                     </td>  
  50.                 </tr>    
  51.                         }    
  52.     
  53.                       
  54.             </tbody>  
  55.         </table>    
  56.             }    
  57.     
  58.               
  59.         <div id="divsubcat" style="display:none">  
  60.             <div class="form-group">  
  61.                 <div class="col-lg-9 col-sm-9">    
  62.                         @Html.HiddenFor(model => model.SubJId)    
  63.                         @Html.LabelFor(model => model.SubcatName, new { @class = "col-lg-3 col-sm-3 control-label" })    
  64.                         @Html.TextBoxFor(model => model.SubcatName, truenullnew { @class = "form-control ", @maxlength = 100, @onchange = "CheckSubJName(this)" })    
  65.     
  66.                     </div>  
  67.                 <div class="col-lg-3 col-sm-3" style="margin-top: 25px;">  
  68.                     <a class="btn btn-primary" id="btnAddCollection">  
  69.                         <i class="fa fa-plus"></i>  
  70.                     </a>  
  71.                 </div>  
  72.             </div>  
  73.             <table id="grdsubcatsave" class="table table-bordered table-striped table-responsive-md" style="display:none">  
  74.                 <thead>  
  75.                     <tr>  
  76.                         <td>Name</td>  
  77.                         <td>Action</td>  
  78.                     </tr>  
  79.                 </thead>  
  80.                 <tbody></tbody>  
  81.             </table>  
  82.         </div>  
  83.     </div>  
  84.     <div class="modal-footer">  
  85.         <button class="btn btn-success" id="btn-submit" type="button">    
  86.                 Submit    
  87.             </button>  
  88.     </div>    
  89.     }    
  90.   
  91. </div>     
The HideShow() function displays the subcategory panel on click of the Have Subcategory? checkbox.
  1. function HideShow() {  
  2.   
  3.        var count = 0;  
  4.        $('#IsSubCat').on("change"function () {  
  5.            if (count == 1) {  
  6.                $("#IsSubCat").prop("checked"true);  
  7.                $('#divsubcat').show();  
  8.                count = 0;  
  9.            }  
  10.            else {  
  11.                $("#IsSubCat").prop("checked"false);  
  12.                $('#divsubcat').hide();  
  13.                count++;  
  14.            }  
  15.        })  
  16.   
  17.    }  
On click of the 'btnAddCollection' button, this function checks that the subcategory you added already exists in array collection or not. If it exists then it shows an error message otherwise it adds that into the displayed table and pushes that category into array, 'CollectionList'.
  1. CollectionList = [];  
  2. $('#btnAddCollection').on('click'function() {  
  3.     debugger;  
  4.     if (isSubJNameExist) {} else {  
  5.         $('#validation-summary').hide();  
  6.         $('#validation-summary').html('');  
  7.         isSubJNameExist = false;  
  8.         var collection = $('#SubcatName').val();  
  9.         var Name = $('#Name').val();  
  10.         if (collection == '' || collection == 'undefined' || collection == undefined) {  
  11.             showerror('Sub category Name is requierd. ')  
  12.         } else if (Name == '' || Name == 'undefined' || Name == undefined) {  
  13.             showerror('Jewelry Name is requierd. ')  
  14.         } else {  
  15.             removeerror();  
  16.             $('#grdsubcatsave').show();  
  17.             var isExist = false;  
  18.             $.each(CollectionList, function(i, value) {  
  19.                 if (value.ColletionName === collection) {  
  20.                     isExist = true;  
  21.                 } else {  
  22.                     isExist = false;  
  23.                 }  
  24.             });  
  25.             if (isExist) {  
  26.                 showerror("Already Exist in current collection.")  
  27.             } else {  
  28.                 removeerror();  
  29.                 var row = "<tr id='" + collection + "'><td>" + collection + "</td> <td> <a href='#'> <i class='fa fa-trash-o'></i></a> </td>";  
  30.                 $('#grdsubcatsave>tbody').append(row);  
  31.                 var collDto = {  
  32.                     ColletionName: collection  
  33.                 };  
  34.                 CollectionList.push(collDto);  
  35.                 $('#SubcatName').val('')  
  36.             }  
  37.         }  
  38.     }  
  39. });  
This function checks the subcategory name from the database. If it exists in the database then it shows an error message, otherwise it removes the error.
  1. function CheckSubJName(reff) {  
  2.     var name = $(reff).val();  
  3.     if (name != "" && name != "undefined") {  
  4.         $.ajax({  
  5.             type: "POST",  
  6.             contentType: "application/json; charset=utf-8",  
  7.             url: domain + "admin/jewelry/CheckSubJNameExist",  
  8.             data: '{Name:' + JSON.stringify(name) + '}',  
  9.             dataType: "json",  
  10.             //called on jquery ajax call success    
  11.             success: function(result) {  
  12.                 debugger;  
  13.                 if (result === "Exist") {  
  14.                     isSubJNameExist = true;  
  15.                     showerror('Sub Jewelry Name Already Exist With us.')  
  16.                 } else {  
  17.                     isSubJNameExist = false;  
  18.                     removeerror();  
  19.                 }  
  20.             },  
  21.             error: function ajaxError(result) {  
  22.                 $('#validation-summary').html('Something Went Wrong.');  
  23.             }  
  24.         });  
  25.     }  
  26. }   
Now, on click of save button, call an Ajax for saving this collection into the database.
  1. $('#btn-submit').on('click'function () {  
  2.   
  3.            if ($('#validation-summary').hasClass("error")) {  
  4.            }  
  5.            else {  
  6.                removeerror();  
  7.                AddCollection();  
  8.            }  
  9.   
  10.        })  
  1. function removeerror() {  
  2.     $('#validation-summary').hide();  
  3.     $('#validation-summary').html('');  
  4.     $('#validation-summary').removeAttr("class");  
  5. }  
And now from here, we can add / update collection list by Ajax call.
  1. function AddCollection() {  
  2.     if (CollectionList.length > 0) {  
  3.         debugger;  
  4.         var jname = $('#Name').val();  
  5.         var jid = $('#JewelryId').val();  
  6.         var model = JSON.stringify(CollectionList)  
  7.         $.ajax({  
  8.             type: "POST",  
  9.             url: domain + "admin/jewelry/AddEditJewelry",  
  10.             contentType: "application/json;charset=utf-8",  
  11.             data: JSON.stringify({  
  12.                 data1: model,  
  13.                 Name: jname,  
  14.                 JewelryId: jid  
  15.             }),  
  16.             dataType: "json",  
  17.             success: function(msg) {  
  18.                 if (msg == "Success") {  
  19.                     window.location.href = domain + "admin/home/index";  
  20.                 } else {  
  21.                     alert("Something went wrong");  
  22.                 }  
  23.             },  
  24.             error: function(xmlhttprequest, textstatus, errorthrown) {}  
  25.         });  
  26.     } else {  
  27.         var jname = $('#Name').val();  
  28.         var jid = $('#JewelryId').val();  
  29.         $.ajax({  
  30.             type: "POST",  
  31.             url: domain + "admin/jewelry/AddEditJewelry",  
  32.             contentType: "application/json;charset=utf-8",  
  33.             data: JSON.stringify({  
  34.                 Name: jname,  
  35.                 JewelryId: jid  
  36.             }),  
  37.             dataType: "json",  
  38.             success: function(msg) {  
  39.                 if (msg == "Success") {  
  40.                     window.location.href = domain + "admin/home/index";  
  41.                 } else {  
  42.                     alert("Something went wrong");  
  43.                 }  
  44.             },  
  45.             error: function(xmlhttprequest, textstatus, errorthrown) {}  
  46.         });  
  47.     }  
  48. }   
You can see the final jewelry.js here:
  1. $(document).ready(function() {  
  2.     var CollectionList = [];  
  3.     HideShow();  
  4.     addSubcategories();  
  5.   
  6.     function HideShow() {  
  7.         var count = 0;  
  8.         $('#IsSubCat').on("change"function() {  
  9.             if (count == 1) {  
  10.                 $("#IsSubCat").prop("checked"true);  
  11.                 $('#divsubcat').show();  
  12.                 count = 0;  
  13.             } else {  
  14.                 $("#IsSubCat").prop("checked"false);  
  15.                 $('#divsubcat').hide();  
  16.                 count++;  
  17.             }  
  18.         })  
  19.     }  
  20.   
  21.     function addSubcategories() {  
  22.         CollectionList = [];  
  23.         $('#btnAddCollection').on('click'function() {  
  24.             debugger;  
  25.             if (isSubJNameExist) {} else {  
  26.                 $('#validation-summary').hide();  
  27.                 $('#validation-summary').html('');  
  28.                 isSubJNameExist = false;  
  29.                 var collection = $('#SubcatName').val();  
  30.                 var Name = $('#Name').val();  
  31.                 if (collection == '' || collection == 'undefined' || collection == undefined) {  
  32.                     showerror('Sub category Name is requierd. ')  
  33.                 } else if (Name == '' || Name == 'undefined' || Name == undefined) {  
  34.                     showerror('Jewelry Name is requierd. ')  
  35.                 } else {  
  36.                     removeerror();  
  37.                     $('#grdsubcatsave').show();  
  38.                     var isExist = false;  
  39.                     $.each(CollectionList, function(i, value) {  
  40.                         if (value.ColletionName === collection) {  
  41.                             isExist = true;  
  42.                         } else {  
  43.                             isExist = false;  
  44.                         }  
  45.                     });  
  46.                     if (isExist) {  
  47.                         showerror("Already Exist in current collection.")  
  48.                     } else {  
  49.                         removeerror();  
  50.                         var row = "<tr id='" + collection + "'><td>" + collection + "</td> <td> <a href='#'> <i class='fa fa-trash-o'></i></a> </td>";  
  51.                         $('#grdsubcatsave>tbody').append(row);  
  52.                         var collDto = {  
  53.                             ColletionName: collection  
  54.                         };  
  55.                         CollectionList.push(collDto);  
  56.                         $('#SubcatName').val('')  
  57.                     }  
  58.                 }  
  59.             }  
  60.         });  
  61.         $('#btn-submit').on('click'function() {  
  62.             if ($('#validation-summary').hasClass("error")) {} else {  
  63.                 removeerror();  
  64.                 AddCollection();  
  65.             }  
  66.         })  
  67.   
  68.         function AddCollection() {  
  69.             if (CollectionList.length > 0) {  
  70.                 debugger;  
  71.                 var jname = $('#Name').val();  
  72.                 var jid = $('#JewelryId').val();  
  73.                 var model = JSON.stringify(CollectionList)  
  74.                 $.ajax({  
  75.                     type: "POST",  
  76.                     url: domain + "admin/jewelry/AddEditJewelry",  
  77.                     contentType: "application/json;charset=utf-8",  
  78.                     data: JSON.stringify({  
  79.                         data1: model,  
  80.                         Name: jname,  
  81.                         JewelryId: jid  
  82.                     }),  
  83.                     dataType: "json",  
  84.                     success: function(msg) {  
  85.                         if (msg == "Success") {  
  86.                             window.location.href = domain + "admin/home/index";  
  87.                         } else {  
  88.                             alert("Something went wrong");  
  89.                         }  
  90.                     },  
  91.                     error: function(xmlhttprequest, textstatus, errorthrown) {}  
  92.                 });  
  93.             } else {  
  94.                 var jname = $('#Name').val();  
  95.                 var jid = $('#JewelryId').val();  
  96.                 $.ajax({  
  97.                     type: "POST",  
  98.                     url: domain + "admin/jewelry/AddEditJewelry",  
  99.                     contentType: "application/json;charset=utf-8",  
  100.                     data: JSON.stringify({  
  101.                         Name: jname,  
  102.                         JewelryId: jid  
  103.                     }),  
  104.                     dataType: "json",  
  105.                     success: function(msg) {  
  106.                         if (msg == "Success") {  
  107.                             window.location.href = domain + "admin/home/index";  
  108.                         } else {  
  109.                             alert("Something went wrong");  
  110.                         }  
  111.                     },  
  112.                     error: function(xmlhttprequest, textstatus, errorthrown) {}  
  113.                 });  
  114.             }  
  115.         }  
  116.     }  
  117. })   
Now on the HTTP post on AddEditJewelry.cs controller we get collection data into variables with names like eg.data1, Name, and JewelryId parameters. Here I first get the jewelry category by id and hold it into the model if it's null, which  means no entry into the DB. So we initialize var cls = new Jewelry(); memory and then save it or update it into the database on the base of jewelry id.
  1. [HttpPost]  
  2. public ActionResult AddEditJewelry(string data1, string Name, string JewelryId) {  
  3.     try {  
  4.         var msg = "";  
  5.         if (!String.IsNullOrEmpty(Name)) {  
  6.             var jid = Convert.ToDecimal(JewelryId);  
  7.             Jewelry cls = collectionService.GetJewelryById(jid);  
  8.             if (cls == null) {  
  9.                 cls = new Jewelry();  
  10.             }  
  11.             cls.JewelryId = Convert.ToDecimal(JewelryId);  
  12.             cls.Name = Name;  
  13.             cls.Photo = "";  
  14.             collectionService.SaveJewelry(cls);  
  15.             if (data1 != null && data1 != "undefined" && cls.JewelryId > 0) {  
  16.                 List < JewelrySubCategory > list = new List < JewelrySubCategory > ();  
  17.                 List < JsubName > subcats = JsonConvert.DeserializeObject < List < JsubName >> (data1);  
  18.                 foreach(JsubName item in subcats) {  
  19.                     JewelrySubCategory subcatmodel = new JewelrySubCategory();  
  20.                     subcatmodel.JewelryId = cls.JewelryId;  
  21.                     subcatmodel.Name = item.ColletionName;  
  22.                     subcatmodel.Photo = "";  
  23.                     list.Add(subcatmodel);  
  24.                 }  
  25.                 collectionService.SaveSubCategories(list);  
  26.             }  
  27.             msg = "Jewelry has been saved successfully.";  
  28.             return Json("Success", JsonRequestBehavior.AllowGet);  
  29.         } else {  
  30.             msg = "There is some errors, Please re-check all the details.";  
  31.             return Json("Fail", JsonRequestBehavior.AllowGet);  
  32.         }  
  33.     } catch (Exception ex) {}  
  34.     return null;  
  35. }   
Make a class for deserialization of subcategory name, and make sure the CollectionName Property and class property name should be the same so that we can serialize it easily.
  1. var collDto = { ColletionName: collection };  
  2. CollectionList.push(collDto); 
  1. public class JsubName  
  2.    {  
  3.        public string ColletionName { getset; }  
  4.    }  

Conclusion

 
So finally, we get the output displayed like it is at the top of the article.