Reputation: 679
I want to sort table row by clicking on its th
but it is not working in my application. When I click on th
it redirects the whole page and reloads it.
I want to sort the table row without rendering the whole page. Please guide me.
I have added all the code. Anyone please help me to solve this problem. Thank you in advance!
Model
public class clsEmployee
{
public int? Country { get; set; }
public IEnumerable<SelectListItem> CountriesList { get; set; }
public int Department { get; set; }
public IEnumerable<SelectListItem> Departments { get; set; }
}
public class clsEmployeeClass
{
public int EmpId { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public int Salary { get; set; }
}
Controller
[HttpGet]
public ActionResult Employee()
{
clsEmployee emp = new clsEmployee();
emp = DropdownList();
emp.Country = 1;
emp.Department = 2;
return View(emp);
}
[HttpPost]
public ActionResult Employee(clsEmployee model, string sortOrder, string currentFilter)
{
model = DropdownList();
ViewBag.CurrentSort = sortOrder;
ViewBag.EmpIdSortParam = string.IsNullOrEmpty(sortOrder) ? "empid_desc" : "";
ViewBag.NameSortParam = sortOrder == "Name" ? "name_desc" : "Name";
ViewBag.AddressSortParam = sortOrder == "Address" ? "address_desc" : "Address";
ViewBag.SalarySortParam = sortOrder == "Salary" ? "salary_desc" : "Salary";
return View(model);
}
public clsEmployee DropdownList()
{
var model = new clsEmployee
{
CountriesList = new List<SelectListItem>
{
new SelectListItem { Value = "1", Text = "India" },
new SelectListItem { Value = "2", Text = "Sri Lanka" },
new SelectListItem { Value = "3", Text = "Pakistan" },
new SelectListItem {Value = "4", Text = "USA" },
},
Departments = new List<SelectListItem>
{
new SelectListItem {Value = "1", Text="Finance", Selected=true },
new SelectListItem {Value = "2", Text = "IT" },
new SelectListItem {Value = "3", Text = "Sales" },
}
};
return model;
}
public void EmployeeSearchonFilter(clsEmployee model)
{
clsUtilities clsUtilities = new clsUtilities();
DataSet ds;
List<clsEmployeeClass> leadingSiresClass = new List<clsEmployeeClass>();
string SqlStatement;
SqlParameter[] paramneters = new SqlParameter[2];
SqlStatement = "exec GetEmployeeDetails @Country,@Department";
paramneters[0] = new SqlParameter("@Country", SqlDbType.Int);
paramneters[0].Value = model.Country;
paramneters[1] = new SqlParameter("@Department", SqlDbType.Int);
paramneters[1].Value = model.Department;
ds = clsUtilities.CommandParams(SqlStatement, paramneters);
DataTable dataTable = ds.Tables[0];
ViewData["Employee"] = ds.Tables[0];
}
public ActionResult EmployeeFilter(clsEmployee model)
{
EmployeeSearchonFilter(model);
return PartialView("~/Views/Employee/_EmployeePartial.cshtml", ViewData["Employee"]);
}
Employee View
<div class="col-md-2">
@using (Html.BeginForm("Employee", "Employee", FormMethod.Post, new { @id = "EmployeeReport" }))
{
<div class="panel panel-default">
<div class="panel-body">
<div>
<b>@Html.DisplayName("Country")</b>
@Html.DropDownListFor(m => m.Country, Model.CountriesList)
</div>
<div>
@Html.DisplayName("Department")
@Html.DropDownListFor(m => m.Department, Model.Departments)
</div>
<div>
<button type="button" id="Search">Search</button>
</div>
</div>
</div>
}
</div>
<div class="col-md-4">
<div class="panel panel-default">
<div class="panel-body">
<div id="EmployeePartial">
</div>
</div>
</div>
</div>
_EmployeePartial partial View
<table>
<thead>
<tr>
<th>
@Html.ActionLink("EmpId", "Employee", new { sortOrder = ViewBag.EmpIdSortParam, currentFilter = ViewBag.CurrentFilter})
<i class="glyphicon @(ViewBag.CurrentSort== "empid_desc" ? "glyphicon-sort-by-order-alt" : "glyphicon-sort-by-order")"></i>
</th>
<th>
@Html.ActionLink("Name", "Employee", new { sortOrder = ViewBag.NameSortParam, currentFilter = ViewBag.CurrentFilter })
<i class="glyphicon @(ViewBag.CurrentSort== "name_desc" ? "glyphicon-sort-by-alphabet-alt" : "glyphicon-sort-by-alphabet")"></i>
</th>
<th>
@Html.ActionLink("Address", "Employee", new { sortOrder = ViewBag.AddressSortParam, currentFilter = ViewBag.CurrentFilter })
<i class="glyphicon @(ViewBag.CurrentSort== "address_desc" ? "glyphicon-sort-by-alphabet-alt" : "glyphicon-sort-by-alphabet")"></i>
</th>
<th>
@Html.ActionLink("Salary", "Employee", new { sortOrder = ViewBag.SalarySortParam, currentFilter = ViewBag.CurrentFilter })
<i class="glyphicon @(ViewBag.CurrentSort== "salary_desc" ? "glyphicon-sort-by-order-alt" : "glyphicon-sort-by-order")"></i>
</th>
</tr>
</thead>
@if (ViewData["Employee"] != null)
{
var dt = ViewData["Employee"] as System.Data.DataTable;
foreach (System.Data.DataRow dr in dt.Rows)
{
<tbody>
<tr>
<td>
@dr["EmpId"]
</td>
<td>
@dr["Name"]
</td>
<td>
@dr["Address"]
</td>
<td>
@dr["Salary"]
</td>
</tr>
</tbody>
}
}
</table>
Scripts inside Employee View
$(document).ready(function () {
PartialViewUpdate();
});
function PartialViewUpdate() {
var partial = $('#EmployeePartial');
var form = $('#EmployeeReport');
$.ajax({
url: '@Url.Action("EmployeeFilter", "Employee")',
type: 'Post',
data: form.serialize(),
success: function (data) {
console.log('success');
partial.html(data);
}
});
};
$('#Search').click(function () {
debugger;
var partial = $('#EmployeePartial');
var form = $('#EmployeeReport');
$.ajax({
url: '@Url.Action("Employee", "Employee")',
type: 'Post',
data: form.serialize(),
success: function (data) {
PartialViewUpdate();
}
});
});
Upvotes: 0
Views: 229
Reputation: 2890
OK as discussed, I've taken what you've got so far and made it work, but with changes!
Code
public class EmployeeController : Controller
{
// GET: Employee
public ActionResult EmployeeSearch()
{
var model = ReturnViewModel();
return View(model);
}
public EmployeeViewModel ReturnViewModel()
{
var model = new EmployeeViewModel()
{
CountriesList = new List<SelectListItem>
{
new SelectListItem { Value = "1", Text = "India" },
new SelectListItem { Value = "2", Text = "Sri Lanka" },
new SelectListItem { Value = "3", Text = "Pakistan" },
new SelectListItem {Value = "4", Text = "USA" }
},
Departments = new List<SelectListItem>
{
new SelectListItem {Value = "1", Text="Finance", Selected=true },
new SelectListItem {Value = "2", Text = "IT" },
new SelectListItem {Value = "3", Text = "Sales" },
}
};
model.CurrentSearchOrder = "ASC";
model.EmployeesFound= new List<Employee>();
return model;
}
public PartialViewResult TestEmployeeSearchService(EmployeeViewModel model)
{
//Simulated service - I presume you have list of employees somewhere.
var list = new List<Employee>()
{
new Employee() {EmpId =1, Name = "John Smith", Address="1 MyStreet MyTown", CountryID = 4, DepartmentID = 2,Salary= 30000}, // - I.T.
new Employee() {EmpId= 2, Name = "Chander Deepak", Address="9 MyRoad MyVillage", CountryID = 1, DepartmentID = 1, Salary = 30000} , //India - Finance
new Employee() {EmpId = 3, Name = "Pritesh Shah", Address="20 MyRoad MyVillage", CountryID = 1, DepartmentID = 1, Salary = 35000} //India - Finance
};
//Employees matching countryid
var employeesInCountry = list.Where(e => e.CountryID == model.CountryID).ToList();
//Department ID
model.EmployeesFound = model.DepartmentID != 0 ? employeesInCountry.Where(e => e.DepartmentID == model.DepartmentID).ToList() : employeesInCountry;
return PartialView("_EmployeePartial", model);
}
public PartialViewResult SortEmployeeData(EmployeeViewModel model, string columnToSort, string sortOrder)
{
ModelState.Clear();
model.EmployeesFound = ReturnSortedEmployees(model.EmployeesFound, columnToSort, sortOrder);
model.CurrentSearchOrder = sortOrder == "ASC" ? "DESC" : "ASC";
return PartialView("_EmployeePartial", model);
}
public List<Employee> ReturnSortedEmployees(List<Employee> countryList, string columnToSort, string order)
{
List<Employee> sortedData;
switch (columnToSort)
{
case "EmpID":
sortedData = order == "ASC" ? countryList.OrderBy(s => s.EmpId).ToList() : countryList.OrderByDescending(s => s.EmpId).ToList();
break;
case "Name":
sortedData = order == "ASC" ? countryList.OrderBy(s => s.Name).ToList() : countryList.OrderByDescending(s => s.Name).ToList();
break;
case "Address":
sortedData = order == "ASC" ? countryList.OrderBy(s => s.Address).ToList() : countryList.OrderByDescending(s => s.Address).ToList();
break;
case "Salary":
sortedData = order == "ASC" ? countryList.OrderBy(s => s.Salary).ToList() : countryList.OrderByDescending(s => s.Salary).ToList();
break;
default:
sortedData = countryList.OrderBy(s => s.Name).ToList();
break;
}
return sortedData;
}
}
public class EmployeeViewModel
{
public IEnumerable<SelectListItem> CountriesList { get; set; }
public IEnumerable<SelectListItem> Departments { get; set; }
public List<Employee> EmployeesFound { get; set; }
public int DepartmentID { get; set; }
public int CountryID { get; set; }
public string CurrentSearchOrder { get; set; }
}
public class Employee
{
public int EmpId { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public int Salary { get; set; }
public int? CountryID { get; set; }
public int DepartmentID { get; set; }
}
}
Main Employee view
@model EmployeeViewModel
@{
ViewBag.Title = "EmployeeSearch";
}
@{ Layout = null; }
<script src="~/Content/Scripts/jquery-3.2.1.js"></script>
<script src="~/Content/Scripts/bootstrap.min.js"></script>
<script src="~/Content/Scripts/jquery-ui-1.11.4.js"></script>
<h2>Employee Search</h2>
<div class="col-md-2">
@using (Html.BeginForm("", "", FormMethod.Post, new { @id = "EmployeeReport" }))
{
<div class="panel panel-default">
<div class="panel-body">
<div>
<b>@Html.DisplayName("Country")</b>
@Html.DropDownListFor(m => m.CountryID, Model.CountriesList)
</div>
<div>
@Html.DisplayName("Department")
@Html.DropDownListFor(m => m.DepartmentID, Model.Departments)
</div>
<div>
<button type="button" id="Search">Search</button>
</div>
</div>
</div>
<div id="divEmployees">
@Html.Partial("_EmployeePartial", Model)
</div>
}
</div>
<style>
.sortable-link {
cursor: pointer;
}
</style>
<script>
$(document).on('click', '.sortable-link', function () {
var formData = $("#EmployeeReport").serialize();
var sortUrl = $(this).data('sorturl');
$.ajax({
type: "POST",
url: sortUrl,
data: formData,
success: function (data) {
$("#divEmployees").html(data);
}
});
});
$('#Search').click(function () {
var form = $('#EmployeeReport');
$.ajax({
url: '@Url.Action("TestEmployeeSearchService", "Employee")',
type: 'Post',
data: form.serialize(),
success: function (data) {
$("#divEmployees").html(data);
}
});
});
</script>
Partial view
@model EmployeeViewModel
<table>
<thead>
<tr>
<th>
<a class="sortable-link" data-sorturl="/Employee/SortEmployeeData?columnToSort=EmpID&[email protected]">ID</a>
<span class="glyphicon @(Model.CurrentSearchOrder == "DESC" ? "glyphicon-sort-by-order-alt" : "glyphicon-sort-by-order")"></span>
</th>
<th>
<a class="sortable-link" data-sorturl="/Employee/SortEmployeeData?columnToSort=Name&[email protected]">Name</a>
<span class="glyphicon @(Model.CurrentSearchOrder == "DESC" ? "glyphicon-sort-by-order-alt" : "glyphicon-sort-by-order")"></span>
</th>
<th>
<a class="sortable-link" data-sorturl="/Employee/SortEmployeeData?columnToSort=Address&[email protected]">Address</a>
<span class="glyphicon @(Model.CurrentSearchOrder == "DESC" ? "glyphicon-sort-by-order-alt" : "glyphicon-sort-by-order")"></span>
</th>
<th>
<a class="sortable-link" data-sorturl="/Employee/SortEmployeeData?columnToSort=Salary&[email protected]">Salary</a>
<span class="glyphicon @(Model.CurrentSearchOrder == "DESC" ? "glyphicon-sort-by-order-alt" : "glyphicon-sort-by-order")"></span>
</th>
</tr>
</thead>
@for (int counter = 0; counter <= Model.EmployeesFound.Count -1; counter++)
{
<tr>
<td>
@Html.TextBoxFor(m => m.EmployeesFound[counter].EmpId, null, new { @class = "form-control" })
</td>
<td>
@Html.TextBoxFor(m => m.EmployeesFound[counter].Name, null, new { @class = "form-control" })
</td>
<td>
@Html.TextBoxFor(m=> m.EmployeesFound[counter].Address, null, new{@class="form-control"})
</td>
<td>
@Html.TextBoxFor(m=> m.EmployeesFound[counter].Salary, null, new{@class="form-control"})
</td>
</tr>
}
</table>
@Html.HiddenFor(x=> x.CurrentSearchOrder)
Please look at the separation of the main view from the partial and how the Links to the Sort method are constructed and selected via JQuery. STOP using ViewBag and use models for your views. Its MVC! where M = Model.. not viewbag!
all the best
Upvotes: 3