MVC3 WebGrid toggling sort direction - asp.net-mvc-3

With an ASP.NET MVC3 WebGrid how can I setup the column sorting such that clicking on the column heading toggles between ascending sort and then descending sort?
Thanks!
Rob

The underlying problem turned out to be a malformed column. The columnName did not in fact match the actual columnName (it was set to be the header text). This problem was hidden because the format specified a Html.ActionLink.
Changing the column definition such that the columnName was correct (and the header set to the actual header value) corrected the problem.

Note 1: Using Razor Syntax for Markup and C# as ServerSide Code.
Note 2: The basic setup knowledge for Sorting came from Sorting, Filtering, and Paging with the Entity Framework Tutorial but I needed more control and leverage than what they supplied for their simple example.
So...
Here is the End-Result-View View for the Grid
Default View http://cognitivegenerationenterprises.net/cgeCorp/Images/Toggling-MVC-Grid/defaultGrid3.png
Here is my ServerSide code on the Index Action (so when my page loads) (again, see link above for more background information)
public ViewResult Index(string sortOrder)
{
// Set the defaults
ViewBag.FirstNameSortParam = "First Name desc";
ViewBag.LastNameSortParam = "Last Name desc";
ViewBag.CitySortParam = "City desc";
ViewBag.StateSortParam = "State desc";
ViewBag.DOBSortParam = "DOB desc";
var students = from s in db.Students select s;
switch (sortOrder)
{
case "First Name desc":
students = students.OrderByDescending(s => s.FirstName);
ViewBag.FirstNameSortParam = sortOrder;
break;
case "First Name asc":
students = students.OrderBy(s => s.FirstName);
ViewBag.FirstNameSortParam = sortOrder;
break;
case "Last Name desc":
students = students.OrderByDescending(s => s.LastName);
ViewBag.LastNameSortParam = sortOrder;
break;
case "Last Name asc":
students = students.OrderBy(s => s.LastName);
ViewBag.LastNameSortParam = sortOrder;
break;
case "City desc":
students = students.OrderByDescending(s => s.StudentAddress.City);
ViewBag.CitySortParam = sortOrder;
break;
case "City asc":
students = students.OrderBy(s => s.StudentAddress.City);
ViewBag.CitySortParam = sortOrder;
break;
case "State desc":
students = students.OrderByDescending(s => s.StudentAddress.State);
ViewBag.StateSortParam = sortOrder;
break;
case "State asc":
students = students.OrderBy(s => s.StudentAddress.State);
ViewBag.StateSortParam = sortOrder;
break;
case "DOB desc":
students = students.OrderByDescending(s => s.DOB);
ViewBag.DOBSortParam = sortOrder;
break;
case "DOB asc":
students = students.OrderBy(s => s.DOB);
ViewBag.DOBSortParam = sortOrder;
break;
default:
students = students.OrderByDescending(s => s.StudentID);
break;
}
return View(students.ToList());
}
The first time this runs, of course "sortOrder" will be null. However the pattern below demonstrates how I accomplished toggling of the "Last Name" column. Also, please note that I set my default 1st state to be Descending. Alternatively you could flip-it-around if you want Ascending as the 1st state registered when a user clicks on the link. For my purposes "Descending" works best.
#{
string fnSort = ViewBag.FirstNameSortParam;
string lnSort = ViewBag.LastNameSortParam;
string citySort = ViewBag.CitySortParam;
string stateSort = ViewBag.StateSortParam;
string dobSort = ViewBag.DOBSortParam;
}
<table>
<tr>
<th>
#{
if (fnSort != "First Name desc")
{
fnSort = "First Name desc";
}else{
fnSort = "First Name asc";
}
}
#Html.ActionLink("First Name", "Index", new { sortOrder = fnSort })
</th>
<th>
#{
if (lnSort != "Last Name desc")
{
lnSort = "Last Name desc";
}else{
lnSort = "Last Name asc";
}
}
#Html.ActionLink("Last Name", "Index", new { sortOrder = lnSort })
</th>
<th>
Email
</th>
<th>
Phone Number
</th>
<th>
#{
if (citySort != "City desc")
{
citySort = "City desc";
}else{
citySort = "City asc";
}
}
#Html.ActionLink("City", "Index", new { sortOrder = citySort })
</th>
<th>
#{
if (stateSort != "State desc")
{
stateSort = "State desc";
}else{
stateSort = "State asc";
}
}
#Html.ActionLink("State", "Index", new { sortOrder = stateSort })
</th>
<th>
#{
if (dobSort != "DOB desc")
{
dobSort = "DOB desc";
}else{
dobSort = "DOB asc";
}
}
#Html.ActionLink("DOB", "Index", new { sortOrder = dobSort })
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.FirstName)
</td>
<td>
#Html.DisplayFor(modelItem => item.LastName)
</td>
<td>
#Html.DisplayFor(modelItem => item.Email)
</td>
<td>
#Html.DisplayFor(modelItem => item.PhoneNumber)
</td>
<td>
#Html.DisplayFor(modelItem => item.StudentAddress.City)
</td>
<td>
#Html.DisplayFor(modelItem => item.StudentAddress.State)
</td>
<td>
#Html.DisplayFor(modelItem => item.DOB)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.StudentID }) |
#Html.ActionLink("Details", "Details", new { id=item.StudentID }) |
#Html.ActionLink("Delete", "Delete", new { id=item.StudentID })
</td>
</tr>
}
</table>
That's it... Toggling works now for "Last Name"... now I will implement sort toggling for the other columns as well
Hope this helps. Let me know if you need more assistance! I'm proud to help (if I can)
Cheers!

