JQuery dialogs don't work after ajax partial view reload - jquery-ui

I am manipulating a table of data in a View. When the user clicks on the data name, a dialog pops up to allow him to edit the data. When he clicks, delete, a dialog prompts him to make sure, then deletes the row. When he chooses to create new row, a dialog pops up to allow him to enter the new information. In all 3 cases, after the action is complete, the PartialView "_Content" reloads the content <div />.
This all works fine the first time, after the entire page loads. But after the PartialView reloads (after one of the actions), the "Edit" dialog no longer works, though the other 2 do. I can rig the page to reload everything after each action, of course, but that's slower and doesn't make sense in an Ajax world. If I put the JQueryUIHelper for the edit dialog in the partial view, again, it works the first time, but the second time, the form opens up inline on the page rather than in a dialog. I also tried this using JQuery and JQueryUI directly and got the same error. I have been researching this and experimenting for days.
UPDATED 4/1/13:* I added some $.click() callbacks to the link classes. They don't work after the page does the partial refresh. I guess what's happening is that the scripts lose their "connection" to the objects in the content <div> when the content reloads.
I am using MVC4, Razor, and JQueryUI via the JQueryUIHelper extension. The code for the View and PartialView is below.
Are there any ideas??
Here's my View
#model IEnumerable<AttributeLookup>
#{
ViewBag.Title = "Attributes";
}
<h2>
Attributes</h2>
#if (ViewBag.Error != null)
{
<div class="message-error">#ViewBag.Error</div>
}
<div id="content">
#Html.Partial("_Content", Model)
</div>
<div style="padding-top: 12px;">
#Ajax.ActionLink("New", "Create", new { }, new AjaxOptions {
HttpMethod = "Get",
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "createContent"
}, new { id = "createLink" })
</div>
#using (Html.JQueryUI().Begin(new Dialog()
.Title("Confirm Delete")
.AutoOpen(false)
.Modal(true)
.CloseOnEscape(true)
.ConfirmAjax(".deleteLink", "Yes", "No",
new AjaxSettings { Method = HttpVerbs.Post, Success = "content" })))
{
<div>
Are you sure you want to delete this attribute?
</div>
}
#using (Html.JQueryUI().Begin(new Dialog()
.Title("Create Attribute")
.AutoOpen(false)
.Width(500)
.TriggerClick("#createLink")
.Modal(true)
.CloseOnEscape(true)
.Button("OK", "save")
.Button("Cancel", "closeDialog")))
{
<div id="createContent" />
}
#using (Html.JQueryUI().Begin(new Dialog(new {id = "editDialog"})
.Title("Edit Attribute")
.AutoOpen(false)
.Width(500)
.TriggerClick(".editLink")
.Modal(true)
.CloseOnEscape(true)
.Button("OK", "save")
.Button("Cancel", "closeDialog")))
{
<div id="editContent" />
}
#section Scripts {
<script type="text/javascript">
var success = function(data) {
$(window.document.body).html(data);
};
var content = function(data) {
$("#content").html(data);
};
var closeDialog = function() {
$(this).dialog('close');
};
var saveCreate = function() {
$("#createForm").submit();
$(this).dialog('close');
};
var saveEdit = function() {
$("#editForm").submit();
$(this).dialog('close');
};
$(".editLink").click(function () { alert("edit clicked"); });
$(".deleteLink").click(function () { alert("delete clicked"); });
</script>
}
Here's the PartialView
#model IEnumerable<AttributeLookup>
#if (ViewBag.Error != null)
{
<div class="message-error">#ViewBag.Error</div>
}
<table id="attribute">
<tbody>
<tr>
<th style="width: 250px;">
#Html.DisplayNameFor(model => model.Name)
</th>
<th style="width: 50px;">
#Html.DisplayNameFor(model => model.Units)
</th>
<th style="width: 30px;">
Contrained
</th>
<th style="width: 400px;">
#Html.DisplayNameFor(model => model.Description)
</th>
<th>
 
