MVC Partial View not rendering - c#

Partial view is not rendering while passing ViewModel.. Its rendering without ViewModel.
I mean if I keep #Html.Partial("PartialClientIndex") then its rendering and when I pass ViewModel it directly going to Dispose without rendering partial view.
I'm missing something here.. could you please help in this.
Main View:
<div id="PartialClient">
#Html.Partial("PartialClientIndex", viewModelList)
</div>
Action:
[HttpPost]
public ActionResult PartialClientIndex(int? SelectedGroupId)
{
int SkipRec = 0;
int NextRec = 25;
VMClient vmclient = new VMClient();
vmclient.IEClients = db.client.Where(cl => cl.Groups.id == SelectedGroupId).OrderBy(c => c.id).Skip(SkipRec).Take(NextRec).ToList();
return PartialView("PartialClientIndex", vmclient);
}
Partial View:
#model IEnumerable<HostingManager.Models.VMClient>
<table>
<thead>
<tr>
<th style="width:25px; padding:10px;">
Group
</th>
<th class="tbContent-Name">
Client Name
</th>
<th class="tbContent-Name">
Contact Person
</th>
<th class="tbContent-Name">
Contact Email
</th >
<th></th>
</tr>
</thead>
<tbody>
#if(Model != null)
{
var x = Model.Select(c=>c.IEClients).ToList();
var y = x[0].ToList();
// var y = x[0]["item1"];
foreach (var item in y) {
<tr>
<td class="tbContent-Name">
#Html.DisplayFor(modelItem => item.Groups.name)
</td>
<td class="tbContent-Name">
#Html.DisplayFor(modelItem => item.contactPerson)
</td>
<td class="tbContent-Name">
#Html.DisplayFor(modelItem => item.contactPerson)
</td>
<td class="tbContent-Name">
#Html.DisplayFor(modelItem => item.contactEmail)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.id }) |
#Html.ActionLink("Delete", "Delete", new { id = item.id }, new { onclick = "return confirm('Are you sure you wish to delete this ?');" })
</td>
</tr>
}
}
</tbody>

It seems that the variable vmclient that you are passing as model into your partial view is of type VMClient. Though your partial view is expecting the IEnumerable<VMClient> type.
You basically have to change the model type in your partial view to the following
#model HostingManager.Models.VMClient
and adjust the way you are assigning the y variable
var y = Model.IEClients;

Related

Whats the best way of using ajax jquery to load partial views onto a specific page?

I have a index page the code looks like this
#model PagedList.IPagedList<PartialViews.Models.Customer>
#using PagedList.Mvc
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<div class="container">
<table class="table">
<tr>
<th>
Title
</th>
<th>
First Name
</th>
<th>
Last Name
</th>
<th>
Email Address
</th>
<th>
Phone Number
</th>
<th>
Modified Date
</th>
<th></th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Title)
</td>
<td>
#Html.DisplayFor(modelItem => item.FirstName)
</td>
<td>
#Html.DisplayFor(modelItem => item.LastName)
</td>
<td>
#Html.DisplayFor(modelItem => item.EmailAddress)
</td>
<td>
#Html.DisplayFor(modelItem => item.Phone)
</td>
<td>
#Html.DisplayFor(modelItem => item.ModifiedDate)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id = item.CustomerID }) |
#Html.ActionLink("Details", "Details", new { id = item.CustomerID }) |
#Html.ActionLink("Delete", "Delete", new { id = item.CustomerID })
</td>
</tr>
}
</table>
#Html.PagedListPager(Model,page=>Url.Action("Index",new{page,pageSize=Model.PageSize}))
</div>
My CustomersController has this code
private AdventureWorksLT2012Entities db = new AdventureWorksLT2012Entities();
// GET: Customers
public ActionResult Index(int page=1, int pageSize=10)
{
List<Customer> customers = db.Customers.ToList();
PagedList<Customer> cust = new PagedList<Customer>(customers,page,pageSize);
return View(cust);
//return View(db.Customers.ToList());
}
Heres the Main page where i want the Customers List from the Index action to be shown
#model PartialViews.Models.Customer
#{
ViewBag.Title = "Main";
}
<body>
<div class="container">
<h2>Customer's List</h2>
<div id="dvCustomerDetails" style="width: 50%; height: 130px;display: none"></div>
</div>
</body>
<script type="text/javascript">
$.ajax({
url: 'Customers/Index',
contentType: 'application/html;',
type: 'GET',
dataType:'html'
})
.success(function(result) {
$('#dvCustomerDetails').html(result);
})
</script>
I want to display this table onto a new page as a partial view using ajax jquery but I am having trouble implementing it.
I was able to use RenderPartial method to display it as a partial view but i am having trouble doing it with ajax. Any help or suggestion will be appreciated.

