MVC4 Filtering with checkboxes - asp.net-mvc

I have created create function in my controller which display all genres in checkoxes like this:
Controller:
public ActionResult Create()
{
var db = new MainDatabaseEntities();
var viewModel = new ANIME
{
GENRES = db.GENRES.Select(c => new { ID_GE = c.ID_GE, GENRE = c.GENRE, isSelected = false }).ToList().Select(g => new GENRES
{
ID_GE = g.ID_GE,
GENRE = g.GENRE,
isSelected = false
}).ToList()
};
return View(viewModel);
}
View:
#model AnimeWeb.Models.ANIME
#using (Html.BeginForm(null, null, FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<table>
<tr>
<td class="lefttablecontent" id="top">
<div class="editor-label">
#Html.HiddenFor(model => model.ID_AN)
</div>
<div class="editor-label">
Original title
</div>
<div class="editor-field">
#Html.EditorFor(model => model.TITLE_OR)
#Html.ValidationMessageFor(model => model.TITLE_OR)
</div>
<div class="editor-label">
English title
</div>
<div class="editor-field">
#Html.EditorFor(model => model.TITLE_EN)
#Html.ValidationMessageFor(model => model.TITLE_EN)
</div>
<div class="editor-label">
Genres
</div>
<div class="editor-list">
#Html.EditorFor(model => model.GENRES)
#Html.ValidationMessageFor(model => model.GENRES)
</div>
</td>
<td class="righttablecontent" id="top">
<p>
<input type="submit" value="Create" />
</p>
</td>
</tr>
</table>
}
}
EditorTemplate for Genres:
#model AnimeWeb.Models.GENRES
#Html.HiddenFor(model => model.ID_GE)
#Html.HiddenFor(model => model.GENRE)
<table>
<tr>
<td class=" right">
#Html.EditorFor(model => model.isSelected)
</td>
<td>
#Html.LabelFor(model => model.isSelected, Model.GENRE)
</td>
</tr>
</table>
Now I would like to display the same template with all genres and use it for filtering in index, but I'm not sure how to do this.
Controller:
public ActionResult Index(string sortOrder, string currentFilter, int? page)
{
using (var db = new MainDatabaseEntities())
{
ViewBag.CurrentSort = sortOrder;
if (searchString != null)
{
page = 1;
}
else
{
searchString = currentFilter;
}
ViewBag.CurrentFilter = searchString;
var anime = from s in db.ANIME.Include("GENRES")
select s;
int pageSize = 10;
int pageNumber = (page ?? 1);
return View(anime.ToPagedList(pageNumber, pageSize));
}
}
View:
#model PagedList.IPagedList<AnimeWeb.Models.ANIME>
#using PagedList.Mvc;
<link href="~/Content/PagedList.css" rel="stylesheet" type="text/css" />
#{
ViewBag.Title = "Index";
}
<p>
#if (Roles.IsUserInRole("Administrator"))
{
#Html.ActionLink("Create New", "Create")
}
</p>
#foreach (var item in Model) //
{ //
#Html.EditorFor(modelItem => item.GENRES); // I'm not sure about this line
} //
<table>
<tr>
<th>
Anime
</th>
<th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.ActionLink(item.TITLE_OR, "Details", new { id = item.ID_AN })
</td>
</tr>
}
</table>
<br />
Page #(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) of #Model.PageCount
#Html.PagedListPager(Model, page => Url.Action("Index",
new { page, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter }))
When I try to display it with #Html.EditorFor(modelItem => item.GENRES) it displays only genres that are selected within each anime but I need all genres to filter with them. I'm not even sure is this a good way to make it. Any suggestions?

Related

Date Fields losing dates when paging MVC