Related

.NET Core 6 Pull Down Menu Selection to Group through View Model

I am having partial success searching / grouping data through a viewmodel:
Partial Success:
URL Value
If I search on "B"
https://localhost:7207/Class01Name/Index2?String02NameSelected=B&SearchString=
Problem:
Not filtering data...simply changes pull down menu back to "All," displaying all data. Data not filtered.
**Question:
**
What in the code has to be changed to have the data filtered successfully?
Question is based on Tutorial at:
https://learn.microsoft.com/en-us/aspnet/core/tutorials/first-mvc-app/search?view=aspnetcore-6.0
Model
using System.ComponentModel.DataAnnotations; // Date Format
namespace Project01Name.Models
{
public class Class01Name
{
public int Id { get; set; }
public string? String01Name { get; set; }
public string? String02Name { get; set; }
public int? Int01Name { get; set; }
public bool? Bool01Name { get; set; }
[DataType(DataType.Date)]
public DateTime? DateTime01Name { get; set; }
}
}
**
View Model
**
using Microsoft.AspNetCore.Mvc.Rendering;
using System.Collections.Generic;
namespace Project01Name.Models.ViewModelsName
{
public class SearchByGroupName
{
public List<Class01Name>? Class01NameList { get; set; } // A list of movies.
public SelectList? String02NameSelection { get; set; } // A SelectList containing the list of genres. This allows the user to select a genre from the list.
public string? String02NameSelected { get; set; } // MovieGenre, which contains the selected genre.
public string? SearchString { get; set; } // SearchString, which contains the text users enter in the search text box.
}
}
Controller Action Method
// GET: String01Names
public async Task<IActionResult> Index2(string class01NameGroup, string searchString)
{
// Use LINQ to get list of genres.
IQueryable<string> string02NameQuery = from m in _context.Class01Name
orderby m.String02Name
select m.String02Name;
var selectVariable = from m in _context.Class01Name
select m;
if (!string.IsNullOrEmpty(searchString))
{
selectVariable = selectVariable.Where(s => s.String01Name!.Contains(searchString));
}
if (!string.IsNullOrEmpty(class01NameGroup))
{
selectVariable = selectVariable.Where(x => x.String02Name == class01NameGroup);
}
var string02NameVM = new SearchByGroupName
{
String02NameSelection = new SelectList(await string02NameQuery.Distinct().ToListAsync()),
Class01NameList = await selectVariable.ToListAsync()
};
return View(string02NameVM);
}
View
#model Project01Name.Models.ViewModelsName.SearchByGroupName
#{
ViewData["Title"] = "Index";
}
<h1>Index</h1>
<p>
<a asp-action="Create">Create New</a>
</p>
<form asp-action="Index2" method="get">
<div class="form-actions no-color">
<p>
<select asp-for="String02NameSelected" asp-items="Model.String02NameSelection"> <option value="">All</option></select>
Title: <input type="text" asp-for="SearchString" />
<input type="submit" value="Filter" />
#*<input type="submit" value="Search" class="btn btn-default" /> |
<a asp-action="Index">Back to Full List</a> *#
</p>
</div>
</form>
<table class="table">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.Class01NameList[0].String01Name)
</th>
<th>
#Html.DisplayNameFor(model => model.Class01NameList[0].String02Name)
</th>
<th>
#Html.DisplayNameFor(model => model.Class01NameList[0].Int01Name)
</th>
<th>
#Html.DisplayNameFor(model => model.Class01NameList[0].DateTime01Name)
</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model.Class01NameList)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.String01Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.String02Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.Int01Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.DateTime01Name)
</td>
<td>
<a asp-action="Edit" asp-route-id="#item.Id">Edit</a> |
<a asp-action="Details" asp-route-id="#item.Id">Details</a> |
<a asp-action="Delete" asp-route-id="#item.Id">Delete</a>
</td>
</tr>
}
</tbody>
</table>
Partial Success:
URL Value
If I search on "B"
https://localhost:7207/Class01Name/Index2?String02NameSelected=B&SearchString=
Problem:
Not filtering data...simply changes pull down menu back to "All," displaying all data. Data not filtered.
**Question:
**
What in the code has to be changed to have the data filtered successfully?
Question is based on Tutorial at:
https://learn.microsoft.com/en-us/aspnet/core/tutorials/first-mvc-app/search?view=aspnetcore-6.0
Not filtering data...simply changes pull down menu back to "All,"
displaying all data. Data not filtered.
**Question: ** What in the code has to be changed to have the data filtered successfully?
Well, seems you wanted to implement searching functionality in way, so that you can filter with the dropdown and search box and finally if you select All as dropdown value you want to load all the list without any filter and shorting means the full list which comes at first view.
If so, you need to use javascript for your dropdown change event as cshtml doesn't deal with change event. In addition, as you are using asp.net core MVC which would return HTML View altough, we need json data for Ajax reponse but we are would bee getting HTML View. So Ajax success Function will through an error where we would use filter with All parameter.
Modification Required:
Javascript:
#section scripts {
<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.2.1.min.js"></script>
<script src="https://cdn.datatables.net/1.11.3/js/jquery.dataTables.min.js"></script>
<script>
$(document).ready(function () {
$("#allId").change(function () {
alert("Click");
var allId = $('#allId').val();
console.log(allId);
if (allId == "All") {
alert("Alert");
$.ajax({
url: 'http://localhost:5094/Search/Index2',
type: 'GET',
dataType: 'json',
data: { String02NameSelected: "All", searchString: "" },
success: function (response) {
},
error: function () {
window.location.href = "#Url.Action("Index2", "Search")?String02NameSelected=All&SearchString=";
}
});
}
});
});
</script>
}
Note:
As you can see, in success function we are doing nothing, because it will always throuh an error because we are not returning json. Thus, we will work in error section. indow.location.href = "#Url.Action("Index2", "Search")?String02NameSelected=All&SearchString=";. Here, for your understanding, we will call this function when we select All as our dropdown value in that scenario, we will pass All and nothing , nothing will convert into null and all will be our search key.
Modify Your Existing View:
In your existing view, replace blow dropdown code snippet , means the select items
<select asp-for="String02NameSelected" id="allId" asp-items="Model.String02NameSelection"> <option value="All">All</option></select>
Note: If you notice I hav introduced a id id="allId" which will be using on dropdown change event.
Controller:
public async Task<IActionResult> Index2(string String02NameSelected, string searchString)
{
if (String02NameSelected == "All" && searchString == null)
{
var dataWithoutfileter = new SearchByGroupName();
dataWithoutfileter.String02NameSelection = new SelectList(String02NameSelectionList, "Text", "Value");
dataWithoutfileter.Class01NameList = listOfClass01Name;
return View(dataWithoutfileter);
}
if (!String.IsNullOrEmpty(String02NameSelected) && String02NameSelected !="All")
{
var objOfClass = new SearchByGroupName();
var string02NameQuery = listOfClass01Name.Where(m => m.String01Name.ToLower().Contains(String02NameSelected.ToLower()) || m.String02Name.ToLower().Contains(String02NameSelected.ToLower()));
objOfClass.Class01NameList = string02NameQuery.ToList();
objOfClass.String02NameSelection = new SelectList(String02NameSelectionList, "Text", "Value");
return View(objOfClass);
}
if (!String.IsNullOrEmpty(searchString))
{
var objOfClass = new SearchByGroupName();
var string02NameQuery = listOfClass01Name.Where(m => m.String01Name.ToLower().Contains(searchString.ToLower()) || m.String02Name.ToLower().Contains(searchString.ToLower()));
objOfClass.Class01NameList = string02NameQuery.ToList();
objOfClass.String02NameSelection = new SelectList(String02NameSelectionList, "Text", "Value");
return View(objOfClass);
}
//First loading
var objSearchByGroupName = new SearchByGroupName();
objSearchByGroupName.String02NameSelection = new SelectList(String02NameSelectionList, "Text", "Value");
objSearchByGroupName.Class01NameList = listOfClass01Name;
return View(objSearchByGroupName);
}
}
Complete Demo:
Full Controller With Seed Model Class Value:
public class SearchController : Controller
{
public static List<Class01Name> listOfClass01Name = new List<Class01Name>()
{
new Class01Name() { Id =101, String01Name ="Titanic",String02Name = "Romantic", Int01Name =01, Bool01Name = false, DateTime01Name = new DateTime(2023-01-15) },
new Class01Name() { Id =102, String01Name ="Forest gump",String02Name = "Motivational", Int01Name =02, Bool01Name = true, DateTime01Name = new DateTime(2023-01-12) },
new Class01Name() { Id =103, String01Name ="Spider Man",String02Name = "Action", Int01Name =03, Bool01Name = false, DateTime01Name = new DateTime(2023-01-10) },
new Class01Name() { Id =104, String01Name ="Harry Potter",String02Name = "Suspense", Int01Name =04, Bool01Name = true, DateTime01Name = new DateTime(2023-01-13)},
};
public List<SelectListItem> String02NameSelectionList = new List<SelectListItem>()
{
new SelectListItem { Text = "Motivational", Value = "Motivational" },
new SelectListItem { Text = "Romantic", Value = "Romantic" },
new SelectListItem { Text = "Action", Value = "Action" },
new SelectListItem { Text = "Comedy", Value = "Comedy" }
};
public async Task<IActionResult> Index2(string String02NameSelected, string searchString)
{
if (String02NameSelected == "All" && searchString == null)
{
var dataWithoutfileter = new SearchByGroupName();
dataWithoutfileter.String02NameSelection = new SelectList(String02NameSelectionList, "Text", "Value");
dataWithoutfileter.Class01NameList = listOfClass01Name;
return View(dataWithoutfileter);
}
if (!String.IsNullOrEmpty(String02NameSelected) && String02NameSelected !="All")
{
var objOfClass = new SearchByGroupName();
var string02NameQuery = listOfClass01Name.Where(m => m.String01Name.ToLower().Contains(String02NameSelected.ToLower()) || m.String02Name.ToLower().Contains(String02NameSelected.ToLower()));
objOfClass.Class01NameList = string02NameQuery.ToList();
objOfClass.String02NameSelection = new SelectList(String02NameSelectionList, "Text", "Value");
return View(objOfClass);
}
if (!String.IsNullOrEmpty(searchString))
{
var objOfClass = new SearchByGroupName();
var string02NameQuery = listOfClass01Name.Where(m => m.String01Name.ToLower().Contains(searchString.ToLower()) || m.String02Name.ToLower().Contains(searchString.ToLower()));
objOfClass.Class01NameList = string02NameQuery.ToList();
objOfClass.String02NameSelection = new SelectList(String02NameSelectionList, "Text", "Value");
return View(objOfClass);
}
//First loading
var objSearchByGroupName = new SearchByGroupName();
objSearchByGroupName.String02NameSelection = new SelectList(String02NameSelectionList, "Text", "Value");
objSearchByGroupName.Class01NameList = listOfClass01Name;
return View(objSearchByGroupName);
}
}
Full View:
#model DotNet6MVCWebApp.Controllers.SearchByGroupName
#{
ViewData["Title"] = "Index";
}
<form asp-action="Index2" method="get">
<div class="form-actions no-color">
<p>
<select asp-for="String02NameSelected" id="allId" asp-items="Model.String02NameSelection"> <option value="All">All</option></select>
Title: <input type="text" asp-for="SearchString" />
<input type="submit" name="searchString" />
</p>
</div>
</form>
<table class="table">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.Class01NameList[0].String01Name)
</th>
<th>
#Html.DisplayNameFor(model => model.Class01NameList[0].String02Name)
</th>
<th>
#Html.DisplayNameFor(model => model.Class01NameList[0].Int01Name)
</th>
<th>
#Html.DisplayNameFor(model => model.Class01NameList[0].DateTime01Name)
</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model.Class01NameList)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.String01Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.String02Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.Int01Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.DateTime01Name)
</td>
<td>
<a asp-action="Edit" asp-route-id="#item.Id">Edit</a> |
<a asp-action="Details" asp-route-id="#item.Id">Details</a> |
<a asp-action="Delete" asp-route-id="#item.Id">Delete</a>
</td>
</tr>
}
</tbody>
</table>
#section scripts {
<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.2.1.min.js"></script>
<script src="https://cdn.datatables.net/1.11.3/js/jquery.dataTables.min.js"></script>
<script>
$(document).ready(function () {
$("#allId").change(function () {
alert("Click");
var allId = $('#allId').val();
console.log(allId);
if (allId == "All") {
alert("Alert");
$.ajax({
url: 'http://localhost:5094/Search/Index2',
type: 'GET',
dataType: 'json',
data: { String02NameSelected: "All", searchString: "" },
success: function (response) {
},
error: function () {
window.location.href = "#Url.Action("Index2", "Search")?String02NameSelected=All&SearchString=";
}
});
}
});
});
</script>
}
Output:

how to dynamically edit the bind data in sql using mvc3 web grid

i am new to mvc.. i have a task that, i have to bind data from existing table in sql using asp.net mvc3(Razor) Web Grid .. now i have to edit the data in webGrid.. i dont know how the edit operation is going to made... Plzz Help me out...
i have given my bind data.. plz let me know how to edit it...
Controller:
public ActionResult Index()
{
var list = GetList();
return View(list);
}
public List<Teacher> GetList()
{
var modelList = new List<Teacher>();
using (SqlConnection conn = new SqlConnection(#"Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=Demo;Data Source=CIPL41\SQLEXPRESS"))
{
conn.Open();
SqlCommand dCmd = new SqlCommand("Select T_Id,T_Name,T_Address,Sub_Id from teacher", conn);
SqlDataAdapter da = new SqlDataAdapter(dCmd);
DataSet ds = new DataSet();
da.Fill(ds);
conn.Close();
for (int i = 0; i <= ds.Tables[0].Rows.Count - 1; i++)
{
var model = new Teacher();
model.T_Id = Convert.ToInt32(ds.Tables[0].Rows[i]["T_Id"]);
model.T_Name = ds.Tables[0].Rows[i]["T_Name"].ToString();
model.T_Address = ds.Tables[0].Rows[i]["T_Address"].ToString();
model.Sub_Id = ds.Tables[0].Rows[i]["Sub_Id"].ToString();
modelList.Add(model);
}
}
return modelList;
}
//
Index.cshtml
#model IEnumerable<MvcApplication1.Models.Teacher>
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
#using (Html.BeginForm("Index", "Teacher"))
{
<table>
<tr>
<th></th>
<th>
T_Id
</th>
<th>
T_Name
</th>
<th>
T_Address
</th>
<th>
Sub_Id
</th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.T_Id }) |
#* #Html.ActionLink("Details", "Details", new { id=item.T_Id }) |*#
#Html.ActionLink("Delete", "Delete", new { id=item.T_Id })
</td>
<td>
#Html.TextBox("T_Id", item.T_Id , new { #style = "width:100px;" })
</td>
<td>
#Html.TextBox("T_Name", item.T_Name , new { #style = "width:100px;" })
</td>
<td>
#Html.TextBox("T_Address", item.T_Address , new { #style = "width:100px;" })
</td>
<td>
#Html.TextBox("Sub_Id",item.Sub_Id,new { #style = "width:100px;"})
</td>
</tr>
}
</table>
Plz help me out....
Have a look at this tutorial http://www.asp.net/mvc/tutorials/getting-started-with-aspnet-mvc3/cs/examining-the-edit-methods-and-edit-view
I think it explains exactly what you're trying to do.