Asp.Net - EF - MVC - Indexing Rows

I am using Asp.Net , EF6 ( MVC ) and have some data stored in my view. What I need is some indexing for each row. Here is the view.
For every row I have 0 Index. I wanna know, if there is some Built in feature in EF, that will help to add indexes for each row, (1,2,3....) and which will be automatically be updated, when new rows are created or deleted.
This is the Code for creating the table and doing Paging in my View.
<div class="bs-example">
<div class="table-responsive">
<div class="panel panel-default">
<table class="table table-striped table-hover table-bordered" cellspacing="0" data-toggle="table" data-click-to-select="true">
<tr>
<th style="vertical-align:middle;" class="text-center">
Index
</th>
<th style="vertical-align:middle;" class="text-center">
#Html.ActionLink("English", "Index", new { sortOrder = ViewBag.EnglishSortParm, currentFilter = ViewBag.CurrentFilter })
</th>
<th style="vertical-align:middle;" class="text-center">
#Html.ActionLink("Russian", "Index", new { sortOrder = ViewBag.RussianSortParm, currentFilter = ViewBag.CurrentFilter })
</th>
<th style="vertical-align:middle;" class="text-center">
#Html.ActionLink("Armenian", "Index", new { sortOrder = ViewBag.ArmenianSortParm, currentFilter = ViewBag.CurrentFilter })
</th>
<th style="vertical-align:middle;" class="text-center">
#Html.ActionLink("French", "Index", new { sortOrder = ViewBag.FrenchSortParm, currentFilter = ViewBag.CurrentFilter })
</th>
<th style="vertical-align:middle;" class="text-center">
#Html.ActionLink("Spanish", "Index", new { sortOrder = ViewBag.SpanishSortParm, currentFilter = ViewBag.CurrentFilter })
</th>
<th style="vertical-align:middle;" class="text-center">
#Html.ActionLink("Arabic", "Index", new { sortOrder = ViewBag.ArabicSortParm, currentFilter = ViewBag.CurrentFilter })
</th>
<th></th>
</tr>
#{
foreach (var item in Model.Item1)
{
<tr class="clickableRow">
<td style="vertical-align:middle; font-size:medium;font-style:italic;" class="text-center">
#ViewBag.IndexOfRow.ToInt32
</td>
<td style="vertical-align:middle;" class="text-center">
#Html.DisplayFor(modelItem => item.English)
</td>
<td style="vertical-align:middle;" class="text-center">
#Html.DisplayFor(modelItem => item.Russian)
</td>
<td style="vertical-align:middle;" class="text-center">
#Html.DisplayFor(modelItem => item.Armenian)
</td>
<td style="vertical-align:middle;" class="text-center">
#Html.DisplayFor(modelItem => item.French)
</td>
<td style="vertical-align:middle;" class="text-center">
#Html.DisplayFor(modelItem => item.Spanish)
</td>
<td style="vertical-align:middle;" class="text-center">
#Html.DisplayFor(modelItem => item.Arabic)
</td>
<td style="vertical-align:middle;" class="text-center">
<span style="color:white;">
#Html.ActionLink("Edit", "Edit", new { id = item.Text, #style = "color:red;" })
#*#Html.ActionLink("Details", "Details", new { id = item.Text })*#
#Html.ActionLink("Delete", "Delete", new { id = item.Text })
</span>
</td>
</tr>
}
}
</table>
</div>
<br />
Page #(Model.Item1.PageCount < Model.Item1.PageNumber ? 0 : Model.Item1.PageNumber) of #Model.Item1.PageCount
#Html.PagedListPager(Model.Item1, page => Url.Action("Index",
new { page, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter }))
</div>
</div>
And this is the code from my Controller
public ViewResult Index(int? page)
{
int pageSize = 15;
int pageNumber = (page ?? 1);
var allModels = new Tuple<IPagedList<Translation>, List<Translation>>
(translations.ToPagedList(pageNumber, pageSize), translations.ToList()) { };
return View(allModels);
}
I have removed the unnecessary code, only is left the code for paging.
I have not done anything so far, because I have not find any indexing question or article in Google or SO so far.
Thanks for help.
And if you want to put Index while creating table, you can loop like this in your table body:
<tbody>
#{
int counter = 1;// Index start value
foreach (var Item in Model.SomeList)
{
<tr>
<td> #counter </td>
</tr>
counter++;
}
}
</tbody>
Just set the start row index in the action method to ViewBag.
int pageSize = 15;
int pageNumber = (page ?? 1);
ViewBag.StartRowIndex = ((pageNumber - 1) * pageSize) + 1;
Then use it in the view.
#{
var rowIndex = (int)ViewBag.StartRowIndex;
}
foreach (var item in Model.Item1)
{
<tr class="clickableRow">
<td style="vertical-align:middle; font-size:medium;font-style:italic;" class="text-center">
#(rowIndex++) //#ViewBag.IndexOfRow.ToInt32
</td>
When you dont know what to do, create a new class :))
Im kidding, but the idea remains valid.
Why dont you craete a new class that will represent your "ViewModel" that will have the exact EF model inside and an extra Index property that you will use to bind to an index in the view?
What you will pass from your controller to the view will be the new ViewModel class.
Note:
If you want to go fancy, you could go somewhere on the line of : ObservableCollection http://msdn.microsoft.com/en-us/library/ms668604(v=vs.110).aspx which derrives from INotifyPropertyChanged
Basically it means that you have an event at your disposal that you can fire when the list has changed (add, delete) that will be used to update the index.