I have an MVC view with a fromDate and a toDate along with a bootstrap datepicker.
The date fields display initally like '15 June 2017'
However, when I do a search, page 1 displays correctly but when i go to any other page the dates reset and show as '06 January 2000'.
Any help would be most appreciated.
Thank you.
Controller:
using PagedList;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using WebApplication5.Models;
namespace WebApplication5.Controllers
{
public class testController : Controller
{
private JobSubmissionEntities1 db = new JobSubmissionEntities1();
public ViewResult Index(string currentFilter, string searchString, DateTime? fromDate, DateTime? toDate, int? page)
{
if (!fromDate.HasValue) fromDate = DateTime.Now.Date.AddDays(-1);
if (!toDate.HasValue) toDate = DateTime.Now.AddDays(5);
if (toDate < fromDate) toDate = DateTime.Now.AddDays(5);
ViewBag.fromDate = fromDate;
ViewBag.toDate = toDate;
//IF searchString is Empty
if (searchString != null)
{
page = 1;
}
else
{
searchString = currentFilter; fromDate = ViewBag.fromDate; toDate = ViewBag.toDate;
}
ViewBag.CurrentFilter = searchString;
var JobDetails = from s in db.JobDetails
select s;
//if searchString IS NOT empty
if (!String.IsNullOrEmpty(searchString))
{
JobDetails = JobDetails.Where(s =>
(s.JobNo.Equals(searchString) &&
s.SubmissionDate >= fromDate && s.SubmissionDate < toDate));
}
else
{
JobDetails = JobDetails.Where(s => (
s.SubmissionDate >= fromDate && s.SubmissionDate < toDate));
}
int pageSize = 10;
int pageNumber = (page ?? 1);
return View(JobDetails.OrderBy(i => i.JobNo).ToPagedList(pageNumber, pageSize));
}
}
}
View:
#model PagedList.IPagedList<WebApplication5.Models.JobDetail>
#using PagedList.Mvc;
<link href="~/Content/PagedList.css" rel="stylesheet" type="text/css" />
#{
Layout = "~/Views/Shared/_Layout_Wide.cshtml";
}
ViewBag.Title = "Index";
}
#section DatePicker {
<link href="~/Content/bootstrap.min.css" rel="stylesheet" />
<link href="~/Content/bootstrap-datetimepicker.min.css" rel="stylesheet" />
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script src="~/Scripts/moment-with-locales.min.js"></script>
<script src="~/Scripts/bootstrap.min.js"></script>
<script src="~/Scripts/bootstrap-datetimepicker.min.js"></script>
}
<h2>Index</h2>
#{
var fromDate = (DateTime)ViewBag.fromDate;
var toDate = (DateTime)ViewBag.toDate;
}
#using (Html.BeginForm("Index", "Test", FormMethod.Get))
{
/***FromDate***/
<div class="container">
<div class="row">
<div class='col-sm-3'>
<div class="form-group">
<div class='input-group date' id='fromDate'>
<div>#Html.TextBox("fromDate", string.Format("{0:dd MMM yyy}", fromDate), new { #class = "form-control", } )</div>
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
</div>
</div>
</div>
/***toDate***/
<div class="container">
<div class="row">
<div class='col-sm-3'>
<div class="form-group">
<div class='input-group date' id='toDate'>
<div>#Html.TextBox("toDate", string.Format("{0:dd MMM yyy}", toDate), new { #class = "form-control", } )</div>
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
</div>
</div>
</div>
/***searchString***/
<div class="container">
<div class="row">
<div class='col-sm-3'>
<div class="form-group">
#Html.Editor("SearchString", ViewBag.CurrentFilter as string, new { htmlAttributes = new { #class = "form-control" } })
</div>
</div>
</div>
</div>
/***Submit***/
<div class="container">
<div class="row">
<div class='col-sm-3'>
<div class="form-group">
<input type="submit" class="btn btn-success" value="Search" />
</div>
</div>
</div>
</div>
<hr />
}
<table class="table-bordered">
<tr style="background-color:black">
<th>
#Html.ActionLink("Job No", "Index", new { style = "color:white" })
</th>
<th>
#Html.ActionLink("Submission Date", "Index", null, new { style = "color:white" })
</th>
<th>
#Html.ActionLink("Job Title", "Index", null, new { style = "color:white" })
</th>
<th>
#Html.ActionLink("Article", "Index", null, new { style = "color:white" })
</th>
<th>
#Html.ActionLink("Status", "Index", null, new { style = "color:white" })
</th>
<th></th>
</tr>
#foreach (var item in Model)
{
//Highlight Rows Green, Yellow or Red Dependant on Status - Yellow means job has not finished processing
string statusCheck = (item.Status);
string style = "";
if (statusCheck.Contains("Status message 0003:Job finished"))
{
style = "background-color:#e6fff2";
}
else if (statusCheck.Equals("0"))
{
style = "background-color:#ffffcc";
}
else
{
style = "background-color:#ff8080";
}
<tr style="#style">
<td>
#Html.DisplayFor(modelItem => item.JobNo)
</td>
<td>
#Html.DisplayFor(modelItem => item.SubmissionDate)
</td>
<td>
#Html.DisplayFor(modelItem => item.JobDesc)
</td>
<td>
#Html.DisplayFor(modelItem => item.Article)
</td>
<td>
#Html.DisplayFor(modelItem => item.Status)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id = item.SubmissionID }) |
#Html.ActionLink("Details", "Details", new { id = item.SubmissionID }) |
#Html.ActionLink("Delete", "Delete", new { id = item.SubmissionID })
</td>
</tr>
}
</table>
<br />
Page #(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) of #Model.PageCount
#Html.PagedListPager(Model, page => Url.Action("Index", new { page, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter, fromDate = ViewBag.fromDate, toDate = toDate }))
#section scripts{
<script type="text/javascript">
$(function () {
$('#fromDate').datetimepicker({
format: 'DD MMMM YYYY',
});
});
</script>
<script type="text/javascript">
$(function () {
$('#toDate').datetimepicker({
format: 'DD MMMM YYYY'
});
});
</script>
}
#Html.TextBox() can pull values out of the ModelState or ViewData.
so you can bind the date values to your text box manually
Kindly refer this link:https://stackoverflow.com/a/29369965/3397630 for an accepted solution which is similar to your problem.
Hope it will be helpful
thanks
Karthik