</th>
</tr>
#{ int count = 0; }
#foreach (var item in Model)
{
string type = count % 2 == 0 ? "normal" : "alt";
<tr class="#type">
<td>
#Ajax.ActionLink(#Html.DisplayFor(modelItem => item.Name).ToHtmlString(), "Edit",
new { id = item.AttributeLookupID }, new AjaxOptions
{
HttpMethod = "Get",
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "editContent"
}, new { #class = "editLink", title = "Edit attribute" })
</td>
<td>
#Html.DisplayFor(modelItem => item.Units)
</td>
<td>
#if (item.AttributeConstraints != null && item.AttributeConstraints.Any())
{
#Html.Raw("X")
}
</td>
<td>
#Html.DisplayFor(modelItem => item.Description)
</td>
<td>
#Html.ActionLink("Delete", "Delete", new { id = item.AttributeLookupID }, new { #class = "deleteLink" })
</td>
</tr>
count++;
}
</tbody>
</table>
Here's the Partial for the Edit form. The Create form is similar:
#model AttributeLookup
#using (Ajax.BeginForm("Edit", "AttributeLookup", new AjaxOptions {
HttpMethod = "Post",
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "content"
}, new {id = "editForm"}))
{
#Html.ValidationSummary(true)
<fieldset>
<legend>AttributeLookup</legend>
#Html.HiddenFor(model => model.AttributeLookupID)
<div class="editor-label">
#Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Name)
#Html.ValidationMessageFor(model => model.Name)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Units)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Units)
#Html.ValidationMessageFor(model => model.Units)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Description)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Description)
#Html.ValidationMessageFor(model => model.Description)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.AttributeConstraints, "Constraint")
</div>
<div class="editor-field">
#Html.DropDownList("ConstraintTypeID")
#Html.DropDownList("SecondaryID")
</div>
</fieldset>
}

I found a solution. First, I removed the TriggerClick from the Helper:
#using (Html.JQueryUI().Begin(new Dialog(new {#id = "editDialog"})
.Title("Edit Attribute")
.AutoOpen(false)
.Width(500)
// deleted --> .TriggerClick(".editLink")
.Modal(true)
.CloseOnEscape(true)
.Button("OK", "saveEdit")
.Button("Cancel", "closeDialog")))
{
<div id="editContent" />
}
And then I explicitly added it to my <scripts>:
$("body").on('click', ".editLink", function () { $("#editDialog").dialog("open"); });
Now it works fine.

I wonder why it works for the other two, but not the edit one? I suspect it has to to with mistakes startingfrom the id. Try taking away id=editdialog. This might be a quickfix. If this doesnt work, keep reading.
The #dialog usually hides due to jqueryUi things that go on at document.ready or page load in the background.
I'm not sure exaclty when it happens, but you'd want to repeat those steps after the reload happens.
At the end of the document in a part thats not reloaded do something like...
<script>
$("body").ajaxComplete( reHideDialog())
function reHideDialog(){
$("#dialog").css('display','none');
}
</script>
when they click the edit link, jqueryui should automatically set the #dialog css display to display:absolute as it renders it in a popup.

Related

MVC IPageList Paging showing two pager control