Use checkboxes in MVC view and pass checked state back to controller for processing

I have an IList of objects that I pass using a ViewModel to my view.
[HttpGet]
public ActionResult Reminder()
{
using(var db = new SalonContext())
{
var tomorrow = DateTime.Today.AddDays(1);
var homeSalon = GetHomeSalonId();
var myAppointments = db.Appointments.Include(c => c.Customer).Include(c => c.Treatment).Include(c => c.Stylist).Include(c => c.Salon).Where(c => c.SalonId == homeSalon).ToList();
var tomorrowsAppointments = myAppointments.Where(a => a.Start.Date == tomorrow).Select(rem => new FutureAppointment
{
AppointmentId = rem.AppointmentId,
Name = rem.Customer.Title + " " +rem.Customer.FirstName + " " + rem.Customer.Surname,
AppointmentTime = rem.Start,
Salon = rem.Salon.Name,
Stylist = rem.Stylist.FirstName,
Treatment = rem.Treatment.Name,
Email = rem.Customer.EMail,
SendReminder = true
}).ToList();
return View(tomorrowsAppointments);
}
}
The view renders the list with the check boxes using this code:
#model IList<MySalonOrganiser.Models.FutureAppointment>
#{
ViewBag.Title = "Email Reminders";
}
<h2>#ViewBag.Title</h2>
#using(Html.BeginForm("Reminder", "Appointment", FormMethod.Post))
{
#Html.AntiForgeryToken()
<table class="table">
<tr>
<th>
Send Reminder
</th>
<th>
Name
</th>
<th>
Appointment Time
</th>
<th>
Salon
</th>
<th>
Treatment
</th>
<th>
Stylist
</th>
<th>
EMail
</th>
<th></th>
</tr>
#for (var i =0; i < Model.Count; i++)
{
<tr>
<td>
#Html.CheckBoxFor(x => x[i].SendReminder)
</td>
<td>
#Html.DisplayFor(x => x[i].Name)
</td>
<td>
#Html.DisplayFor(x => x[i].AppointmentTime)
</td>
<td>
#Html.DisplayFor(x => x[i].Salon)
</td>
<td>
#Html.DisplayFor(x => x[i].Treatment)
</td>
<td>
#Html.DisplayFor(x => x[i].Stylist)
</td>
<td>
#Html.DisplayFor(x => x[i].Email)
</td>
</tr>
}
</table>
<div>
<input type="Submit" value="Send Reminders" />
</div>
}
When I post the view back to the controller, I see the list's items of type FutureAppointment in the returned model, but everything except the checkbox state is null.
Can anyone help me with why and how to fix this so I see all the model data?
Jason.
It's because your form only contains input fields for the checkboxes. The DisplayFor helper will only create a text or label or whatever displaying the value of the other fields. You can fix this by adding hidden inputs for them:
#for (var i =0; i < Model.Count; i++)
{
<tr>
<td>
#Html.CheckBoxFor(x => x[i].SendReminder)
</td>
<td>
#Html.DisplayFor(x => x[i].Name)
#Html.HiddenFor(x => x[i].Name)
</td>
<td>
#Html.DisplayFor(x => x[i].AppointmentTime)
#Html.HiddenFor(x => x[i].AppointmentTime)
</td>
<td>
#Html.DisplayFor(x => x[i].Salon)
#Html.HiddenFor(x => x[i].Salon)
</td>
<td>
#Html.DisplayFor(x => x[i].Treatment)
#Html.HiddenFor(x => x[i].Treatment)
</td>
<td>
#Html.DisplayFor(x => x[i].Stylist)
#Html.HiddenFor(x => x[i].Stylist)
</td>
<td>
#Html.DisplayFor(x => x[i].Email)
#Html.HiddenFor(x => x[i].Email)
</td>
</tr>
}
You are not posting back the values. Html.DisplayFor does not generate input tags, and only inputs inside a form are posted back to server. You will have to use Html.TexBoxFor or Html.HiddenFor methods for those properties.
Under each of the DisplayFor calls, add a #Html.HiddenFor(x=>x[i].Property) call to add a hidden field containing the same value.
The hidden field values will then get posted by the form and bound to your model when the data hits your controller.
The DisplayFor will only add a label to the output (unless overridden for the model with a display template), label values do not get posted by a form.