ViewBag is null on the second page of PagedList in mvc application

I m stuck on this for a while now and will appreciate any help.
The value of ViewBag.SearchTerm is null when I click on the 2 item in the paged list. My List page is present in a partial view (_CentraladdrcdoQuery) as below
#using SFRS.GazMatching.Web.DAL
#model IPagedList<CentraladdrcdoQuery>
#using PagedList;
#using PagedList.Mvc;
<div id="results" class="col-md-10">
<div class="row">
<div class="col-md-4">
<table class="table pull-left table-condensed">
<tr>
<td>
#Html.DisplayNameFor(model => model.First().RecordId)
</td>
</tr>
</table>
</div>
<div class="col-md-4">
<table class="table pull-left table-condensed">
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.RecordId)
</td>
</tr>
}
</table>
</div>
<br />
</div>
<div class="row">
<div class="col-md-4 clearfix">
#Html.PagedListPager(Model, page => Url.Action("Search", new { page, ViewBag.SearchTerm }), new PagedListRenderOptions
{
LinkToFirstPageFormat = "<<",
LinkToPreviousPageFormat = "prev",
LinkToNextPageFormat = "next",
LinkToLastPageFormat = ">>",
})
</div>
</div>
The main search view is
#model IPagedList<CentraladdrcdoQuery>
#{
SearchFormViewModel searchFormViewModel = new SearchFormViewModel();
}
#Html.Partial("_SearchForm",searchFormViewModel)
<h2>Search Results</h2>
#Html.Partial("_CentraladdrcdoQuery", Model)
and the Search Controller action is
public ActionResult Search(string searchTerm, int? page)
{
var centraladdrcdoQuerylst= GetCentraladdrcdoQueryData(searchTerm,page);
ViewBag.SourceList = GetSourceList();
ViewBag.SearhTerm = searchTerm;
return View(centraladdrcdoQuerylst);
}