I am new to MVC. I am trying to create a Grid structure based on some filters on page and then apply paging. Everything works fine except that when I click on second page, another pager control is added to page resulting in total two pager control on page. Any help would be highly appreciated. Below is my code:
Model:
public class UnMatched
{
public List<string> List_BUnit { get; set; }
public PagedList<UnMatched> List_Grid { get; set; }
}
Controller:
public ActionResult Index(int? page)
{
return Request.IsAjaxRequest()
? (ActionResult)PartialView("AjaxMethod")
: View(PopulateBUnit());
}
public ActionResult AjaxMethod(string bunit, int? Page)
{
//Get lst_UnMatch here
return PartialView(List_Grid.ToPagedList(pageIndex, pageSize));
}
Main View:
#model MVC_Sample.Models.UnMatched
#using PagedList;
#using PagedList.Mvc;
#{
ViewBag.Title = "Home Page";
}
<head>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
</head>
<div id="GridContainer" style="display:none;">
#Html.Partial("AjaxMethod", Model.List_Grid)
</div>
PartialView:
#model IPagedList<MVC_Sample.Models.UnMatched>
#using PagedList;
#using PagedList.Mvc;
<div id="GridDiv">
<table class="Grid">
<tr>
<th>
#Html.DisplayName("rec_FSRPT_ID")
</th>
<th>
#Html.DisplayName("BUNit")
</th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.rec_FSRPT_ID)
</td>
<td>
#Html.DisplayFor(modelItem => item.BUNit)
</td>
</tr>
}
</table>
</div>
</div>
<div id="myPager">
#Html.PagedListPager(
Model,
page => Url.Action("AjaxMethod", new { page = page}),
PagedListRenderOptions.EnableUnobtrusiveAjaxReplacing(new AjaxOptions(){
HttpMethod = "GET", UpdateTargetId = "GridDiv" }))
</div>
<script>
$(function () {
$('#myPager').on('click', 'a', function () {
$.ajax({
url: this.href,
type: 'GET',
cache: false,
success: function (result) {
$('#myPager').html(result);
}
});
return false;
});
});
</script>
Pager Control screenshot:
Instead of #myPager link click use the following code.
<div class="row">
<div class="col col-xs-12 col-sm-6">
<div class="dataTables_info" id="dt_basic_info" role="status" aria-live="polite">Showing <span class="txt-color-darken">#Model.FirstItemOnPage</span> to <span class="txt-color-darken">#Model.LastItemOnPage</span> of <span class="text-primary">#Model.TotalItemCount</span> entries</div>
</div>
<div class="col col-xs-12 col-sm-6">
<a id="pagingFormAction" href="#Url.Action("AjaxMethod", new { Pageindex = 1 bunit = ViewBag.bunit })" style="display:none"></a>
#Html.PagedListPager(Model, page => Url.Action("AjaxMethod", new { Pageindex = page, bunit = ViewBag.bunit }), PagedListRenderOptions.EnableUnobtrusiveAjaxReplacing(new PagedListRenderOptions() { ContainerDivClasses = new[] { "dataTables_paginate paging_simple_numbers" } }, new AjaxOptions() { HttpMethod = "replace", UpdateTargetId = "GridDiv", OnBegin = "beginPaging", OnSuccess = "successPaging", OnFailure = "failurePaging" }))
</div>
</div>
you can remove OnBegin = "beginPaging", OnSuccess = "successPaging", OnFailure = "failurePaging" if not required.
Thanks all for your help.
I put mypager div inside div Griddiv and it worked. On pager click, i was getting whole grid data again and then binding it to div #GridDiv.
<div id="GridDiv">
// grid.GetHTML code here
<div id="myPager">
#Html.PagedListPager(
Model,
page => Url.Action("AjaxMethod", new { page = page}),
PagedListRenderOptions.EnableUnobtrusiveAjaxReplacing(new AjaxOptions(){
HttpMethod = "GET", UpdateTargetId = "GridDiv" }))
</div>
</div>

ASP MVC 5 Post a form from a link

I need to make a custom data grid view with multi column filtering and pagination. so i made a view model winch will encapsulate three class
IEnumerable from the data.
Filter class with some properties
Pager to holder page size, current page, total pages etc ..
Filtering working fine but pagination not :(. as i loose the view model when pressing pagination link "It seems that i need to also submit the search form"
Any one can show how i can submit the form when pressing a link.
here is my view
#model TestFilteringAndPagination.ViewModels.CarViewModel
#{
ViewBag.Title = "Home Page";
}
#*Search form*#
#using (Html.BeginForm("Index", "Home", FormMethod.Post, new { id = "frm" }))
{
#Html.HiddenFor(m => Model.Pager.CurrentPage)
#Html.HiddenFor(m => Model.Pager.PageSize)
#Html.HiddenFor(m => Model.Pager.EndPage)
#Html.HiddenFor(m => m.Pager.StartPage)
<div class="form-inline">
<div class="form-group">
<label>Car No</label>
#Html.EditorFor(x => x.Filter.CarNumber, new { #class = "form-control" })
</div>
<div class="form-group">
<label>Line name</label>
#Html.EditorFor(x => x.Filter.LineName, new { #class = "form-control" })
</div>
<button type="submit" class="btn btn-default">Search</button>
</div>
<ul class="pagination">
#for (var page = Model.Pager.StartPage; page <= Model.Pager.EndPage; page++)
{
<li class="#(page == Model.Pager.CurrentPage ? "active" : "")">
#page
</li>
}
</ul>
}
#*Data grid*#
<table class="table">
<thead>
<tr>
<th>
Car number
</th>
<th>
Car Line
</th>
</tr>
</thead>
<tbody>
#foreach (var car in Model.Cars)
{
<tr>
<td>
#Html.DisplayFor(x => car.CarNumber)
</td>
<td>
#Html.DisplayFor(x => car.LineName)
</td>
</tr>
}
</tbody>
</table>
You can install the PagedList.MVC NuGet Package, see this post for more info about how to create exactly what you want.
Sorting, Filtering, and Paging with the Entity Framework in an ASP.NET MVC Application