selected item in dropdownlist mvc3

Mvc3 dropdownlistFor is deriving me crazy!!!
I have two selects with the same code (different tevt and values) but one of them not works.
here is my Controller code:
[Authorize(Roles = "admins")]
public ActionResult Edit(int id = -1)
{
Advertise Advertise = db.Advertises.Find(id);
if (null == Advertise)
return View("ProductNotFound");
var selectListItems = new List<SelectListItem>();
selectListItems.Add(new SelectListItem { Text = "A", Value = "A", Selected = ("A" == Advertise.Class) });
selectListItems.Add(new SelectListItem { Text = "B", Value = "B", Selected = ("B" == Advertise.Class) });
selectListItems.Add(new SelectListItem { Text = "C", Value = "C", Selected = ("C" == Advertise.Class) });
selectListItems.Add(new SelectListItem { Text = "D", Value = "D", Selected = ("D" == Advertise.Class) });
ViewBag.Class = new SelectList(selectListItems, "Value", "Text",Advertise.Class);
var selectListItems2 = new List<SelectListItem>();
selectListItems2.Add(new SelectListItem { Text = "Image", Value = "Image", Selected = ("Image" == Advertise.FileType) });
selectListItems2.Add(new SelectListItem { Text = "Flash", Value = "Flash", Selected = ("Flash" == Advertise.FileType) });
ViewBag.Type = new SelectList(selectListItems2, "Value", "Text",Advertise.FileType);
return View(Advertise);
}
and here is my view code:
<tr>
<td class="label">
#Html.LabelFor(model => model.Class) :
</td>
<td class="editor-field">
#Html.DropDownListFor(model => model.Class, (SelectList)ViewBag.Class)
#Html.ValidationMessageFor(model => model.Class)
</td>
</tr>
<tr>
<td class="label">
#Html.LabelFor(model => model.FileType) :
</td>
<td class="editor-field">
#Html.DropDownListFor(model => model.FileType, (SelectList)ViewBag.Type)
#Html.ValidationMessageFor(model => model.FileType)
</td>
</tr>
the secound select works perfectly and the first one (class) doesn't select the selected item on page load.
and for the record, the value stored in the database is C.
please help!!!
What a ...!!!!
I found out the reason of not working select is: the name of my variable (ViewBag.Class) is the same as my Field in the model!!! I change ViewBag.Class to ViewBag.glass (just to change the name) and it worked!!!
thanks anyway.
I hope it helps somebody which has this problem!!!