Change the string from database column while I displays over html

This is how i am set my page according my database column:
This is the code (only for the first column)
<table class="table">
<tr>
<th style="font-size: 20px">
#Html.DisplayNameFor(model => model.fileName)
</th>
<th></th>
</tr>
#foreach (var item in Model)
{
<tr>
<td style="font-size: 15px">
#Html.DisplayFor(modelItem => item.fileName)
</td>
<td>
#Html.ActionLink("File Details", "Details", new { id = item.id })
</td>
</tr>
}
</table>
How can i change fileName to another string when over my html page ?
I don't know if this will work(I am unable to test it at the moment, not on windows),
[Display(Name = "File Name")] //this is the line you must add.
public string fileName{get;set;} //this is your model property name.
This should change it to File Name

MVC3 Display the edit view on the same page as the list of items

I have a list of transactions. When I click one of them, I'd like to be able to display the edit form (populated with the selected item's data) to the right of the list. Any ideas?
Below is the partial view that displays the list of transactions.
#model IEnumerable<BudgetPlus.Models.Transaction>
#{
ViewBag.Title = "Index";
}
<p>
#Html.ActionLink("Create New", "Create", null, new { #class = "button-link" })
</p>
<table>
<thead>
<tr>
<th class="column-Date">Date</th>
<th class="column-Description">Description</th>
<th class="column-Category">Category</th>
<th class="column-Amount">Amount</th>
<th class="action-button"></th>
<th class="action-button"></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Date)
</td>
<td>
#Html.DisplayFor(modelItem => item.Description)
</td>
<td>
#Html.DisplayFor(modelItem => item.Category.DisplayName)
</td>
<td>
#Html.DisplayFor(modelItem => item.Amount)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id = item.Id })
</td>
<td>
#Html.ActionLink("Delete", "Delete", new { id = item.Id })
</td>
</tr>
}
</tbody>
</table>
<div>
#Html.EditorForModel("Edit")
</div>
And this is what the edit method in my TransactionController looks like.
public ActionResult Edit(int id)
{
Transaction transaction = db.Transactions.Find(id);
ViewBag.CategoryId = new SelectList(db.Categories, "Id", "DisplayName", transaction.CategoryId);
return View(transaction);
}
Probably the easiest way to achieve this is to use Ajax.Actionlink helper.
In your for loop have this instead of Html.Actionlink:
#Ajax.ActionLink("Edit", "Edit", new { id=item.Id }, new AjaxOptions { UpdateTargetId = "editor", HttpMethod = "Get", InsertionMode = InsertionMode.Replace });
And on the right side of your table:
<div id="editor"></div>
Then have a partial view for editing the Transaction, which will be rendered into the div with id "editor". You are using EditorForModel helper so I assume you have a partial view for editing already.
In your actionmethod return the partial view instead:
return PartialView("YourPartialView", transaction);

Categories

Resources