MVC4 Filtering with checkboxes

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?

Disable unobtrusive validation on an ASP.NET MVC form

I have two forms on a page. I want the first form to use unobtrusive validation, as it's since automatically generated by ASP.NET MVC Framework. There is a second form, however, which I wrote manually, that should not use unobtrusive validation.
Here's some code:
#using (Html.BeginForm("Add", "Contacts", FormMethod.Post, new { id = "AddForm" }))
{
#Html.ValidationSummary(true)
<fieldset>
<legend>Datos Contacto</legend>
<div class="editor-label">
#Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Name)
#Html.ValidationMessageFor(model => model.Name)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.ContactDepartmentID)
</div>
<div class="editor-field">
#Html.DropDownListFor(model => model.ContactDepartmentID, (List<SelectListItem>)ViewBag.ContactDepartments)
#Html.ValidationMessageFor(model => model.ContactDepartmentID)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Sex)
</div>
<div class="editor-field">
#Html.DropDownListFor(model => model.Sex, (List<SelectListItem>)ViewBag.Sexs)
#Html.ValidationMessageFor(model => model.Sex)
</div>
</fieldset>
<br />
#Html.HiddenFor(model => model.SerializedEmails, new { data_bind = "value: ko.toJSON($root.emails())" })
#Html.HiddenFor(model => model.SerializedPhones, new { data_bind = "value: ko.toJSON($root.phones())" })
}
<form id="phoneForm" >
<fieldset>
<legend>Teléfonos</legend>
<table class="table">
<tbody data-bind="foreach: phones">
<tr>
<th>
Celular?
</th>
<th>
Phone
</th>
<th>
Extension
</th>
<th>
</th>
</tr>
<tr>
<td>
<input type="checkbox" data-bind="checked: isMobile" />
</td>
<td>
<input class="phone" data-bind='value: phone'/>
</td>
<td>
<input type="text" class="extension" data-bind='value: phoneExtension, enable: !isMobile() ' />
</td>
<td>
<a href='#' data-bind='click: $root.removePhone'>Delete</a>
</td>
</tr>
</tbody>
</table>
<a href='#' data-bind='click: $root.addPhone'>Agregar teléfono</a>
</fieldset>
</form>
<p>
<button onclick="Submit();" type="button" class="btn btn-primary" data-bind='enable: phones().length > 0 || emails().length > 0'>
Create</button>
</p>
JS:
function Submit()
{
var valid = $('#AddForm').valid();
var valid2 = $('#phoneForm').valid();
}
jQuery.validator.addClassRules("phone", {
required: true
});
As a side note: When I remove the unobtrusive validation from the page, the second form validates, but the first does not. If I use unobtrusive validation the first form validates, but the second form does not.
I know I can do the whole validation on the client side—and, if that's the only way, I will do it. I was thinking about a way to continue using unobtrusive validation, but allowing it to be conditionally disabled using e.g. custom attributes.
You can disable the unobtrusive validation from within the razor code via this Html Helper property:
HtmlHelper.ClientValidationEnabled = false;
That way you can have unobtrusive validation on and off for different forms according to this setting in their particular view/partial view.
You can mark the elements or find it all the input of the second form and remove the rules, this sample is for remove all rules of some controls in the form, this cause according with the user selected some options, the values required will be others. for this reason i store the rules to restore it later.
///Remove rules
$("input.rO,textarea.rO").each(function () {
try
{
var rule = $(this).rules();
if (rule) {
$(this).data("rule", rule);
$(this).rules("remove");
}
}
catch(err){}
});
///Restore rules
$("input.rO.om" + v + ",textarea.rO.om"+v).each(function () {
try
{
var rule = $(this).data("rule");
if (rule)
$(this).rules("add", rule);
}
catch(err){}
});

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