ASP.NET MVC 3 PagedList. The method 'Skip' is only supported for sorted input in LINQ to Entities.

Why is it it gives error in return View(contacts.ToPagedList(pageNumber, pageSize)); statement the error in the Index method :
The method 'Skip' is only supported for sorted input in LINQ to Entities. The method 'OrderBy' must be called before the method 'Skip'.
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using PhoneBook.Models;
using PagedList;
namespace PhoneBook.Controllers
{
public class ContactsController : Controller
{
private PhoneDBContext db = new PhoneDBContext();
//
// GET: /Contacts/
public ViewResult Index(string searchString, string sortOrder, Contact model, string currentFilter, int? page)
{
ViewBag.CurrentSort = sortOrder;
ViewBag.FNameSortParm = sortOrder == "FName asc"? "FName desc" : "FName asc";
ViewBag.DateSortParm = sortOrder == "Date asc" ? "Date desc" : "Date asc";
ViewBag.LNameSortParm = sortOrder == "LName asc" ? "LName desc" : "LName asc";
ViewBag.CompSortParm = sortOrder == "Company asc" ? "Company desc" : "Company asc";
ViewBag.MobSortParm = sortOrder == "Mob asc" ? "Mob desc" : "Mob asc";
ViewBag.TelSortParm = sortOrder == "Tel asc" ? "Tel desc" : "Tel asc";
if (Request.HttpMethod == "GET") { searchString = currentFilter; }
else {page = 1;}
ViewBag.CurrentFilter = searchString;
var contacts = from m in db.Contacts
select m;
switch (sortOrder)
{
case "FName desc":
contacts = contacts.OrderByDescending(s => s.FirstName);
break;
case "FName asc":
contacts = contacts.OrderBy(s => s.FirstName);
break;
case "LName desc":
contacts = contacts.OrderByDescending(s => s.LastName);
break;
case "LName asc":
contacts = contacts.OrderBy(s => s.LastName);
break;
case "Company desc":
contacts = contacts.OrderByDescending(s => s.Company);
break;
case "Company asc":
contacts = contacts.OrderBy(s => s.Company);
break;
case "Date desc":
contacts = contacts.OrderByDescending(s => s.DateAdded);
break;
case "Date asc":
contacts = contacts.OrderBy(s => s.DateAdded);
break;
case "Mob desc":
contacts = contacts.OrderByDescending(s => s.MobileNumber);
break;
case "Mob asc":
contacts = contacts.OrderBy(s => s.MobileNumber);
break;
case "Tel desc":
contacts = contacts.OrderByDescending(s => s.TelephoneNumber);
break;
case "Tel asc":
contacts = contacts.OrderBy(s => s.TelephoneNumber);
break;
}
if (!String.IsNullOrEmpty(searchString))
{
contacts = contacts.Where(s => s.LastName.ToUpper().Contains(searchString)||s.FirstName.ToUpper().Contains(searchString)||s.Company.ToUpper().Contains(searchString));
}
int pageSize = 3;
int pageNumber = (page ?? 1);
return View(contacts.ToPagedList(pageNumber, pageSize));
}
//
// GET: /Contacts/Details/5
public ViewResult Details(int id)
{
Contact contact = db.Contacts.Find(id);
return View(contact);
}
//
// GET: /Contacts/Create
public ActionResult Create()
{
return View();
}
//
// POST: /Contacts/Create
[HttpPost]
public ActionResult Create(Contact contact)
{
if (ModelState.IsValid)
{
db.Contacts.Add(contact);
contact.DateAdded = DateTime.Now;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(contact);
}
//
// GET: /Contacts/Edit/5
public ActionResult Edit(int id=0)
{
Contact contact = db.Contacts.Find(id);
if (contact == null) { return HttpNotFound(); } // returns blank page if id is not valid
return View(contact);
}
//
// POST: /Contacts/Edit/5
[HttpPost]
public ActionResult Edit(Contact contact)
{
if (ModelState.IsValid)
{
db.Entry(contact).State = EntityState.Modified;
contact.DateAdded = DateTime.Now;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(contact);
}
//
// GET: /Contacts/Delete/5
public ActionResult Delete(int id)
{
Contact contact = db.Contacts.Find(id);
if (contact == null) { return HttpNotFound(); }
return View(contact);
}
//
// POST: /Contacts/Delete/5
[HttpPost, ActionName("Delete")]
public ActionResult DeleteConfirmed(int id)
{
Contact contact = db.Contacts.Find(id);
if (contact == null) { return HttpNotFound(); }
db.Contacts.Remove(contact);
db.SaveChanges();
return RedirectToAction("Index");
}
public ActionResult SearchIndex(string searchString)
{
var contacts = from m in db.Contacts
select m;
if (!String.IsNullOrEmpty(searchString))
{
contacts = contacts.Where(s => s.LastName.Contains(searchString));
}
return View(contacts);
}
protected override void Dispose(bool disposing)
{
db.Dispose();
base.Dispose(disposing);
}
}
}
below is the Index.cshtml code:
#model PagedList.IPagedList<PhoneBook.Models.Contact>
#{
ViewBag.Title = "Phone Book";
}
<p>
#using (Html.BeginForm()){
<p> Search: #Html.TextBox("SearchString", ViewBag.CurrentFilter as string)
<input type="submit" value="Go" /></p>
}
</p>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table>
<tr>
<th>
#Html.ActionLink("First Name", "Index", new { sortOrder=ViewBag.FNameSortParm, currentFilter=ViewBag.CurrentFilter })
</th>
<th>
#Html.ActionLink("Last Name", "Index", new { sortOrder = ViewBag.LNameSortParm, currentFilter = ViewBag.CurrentFilter })
</th>
<th>
#Html.ActionLink("Mobile Num", "Index", new { sortOrder = ViewBag.MobSortParm, currentFilter = ViewBag.CurrentFilter })
</th>
<th>
#Html.ActionLink("Tel Num", "Index", new { sortOrder = ViewBag.TelSortParm, currentFilter = ViewBag.CurrentFilter })
</th>
<th>
#Html.ActionLink("Company", "Index", new { sortOrder = ViewBag.CompSortParm, currentFilter = ViewBag.CurrentFilter })
</th>
<th>
#Html.ActionLink("Date Added/Updated", "Index", new { sortOrder = ViewBag.DateSortParm, currentFilter = ViewBag.CurrentFilter })
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.FirstName)
</td>
<td>
#Html.DisplayFor(modelItem => item.LastName)
</td>
<td>
#Html.DisplayFor(modelItem => item.MobileNumber)
</td>
<td>
#Html.DisplayFor(modelItem => item.TelephoneNumber)
</td>
<td>
#Html.DisplayFor(modelItem => item.Company)
</td>
<td>
#Html.DisplayFor(modelItem => item.DateAdded)
</td>
<td>
#Html.ActionLink("Details", "Details", new { id=item.ID })
#Html.ActionLink("Edit", "Edit", new { id=item.ID })
#Html.ActionLink("Delete", "Delete", new { id=item.ID })
</td>
</tr>
}
</table>
<div>
Page #(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber)
of #Model.PageCount
#if (Model.HasPreviousPage)
{
#Html.ActionLink("<<", "Index", new { page = 1, sortOrder = ViewBag.CurrentSort, currentFilter=ViewBag.CurrentFilter })
#Html.Raw(" ");
#Html.ActionLink("< Prev", "Index", new { page = Model.PageNumber - 1, sortOrder = ViewBag.CurrentSort, currentFilter=ViewBag.CurrentFilter })
}
else
{
#:<<
#Html.Raw(" ");
#:< Prev
}
#if (Model.HasNextPage)
{
#Html.ActionLink("Next >", "Index", new { page = Model.PageNumber + 1, sortOrder = ViewBag.CurrentSort, currentFilter=ViewBag.CurrentFilter })
#Html.Raw(" ");
#Html.ActionLink(">>", "Index", new { page = Model.PageCount, sortOrder = ViewBag.CurrentSort, currentFilter=ViewBag.CurrentFilter })
}
else
{
#:Next >
#Html.Raw(" ")
#:>>
}
</div>
Try the following three changes.
Put this code before the switch statement:
if (!String.IsNullOrEmpty(searchString))
{
contacts = contacts.Where(s => s.LastName.ToUpper().Contains(searchString)||s.FirstName.ToUpper().Contains(searchString)||s.Company.ToUpper().Contains(searchString));
}
Add a default case in your switch statement, and make it throw.
switch (sortOrder) {
case ...:
...
default:
throw new ArgumentException("Bad sort order specified", "sortOrder");
}
Use the type IOrderedQueryable<T>.
IOrderedQueryable<T> orderedContacts;
switch (sortOrder)
{
case "FName desc":
orderedContacts = contacts.OrderByDescending(s => s.FirstName);
break;
...
}
...
return View(orderedContacts.ToPagedList(pageNumber, pageSize));
return View(orderedContacts.ToList().ToPagedList(pageNumber, pageSize));