jquery post to asp.net mvc controller

I have these two controller actions:
public ActionResult Index(string search, int? page)
{
return View(db.powners.Where(x => x.petowner.StartsWith(search) || search == null).OrderBy(x => x.petowner).ToList().ToPagedList(page ?? 1, 5));
}
public ActionResult Ownerfind(string search, int? page)
{
return View(db.powners.Where(x => x.petowner.StartsWith(search) || search == null).OrderBy(x => x.petowner).ToList().ToPagedList(page ?? 1, 5));
}
And this json method also:
public JsonResult Getowner(int nownerid)
{
OwnerEntities owner = new OwnerEntities();
var existingCust = owner.powners.Single(p => p.ownerid == nownerid);
return Json(existingCust);
}
Index view:
#model PagedList.IPagedList<Mvc4test2.Models.powner>
#using PagedList.Mvc;
#using PagedList;
#{
ViewBag.Title = "Index";
}
<link href="../../Content/PagedList.css" rel="stylesheet" type="text/css" />
<div style="font-family:Arial">
<h2>Index</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<p>
#using (#Html.BeginForm("Index", "owner", FormMethod.Get))
{
<b>Search</b>#Html.TextBox("search")<input type="submit" value="search" />
}
</p>
<table id="ownertable">
<tr>
<th>
#Html.DisplayNameFor(model => model.First().petowner)
</th>
<th>
#Html.DisplayNameFor(model => model.First().ostreet)
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.ownerid)
</td>
<td>
#Html.DisplayFor(modelItem => item.petowner)
</td>
<td>
#Html.DisplayFor(modelItem => item.ostreet)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.ownerid }) |
#Html.ActionLink("Details", "Details", new { id=item.ownerid }) |
#Html.ActionLink("Delete", "Delete", new { id=item.ownerid })
</td>
</tr>
}
</table>
#Html.PagedListPager(Model, page=>Url.Action("Index", new{page, search=Request.QueryString["search"]}), new PagedListRenderOptions(){Display=PagedListDisplayMode.IfNeeded, DisplayPageCountAndCurrentLocation=true,MaximumPageNumbersToDisplay=5})
Ownerfind view:
#model PagedList.IPagedList<Mvc4test2.Models.powner>
#using PagedList.Mvc;
#using PagedList;
#{
ViewBag.Title = "Index";
}
<link href="../../Content/PagedList.css" rel="stylesheet" type="text/css" />
<div style="font-family:Arial">
<h2>Index</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<p>
#using (#Html.BeginForm("ownerfind", "owner", FormMethod.Get))
{
<b>Search</b>#Html.TextBox("search")<input type="submit" value="search" />
}
</p>
<p>
hello
</p>
<table id="ownertable">
<tr>
<th>
#Html.DisplayNameFor(model => model.First().petowner)
</th>
<th>
#Html.DisplayNameFor(model => model.First().ostreet)
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.ownerid)
</td>
<td>
#Html.DisplayFor(modelItem => item.petowner)
</td>
<td>
#Html.DisplayFor(modelItem => item.ostreet)
</td>
</tr>
}
</table>
#Html.PagedListPager(Model, page=>Url.Action("ownerfind","owner", new{page, search=Request.QueryString["search"]}), new PagedListRenderOptions(){Display=PagedListDisplayMode.IfNeeded, DisplayPageCountAndCurrentLocation=true,MaximumPageNumbersToDisplay=5})
</div>
Jquery segment:
$("#ownertable td:nth-child(1)").click(function (event) {
event.preventDefault();
var $td = $(this).closest('tr').children('td');
var currentid = $.trim($td.eq(0).text());
alert("hi:" + currentid);
$.ajax({
url: 'owner/Getowner',
type: 'POST',
data: 'nownerid=' + currentid,
dataType: "json",
success: function (result) {
alert("hello");
//alert(result.petowner);
opener.$('input#ownerid').val(result.ownerid);
opener.$('#petowner').val(result.petowner);
opener.$('input#ostreet').val(result.ostreet);
self.close();
}
});
});
Here's the problem:
If I use the first controller action public ActionResult Index(string search, int? page), then I get the json result as expected. However if I use the second controller action
public ActionResult Ownerfind(string search, int? page) then the I donot get a json result back.
Both controller actions work on screen, and I get the alert("hi:" + currentid);
But I only get a json result if I use click on the table used in the Index view.
Why isn't the ownerfind view working with jquery? It displays correctly just no json result.
I want seperate view, because one will be a lookup and another a regular for adding and editing.
Add [HttpPost] attribute to Getowner action from Contoller
And return from get owner something like this:
return Json(new { Data = existingCust });