Refresh portion of the page

I have a page that contains 3 divisions such as General, Attendee Information and Customized Questions (Partial view). The Customized questions will display a list of questions (textbox) along with the answer(dropdownlist) , which contains an edit button to modify the answer field in the dropdownlist. Now, when the edit button was clicked, a pop-up window will appear to modify the answer field, once the user clicked the save button the modified answer should reflects in the dropdownlist. I already created a partial view for Customized Questions but still the answer value didn't reflect the changes in the dropdownlist. Any sample codes or ideas?
Controller
[HttpPost]
public ActionResult UpdateAnswers(string answers, string question, string controlid, int eventid)
{
var replacetext=string.Empty;
if (answers.Length>0)
replacetext = answers.Replace("\n", ",");
_service.UpdateAnswers(eventid, replacetext, controlid);
var eventdetails = _service.GeteventByID(eventid);
return PartialView( "CustomizedQuestions", eventdetails);
}
Partial View
#using EM.Website.Helpers
#model EM.Model.tbl_SBAem_Event
#{
var dropdownList = new List<KeyValuePair<int, string>> {new KeyValuePair<int, string>(0, "Required"), new KeyValuePair<int, string>(1, "Optional"), new KeyValuePair<int, string>(2, "Hidden")};
var selectList = new SelectList(dropdownList, "key", "value", 0);
}
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
<table class="table-customized-question">
<tr>
<th class="td-customized-question-row"></th>
<th class="td-customized-question-row">Question Label</th>
<th class="td-customized-question-row">Display Mode</th>
<th class="td-customized-question-row">Answer Field</th>
<th class="td-customized-question-row">Edit Choices</th>
</tr>
<tr>
<td class="td-customized-question-firstrow">#1</td>
<td class="td-customized-question-row">#Html.EditorFor(model => model.EM_opt1Name)</td>
<td class="td-customized-question-row">#Html.DropDownListFor(model => model.EM_reqOpt1, selectList)</td>
<td class="td-customized-question-row">#Html.DropDownListFor(model => model.EM_opt1Values, #Html.SplitText(Model.EM_opt1Values, ','), new { #class = "dropdownlist-width" })</td>
<td>#Html.ActionImage("CustomizedQuestion", new { eventID = Model.EventMngID, question = Model.EM_opt1Name }, "~/Content/Images/edit.jpg", "Edit", new { #class = "editButton", title = Model.EM_opt1Name, answers = Model.EM_opt1Values, id = "EM_opt1Values", eventID = Model.EventMngID })</td>
</tr>
<tr>
<td class="td-customized-question-firstrow">#2</td>
<td class="td-customized-question-row">#Html.EditorFor(model => model.EM_opt2Name)</td>
<td class="td-customized-question-row">#Html.DropDownListFor(model => model.EM_reqOpt2, selectList)</td>
<td>#Html.ActionImage("CustomizedQuestion", new { eventID = Model.EventMngID, question = Model.EM_opt2Name }, "~/Content/Images/edit.jpg", "Edit", new { #class = "editButton", title = Model.EM_opt2Name, answers = Model.EM_opt2Values, id = "EM_opt2Values", eventID = Model.EventMngID })</td>
</tr>
<tr>
<td class="td-customized-question-firstrow">#3</td>
<td class="td-customized-question-row">#Html.EditorFor(model => model.EM_opt3Name)</td>
<td class="td-customized-question-row">#Html.DropDownListFor(model => model.EM_reqOpt3, selectList)</td>
<td class="td-customized-question-row">#Html.DropDownListFor(model => model.EM_opt3Values, #Html.SplitText(Model.EM_opt3Values, ','), new { #class = "dropdownlist-width" })</td>
<td>#Html.ActionImage("CustomizedQuestion", new { eventID = Model.EventMngID, question = Model.EM_opt3Name }, "~/Content/Images/edit.jpg", "Edit", new { #class = "editButton", title = Model.EM_opt3Name, answers = Model.EM_opt3Values, id = "EM_opt3Values", eventID = Model.EventMngID })</td>
</tr>
<tr>
<td class="td-customized-question-firstrow">#4</td>
<td class="td-customized-question-row">#Html.EditorFor(model => model.EM_opt4Name)</td>
<td class="td-customized-question-row">#Html.DropDownListFor(model => model.EM_reqOpt4, selectList)</td>
<td class="td-customized-question-row">#Html.DropDownListFor(model => model.EM_opt4Values, #Html.SplitText(Model.EM_opt4Values, ','), new { #class = "dropdownlist-width" })</td>
<td>#Html.ActionImage("CustomizedQuestion", new { eventID = Model.EventMngID, question = Model.EM_opt4Name }, "~/Content/Images/edit.jpg", "Edit", new { #class = "editButton", title = Model.EM_opt4Name, answers = Model.EM_opt4Values, id = "EM_opt4Values", eventID = Model.EventMngID })</td>
</tr>
<tr>
<td class="td-customized-question-firstrow">#5</td>
<td class="td-customized-question-row">#Html.EditorFor(model => model.EM_opt5Name)</td>
<td class="td-customized-question-row">#Html.DropDownListFor(model => model.EM_reqOpt5, selectList)</td>
<td class="td-customized-question-row">#Html.DropDownListFor(model => model.EM_opt5Values, #Html.SplitText(Model.EM_opt5Values, ','), new { #class = "dropdownlist-width" })</td>
<td>#Html.ActionImage("CustomizedQuestion", new { eventID = Model.EventMngID, question = Model.EM_opt5Name }, "~/Content/Images/edit.jpg", "Edit", new { #class = "editButton", title = Model.EM_opt5Name, answers = Model.EM_opt5Values, id = "EM_opt5Values", eventID = Model.EventMngID })</td>
</tr>
<tr>
<td class="td-customized-question-firstrow">#6</td>
<td class="td-customized-question-row">#Html.EditorFor(model => model.EM_opt6Name)</td>
<td class="td-customized-question-row">#Html.DropDownListFor(model => model.EM_reqOpt6, selectList)</td>
<td class="td-customized-question-row">#Html.DropDownListFor(model => model.EM_opt6Values, #Html.SplitText(Model.EM_opt6Values, ','), new { #class = "dropdownlist-width" })</td>
<td>#Html.ActionImage("CustomizedQuestion", new { eventID = Model.EventMngID, question = Model.EM_opt6Name }, "~/Content/Images/edit.jpg", "Edit", new { #class = "editButton", title = Model.EM_opt6Name, answers = Model.EM_opt6Values, id = "EM_opt6Values", eventID = Model.EventMngID })</td>
</tr>
</table>
}
Jquery-Ajax
$(".editButton").live("click", function (e) {
e.preventDefault();
var $title = $(this).attr("title");
var $answers = $(this).attr("answers");
var $controlid = $(this).attr("id");
var $eventId = $(this).attr("eventID");
dropdownlist($controlid, $title, $answers, $eventId);
});
function dropdownlist(controlid, title, answer, eventid) {
var $answersreplaced = answer.replace(/\,/g, " \r");
var $deleteDialog = $('<div><textarea id="answerlist" rows="10" cols="50">' + $answersreplaced + '</textarea><div><div style="font-size:9px">(To change back to an open answer field, delete all choices above and save)</div>');
$deleteDialog.dialog({
resizable: false,
height: 280,
width: 350,
title: title + " - Edit Choices",
modal: true,
buttons: {
"Save": function () {
$.ajax({
url: '#Url.Action("UpdateAnswers")',
type: 'POST',
dataType: 'html',
context: $(this),
data: {
answers: $("#answerlist").val(),
question: title,
controlid: controlid,
eventid: eventid
},
success: function (result) {
$(this).dialog("close");
alert(result);
$("#"+controlid+"").html(data);
},
error: function () {
//xhr, ajaxOptions, thrownError
alert('there was a problem saving the new answers, please try again');
}
});
},
Cancel: function () {
$(this).dialog("close");
}
}
});
};
Do my approach is correct?
Yes, your approach is correct. You could for example use jQuery UI dialog to implement the popup and editing part. The idea is to use AJAX in order to avoid refreshing the whole page but only the portion you are interested in. So the partial that will be shown in the modal dialog will contain a form that will be submitted to a controller action using AJAX and the server will return the partial view with the new information about the questions.
You must use
$.ajax({
type: "POST",
url: '#Url.Action("action", "controller")',
data: "{... parameterd}",
contentType: "application/json; charset=utf-8",
success: function (data) {
.. $("#yourDivID").html(data);
}
});
#using (Ajax.BeginForm("action", "controller", ajaxOptions)) , not
#using (Html.BeginForm())

Resources