error when update data to database using checkbox

i try to update my database using checkbox, when i delete data, my code is work. but when i update to add some value to database, i got some error.
**
Cannot insert explicit value for identity column in table 'HotelRoomFacility' when IDENTITY_INSERT is set to OFF.
**
this my code
my service
public void UpdateFacilityInHotel(List<int> FacilityIDs, int RoomTypeID)
{
List<HotelRoomFacility> hotelRoomFacilities = _HotelRoomFacility.AsQueryable().Where(f => f.RoomTypeID == RoomTypeID).ToList();
foreach (int newFacility in FacilityIDs)
{
if (hotelRoomFacilities.Where(h => h.RoomFacilityID == newFacility).Count() == 0)
{
HotelRoomFacility facility = new HotelRoomFacility
{
RoomFacilityID = newFacility,
RoomTypeID = RoomTypeID
};
_HotelRoomFacility.Add(facility);
}
}
foreach (HotelRoomFacility facility in hotelRoomFacilities)
{
if (FacilityIDs.Contains(facility.RoomFacilityID) == false)
_HotelRoomFacility.Delete(facility);
}
_HotelFacilityRepository.CommitChanges();
}
my controller
public ActionResult EditRoom(int RoomTypeID)
{
ViewBag.hotel = _hotelService.GetByID(_HotelID).HotelName;
//var roomType = _hotelService.ShowRoomByID(RoomTypeID);
//return View(roomType);
List<EditRoomTypeViewModel> editRoomTypeViewModel = _showRoomByIDService.ShowRoomByID(RoomTypeID);
return View(editRoomTypeViewModel.FirstOrDefault());
}
[HttpPost]
public ActionResult EditRoom(EditRoomTypeViewModel typeRoom, FormCollection forms)
{
List<string> IDs = forms["FacilityIDs"].Split(',').ToList();
List<int> FacilityIDs = new List<int>();
foreach (string ID in IDs)
{
FacilityIDs.Add(Convert.ToInt32(ID));
}
_showRoomByIDService.UpdateFacilityInHotel(FacilityIDs, _HotelID);
return EditRoom(_HotelID);
var x = _hotelService.UpdateRoom(typeRoom.RoomTypeID, typeRoom.RoomTypeName, typeRoom.RoomTypeDescription);
if (x != null)
{
return RedirectToAction("Room");
}
return View(typeRoom);
}
my view
#model XNet.Repository.Model.EditRoomTypeViewModel
#{
ViewBag.Title = "addRoom";
}
<h2>Edit Room</h2>
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
<fieldset>
<legend>Isikan Data</legend>
<div>
#Html.Label("Hotel Name")
</div>
<div>
#ViewBag.hotel
</div>
<br />
<div>
#Html.HiddenFor(model => model.RoomTypeID)
</div>
<br />
<div>
#Html.Label("Room Type Name")
</div>
<div>
#Html.EditorFor(model => model.RoomTypeName)
#Html.ValidationMessageFor(model => model.RoomTypeName)
</div>
<br />
<div>
#Html.Label("Room Type Description")
</div>
<div>
#Html.TextAreaFor(model => model.RoomTypeDescription)
#Html.ValidationMessageFor(model => model.RoomTypeDescription)
</div>
<br />
<table>
<thead>
<tr>
<th>Facility Name</th>
<th> is available</th>
</tr>
</thead>
<tbody>
#foreach (var facility in Model.facilitiesInRoom)
{
<tr>
<td>
#(facility.RoomFacilityName)
</td>
<td style="text-align:center;">
<input type="checkbox" #(facility.RoomFacilityAvailable ? " checked=checked" : null) name="FacilityIDs" value="#facility.RoomFacilityID" />
</td>
</tr>
}
</tbody>
</table>
<br />
<p>
<input type="submit" value="Save" />
<input style="width:100px;" type="button" title="EditHotelDetail" value="Back to Detail" onclick="location.href='#Url.Action("Index", "Hotel") '" />
</p>
</fieldset>
}
Here is the database diagram

How to pass data from View to Controller in MVC 3

I have created a ViewModel with two things, a Contact and a list of Phones for that Contact.
My goal is to add data for a new Contact, and add a few Phones, and then save by a Controller action.
I've edited the scaffolded Create.cshtml for my Contact, added a grid for the phones. Added a javascript for creating the phones. So far so good.
The problem is when I click the Create button, and I get back to the Controller, I get no Phones. How do I (in the View) add the phone-rows to my IEnumerable?
EDIT:
Took out code in view that was not correct in this context.
My ViewModel:
public class ContactViewModel
{
public Contact Contact {get; set;}
public IEnumerable<Phone> Phones { get; set; }
}
My view:
#model PilotKibsNet.Controllers.ContactViewModel
<script type="text/javascript" src="../../Scripts/jquery-1.5.1.js"></script>
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
<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 type="text/javascript">
function Add() {
$("#tbl > tbody:last").append("<tr><td>" + $("#Number").val() + "</td><td>" + $("#Kind").val() + "</td><td></td></tr>");
$("#Number").val("");
$("#Kind").val("");
}
</script>
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>Contact</legend>
<div class="editor-label">
#Html.LabelFor(model => model.Contact.Name)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Contact.Name)
#Html.ValidationMessageFor(model => model.Contact.Name)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Contact.Address)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Contact.Address)
#Html.ValidationMessageFor(model => model.Contact.Address)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Contact.City)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Contact.City)
#Html.ValidationMessageFor(model => model.Contact.City)
</div>
<legend>Phone numbers</legend>
<label>Number :</label>
#Html.TextBox("Number")
<label>Kind :</label>
#Html.TextBox("Kind")
<input type="button" value="Add" onclick="Add()" />
<table id="tbl">
<tr>
<th>
Phone
</th>
<th>
Kind
</th>
<th></th>
</tr>
<tbody>
</tbody>
</table>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
And then, in by Controller action, the Contact has the data, but the Phone is an empty list.
[HttpPost]
public ActionResult Create(ContactViewModel contactViewModel)
{
if (ModelState.IsValid)
{
contactViewModel.Contact.id = Guid.NewGuid();
db.Contacts.AddObject(contactViewModel.Contact);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(contactViewModel.Contact);
}
How do I get the Phones back to the server?!?
You have only display templates for those Phones collection. No value at all will be sent to the server. You could use hidden fields if the user is not supposed to edit the values or textboxes if he is.
Also I would replace this foreach loop in your view by an editor template:
if (Model != null)
{
#Html.EditorFor(x => x.Phones)
}
and then I will define an editor template which would be rendered for each element of the Phones collection (~/Views/Shared/EditorTemplates/Phone.cshtml):
#model Phone
<tr>
<td>
#Html.DisplayFor(x => x.Number)
#Html.HiddenFor(x => x.Number)
</td>
<td>
#Html.DisplayFor(x => x.Type)
#Html.HiddenFor(x => x.Type)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id = Model.id }) |
#Html.ActionLink("Details", "Details", new { id = Model.id }) |
#Html.ActionLink("Delete", "Delete", new { id = Model.id })
</td>
</tr>
I have used hidden fields here to persist the values of the model so that when you post the form to the server they would be sent.
Another and IMHO better approach if the user is not supposed to edit those values in the table is to simply refetch them in your POST action from your database.

Resources