I've created an MVC website using VS2013. My view contains a a dropdownlist for "Import Status" and a paging control as shown below:
My view is as follows:
#model PagedList.IPagedList<ESBAMPortal.Models.SupplierStockUpdateViewModel>
#using PagedList.Mvc;
<link href="~/Content/PagedList.css" rel="stylesheet"
type="text/css" />
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
SelectList itemsPerPageList = ESBAMPortal.Helpers.DefaultValues.ItemsPerPageList;
}
<h2>Stock Updates</h2>
<div class="container-fluid">
<div class="row">
<div id="instruction" class="col-md-6 pull-left">
<h5>Click the 'Process Start' datetime to see a copy of the file received</h5>
</div>
</div>
<div class="row" id="filters">
<div id="filtersDropdown" class="col-md-6 pull-right">
#using (Html.BeginForm("Index", "SupplierStockUpdate", FormMethod.Get, new { #class = "pull-right" }))
{
{
<span>
#Html.Label("Import Status:")
#Html.DropDownListFor(m => m.FirstOrDefault().SelectedStatusId, Model.FirstOrDefault().StatusItems)
</span>
<span>
#Html.Label("Items per page:")
#Html.DropDownList("ItemsPerPage", itemsPerPageList,
new { #id = "ItemsPerPageList" })
</span>
}
<input type="submit" value="Refresh" />
}
</div>
</div>
</div>
<table class="table table-striped">
<thead>
<tr>
<th>#Html.DisplayNameFor(model => model.FirstOrDefault().ReceivedFilename)</th>
<th>#Html.ActionLink("Proces Start", "Index", new { sortOrder = ViewBag.TimeReceivedSort, itemsPerPage = itemsPerPageList.SelectedValue })</th>
<th>#Html.DisplayNameFor(model => model.FirstOrDefault().TimeProductLookupResponse)</th>
<th>#Html.DisplayNameFor(model => model.FirstOrDefault().TimeInsertResponse)</th>
<th>#Html.DisplayNameFor(model => model.FirstOrDefault().ImportStatus)</th>
<th>#Html.DisplayNameFor(model => model.FirstOrDefault().ImportErrors)</th>
<th>#Html.ActionLink("Supplier", "Index", new { sortOrder = ViewBag.SupplierSort })</th>
<th>#Html.DisplayNameFor(model => model.FirstOrDefault().RowsInserted)</th>
<th>#Html.DisplayNameFor(model => model.FirstOrDefault().TimeOfExceptionString)</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>#Html.DisplayFor(model => item.ReceivedFilename)</td>
<td>
#Html.ActionLink(item.TimeReceived.ToString(), "Index", "ArchivedMsg",
new { interchangeId = item.InterchangeId }, null)
</td>
<td>#Html.DisplayFor(model => item.TimeProductLookupResponse)</td>
<td>#Html.DisplayFor(model => item.TimeInsertResponse)</td>
<td>#Html.DisplayFor(model => item.ImportStatus)</td>
<td>#Html.DisplayFor(model => item.ImportErrors)</td>
<td>#Html.DisplayFor(model => item.SupplierCode)</td>
<td>#Html.DisplayFor(model => item.RowsInserted)</td>
#{
if (item.TimeOfExceptionString.IsDateTime())
{
<td>#Html.ActionLink(item.TimeOfExceptionString, "IndexForInterchangeId", "Fault", new { interchangeId = item.InterchangeId }, null) </td>
}
else
{
<td>NA</td>
}
}
</tr>
}
</tbody>
</table>
<div id="pageControllFooter" class="container-fluid">
<div class="row">
<div id="pageButtons" class="col-md-2">
#Html.PagedListPager(Model, page => Url.Action("Index", new { page, itemsPerPage = ViewBag.CurrentItemsPerPage }))
</div>
</div>
<div class="row">
<div id="pageDesc" class="col-md-2">
#if (Model != null
&& Model.PageCount > 0)
{
<div>
Page #(Model.PageCount < Model.PageNumber
? 0 : Model.PageNumber)
of #Model.PageCount
</div>
}
</div>
</div>
</div>
Model:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace ESBAMPortal.Models
{
public class SupplierStockUpdateViewModel
{
public string ActivityID { get; set; }
public string InterchangeId { get; set; }
[DisplayName("Received")]
public DateTime? TimeReceived { get; set; }
[DisplayName("DW Product Requested")]
public DateTime? TimeProductLookupRequested { get; set; }
[DisplayName("DW Product Response")]
public DateTime? TimeProductLookupResponse { get; set; }
[DisplayName("CIMS Insert Requested")]
public DateTime? TimeInsertRequested { get; set; }
[DisplayName("CIMS Insert Response")]
public DateTime? TimeInsertResponse { get; set; }
[DisplayName("Supplier Code")]
public string SupplierCode { get; set; }
[DisplayName("CIMS Records Updated")]
public int? RowsInserted { get; set; }
public string ReceivedFilename { get; set; }
public DateTime? TimeOfException { get; set; }
public string TimeOfExceptionString { get; set; }
public double TotalDuration { get; set; }
public string ImportStatus { get; set; }
public int? ImportErrors { get; set; }
public DateTime LastModified { get; set; }
//constructor
public SupplierStockUpdateViewModel()
{
_statuses = new List<Status>();
_statuses.Add(new Status()
{
Id = 1,
Name = "All"
});
_statuses.Add(new Status()
{
Id = 2,
Name = "Pending"
});
_statuses.Add(new Status()
{
Id = 3,
Name = "Complete"
});
}
private readonly List<Status> _statuses;
public class Status
{
public int Id { get; set; }
public string Name { get; set; }
}
[Display(Name = "Status")]
public int SelectedStatusId { get; set; }
//our VM has a select list
public IEnumerable<SelectListItem> StatusItems
{
get { return new SelectList(_statuses, "Id", "Name"); }
}
}
}
Controller:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using ESBAMPortal.DataLayer;
using ESBAMPortal.Models;
using PagedList;
using ESBAMPortal.DomainClasses.BAM;
using System.IO;
namespace ESBAMPortal.Controllers
{
public class SupplierStockUpdateController : Controller
{
private IRepository<SupplierStockUpdate> SupplierStockUpdateRepository;
public SupplierStockUpdateController(BAMContext context)
{
this.SupplierStockUpdateRepository = new EFRepository<SupplierStockUpdate>(context);
}
private string TranslateStatusFilter(int status)
{
string ret = "";
switch (status)
{
case 2:
ret = "Pending";
break;
case 3:
ret = "Complete";
break;
}
return ret;
}
// GET: /SupplierStock/
public ActionResult Index(string sortOrder, int? page, int? itemsPerPage, SupplierStockUpdateViewModel vm)
{
string statusFilter = TranslateStatusFilter(vm.SelectedStatusId);
ViewBag.CurrentItemsPerPage = itemsPerPage;
ViewBag.TimeReceivedSort = String.IsNullOrEmpty(sortOrder) ? "timeReceived" : "";
ViewBag.SupplierSort = sortOrder == "supplier" ? "supplier_desc" : "supplier";
var query = this.SupplierStockUpdateRepository.GetAll();
switch (sortOrder)
{
case "timeReceived":
query = query.OrderBy(f => f.TimeReceived);
break;
case "supplier":
query = query.OrderBy(f => f.SupplierCode);
break;
case "supplier_desc":
query = query.OrderByDescending(f => f.SupplierCode);
break;
default:
query = query.OrderByDescending(f => f.TimeReceived);
break;
}
if (statusFilter == "Pending" || statusFilter == "Complete")
{
query = query.Where(x => x.ImportStatus == statusFilter);
}
//shove results into view model
List<SupplierStockUpdateViewModel> SupplierStockUpdatesVM = new List<SupplierStockUpdateViewModel>();
DateTime start = new DateTime();
DateTime end = new DateTime();
foreach (var item in query.ToList())
{
SupplierStockUpdateViewModel SupplierStockUpdateVM = new SupplierStockUpdateViewModel();
SupplierStockUpdateVM.ActivityID = item.ActivityID;
SupplierStockUpdateVM.InterchangeId = item.InterchangeId;
SupplierStockUpdateVM.TimeReceived = item.TimeReceived;
SupplierStockUpdateVM.TimeProductLookupRequested = item.TimeProductLookupRequested;
SupplierStockUpdateVM.TimeProductLookupResponse = item.TimeProductLookupResponse;
SupplierStockUpdateVM.TimeInsertRequested = item.TimeInsertRequested;
SupplierStockUpdateVM.TimeInsertResponse = item.TimeInsertResponse;
SupplierStockUpdateVM.SupplierCode = item.SupplierCode;
SupplierStockUpdateVM.RowsInserted = item.RowsInserted;
SupplierStockUpdateVM.TimeOfException = item.TimeOfException;
SupplierStockUpdateVM.ReceivedFilename = item.ReceivedFilename;
SupplierStockUpdateVM.ImportStatus = item.ImportStatus;
SupplierStockUpdateVM.ImportErrors = item.ImportErrors;
start = (item.TimeReceived == null) ? DateTime.MinValue : (System.DateTime)item.TimeReceived;
if (item.TimeOfException == null)
{
SupplierStockUpdateVM.TimeOfExceptionString = "NA";
if (item.TimeInsertResponse != null)
{
end = (System.DateTime)item.TimeInsertResponse;
}
else
{
//no exception but process still running so give a duration of 0
end = start;
}
}
else
{
SupplierStockUpdateVM.TimeOfExceptionString = item.TimeOfException.ToString();
end = (System.DateTime)item.TimeOfException;
}
if (start == DateTime.MinValue)
{
SupplierStockUpdateVM.TotalDuration = 0;
}
else
{
SupplierStockUpdateVM.TotalDuration = (end - start).TotalSeconds;
}
SupplierStockUpdatesVM.Add(SupplierStockUpdateVM);
}
int pageSize = (itemsPerPage ?? 10);
int pageNumber = (page ?? 1);
return View(SupplierStockUpdatesVM.ToPagedList(pageNumber, pageSize));
}
}
}
On clicking the "Refesh" button all works ok, the filtered Import Status is passed to the controller. My problem is, when paging by clicking the boxes of the page controls, the value 0 is always passed in the VM.SelectedStatusId field.
I've tried changing the view's call to explicitly pass the SelectedStatusId as follows:
#Html.PagedListPager(Model, page => Url.Action("Index", new { page, itemsPerPage = ViewBag.CurrentItemsPerPage, Model.FirstOrDefault().SelectedStatusId }))
...and adding a corrsponding int param on the controller action but still this was coming through as 0.
Could anyone let me know where I'm going wrong? Thanks.
Upon first look, it seems you have coded the following line wrong.
#Html.PagedListPager(Model, page => Url.Action("Index", new { page, itemsPerPage = ViewBag.CurrentItemsPerPage, Model.FirstOrDefault().SelectedStatusId }))
You have forgotten the return parameter for the last parameter in you expression. Try the following
#Html.PagedListPager(Model, page => Url.Action("Index", new { page, itemsPerPage = ViewBag.CurrentItemsPerPage, vm = Model.FirstOrDefault().SelectedStatusId }))
note the "vm = "
Let me know if that works!
The vm.SelectedStatusId is passed into the action when the user clicks the "Refresh" button on the view.
I assign the selected status to a viewbag property in the Index action of the controller:
ViewBag.StatusId = vm.SelectedStatusId;
When the user later pages through the results, I pass in the previously selected status filter, from the viewbag:
#Html.PagedListPager(Model, page => Url.Action("Index", new { page, itemsPerPage = ViewBag.CurrentItemsPerPage, selectedStatusId = ViewBag.StatusId }))
Related
I am trying to do the following: I have two models, header and List(details), sent to a view by a view model. When loading the main view, a dropdown is displayed from a list in the ViewModel.header model previously loaded. When you click on that dropdown, a partial view is loaded with some values, filtered by the value of the ddl, of the ViewModel.List(details) for the user to complete the information. So far everything works fine, but when doing the Post, controller it receives the ViewModel.List(details) in null.
what am I doing wrong?
Header
public class StockTransactionsHeader
{
[Key]
public int TransactionHeaderID { get; set; }
public DateTime TransactionDate { get; set; }
public string TransactionDocument { get; set; }
public int CategoryID { get; set; }
[NotMapped]
public List<SelectList> CategoryCollection { get; set; }
public virtual List<StockTransactionsDetails> StockTransactionsDetails { get; set; }
}
Details
public class StockTransactionsDetails
{
[Key]
public int TransactionDetailID { get; set; }
public int TransactionHeaderID { get; set; }
public int ProductID { get; set; }
public decimal Qty { get; set; }
public decimal Amount { get; set; }
public decimal TransactionAmount { get; set; }
[NotMapped]
public string ProductDescription { get; set; }
public virtual StockTransactionsHeader StockTransactionsHeader { get; set; }
}
ViewModel
public class StockTransactionsViewModel
{
public StockTransactionsHeader StockTransactionsHeader { get; set; }
public List<StockTransactionsDetails> StockTransactionsDetails { get; set; }
}
Controller Create
public ActionResult Create()
{
var stockTransactions = new StockTransactionsViewModel();
stockTransactions.StockTransactionsHeader = GetHeaderCategories();
return View(stockTransactions);
}
GetHeaderCategories()
private StockTransactionsHeader GetHeaderCategories()
{
var header = new StockTransactionsHeader();
header.CategoryCollection = CommonServices.GetSelecList((int)DeliveryCommonHelper.ConfigurationType.Categoria);
return header;
}
MainView
#model DeliverySolutionCommon.ViewModels.StockTransactionsViewModel
#using (Html.BeginForm())
{
<div class="form-row">
<div id="partialView" class="table-responsive">
</div>
</div>
<div class="form-group">
<div class="col-md-2">
<input type="submit" value=" Procesar " class="btn btn-warning" />
</div>
</div>
}
Script to load partial view
<script>
$(document).ready(function () {
$("#Category").on("change", function () {
autoFiltro();
})
})
function autoFiltro() {
var url = "#Url.Action("GetProductsListByCategory", "StockTransactions")";
var id = $("#Category").val();
var data = { idCategory: id };
$.post(url, data).done(function (data) {
$("#partialView").html(data);
})
}
</script>
GetProductsListByCategory
[HttpPost]
public PartialViewResult GetProductsListByCategory(int idCategory)
{
var products = ProductsServices.GetProductsListByCategory(idCategory);
var stockTransactions = new StockTransactionsViewModel();
stockTransactions.StockTransactionsDetails = GetTransactionsDetails(products);
return PartialView("_createStockTransactions", stockTransactions);
}
GetTransactionsDetails
private List<StockTransactionsDetails> GetTransactionsDetails (List<Products> products)
{
var details = new List<StockTransactionsDetails>();
foreach (var item in products)
{
StockTransactionsDetails detail = new StockTransactionsDetails();
detail.ProductID = item.ProductID;
detail.ProductDescription = item.Description;
details.Add(detail);
}
return details;
}
PartialView
#model DeliverySolutionCommon.ViewModels.StockTransactionsViewModel
<table class="table table-sm table-bordered table-striped">
#foreach (var item in Model.StockTransactionsDetails)
{
<tr class="d-flex">
<td class="col-7">
#Html.DisplayFor(modelItem => item.ProductDescription)
</td>
<td class="col-1">
#Html.EditorFor(modelItem => item.Qty, new { htmlAttributes
= new { #class = "form-control" } })
</td>
<td class="col-2">
#Html.EditorFor(modelItem => item.Amount, new {
htmlAttributes = new { #class = "form-control" } })
</td>
<td class="col-2">
#Html.EditorFor(modelItem => item.TransactionAmount, new {
htmlAttributes = new { #class = "form-control" } })
</td>
</tr>
}
</table>
Aaaaand finally Create Post
[HttpPost]
public ActionResult Create(StockTransactionsViewModel stockTransactionsView)
{
// StockStransactionsView.StockTransactionsDetails = null
}
The problem is you are posting back a list and there is no indexing information in your HTML... MVC model binder does not know how to put the items in a list without the index info...
you can try something like this:
#for (int i = 0; i < Model.StockTransactionsDetails.Count, i++)
{
<tr class="d-flex">
<td class="col-7">
#Html.EditorFor(modelItem => Model[i].Amount, new {
htmlAttributes = new { #class = "form-control" } })
</td>
// more code...
This would add the indexing information to your HTML...
Alternatively you can use EditorTemplate... something like this:
// Note that EditorFor template would iterate the list item for you
#Html.EditorFor(m => m.Model.StockTransactionsDetails)
This tutorial might help
I have a situation where I would like administrators to re-order questions to however they like, however, I have an issue on retrieving the value selected from the "DropDownListFor" from my form to my controller.
Placing the breakpoint at "Debug.WriteLine(MV.Count), the variable "SetNewValue" returns null in my controller
So what is the proper way to retrieve the new value that is selected and my default selected value from my DropDownListFor, as well as the current question number to my controller upon "onchange = this.form.submit()"?
I know the [HttpPost] Controller part is not a proper method to swap the questions, it is there for me to see whether the variables I have set do return the values that are sent from the DropDownListFor upon "onchange" form submit.
Any form of help is appreciated, as I am a beginner in MVC.
My View
#model IList<AppXamApplication.Models.EditQuestionsAndAnswersViewModel>
#{
ViewBag.Title = "EditQuestionsPage2";
}
<h4>Edit Your Questions Here</h4>
#using (Html.BeginForm("EditQuestionsPage2", "ExamAdmin", FormMethod.Post, new { #class = "form-horizontal", role = "form" }))
{
<table id="tblQuestions" border="0" style="border:none">
#for (int i = 0; i < Model.Count; i++)
{
if (Model[i].TypeOfQuestion == "Open Ended")
{
<tr>
<td>
#Html.DropDownListFor(m => m[i].SetNewValue, new SelectList(Model[i].TotalNoQuestions, "Value", "Text", Model[i].ToSetPreSelectValue), new { #Name = "CurrentQnAction", onchange = "this.form.submit();" })
#Html.HiddenFor(m => m[i].CurrentQuestionNumber, new { CurrentQnNoID = Model[i].CurrentQuestionNumber })
</td>
<td> </td>
<td> </td>
<td>
#Html.ActionLink("Delete Question", "EditQuestionsPage2", new { Question_ID = Model[i].QuestionID, #class = "form-control" })
</td>
</tr>
<tr>
<td>
<b>Question Type: #Html.DisplayFor(m => m[i].TypeOfQuestion, new { #class = "form-control" }) </b>
</td>
</tr>
<tr>
<td>
#Html.EditorFor(m => m[i].QuestionsAsked, new { #class = "form-control" })
</td>
</tr>
<tr>
<td>
<br />
<br />
</td>
</tr>
}
}
</table>
}
Edited: My Model
public class EditQuestionsAndAnswersViewModel
{
//Questions
public string QuestionID { get; set; }
public string TypeOfQuestion { get; set; }
public string ExamID { get; set; }
public string QuestionsAsked { get; set; }
public string UserID { get; set; }
public int? OrderingQuestions { get; set; }
public int? CurrentQuestionNumber { get; set; }
public string SetNewValue { get; set; }
public int? ToSetPreSelectValue{ get; set; }
public IList<SelectListItem> TotalNoQuestions { get; set; }
public IList<EditAnswers> PossibleAnswers { get; set; }
public string AnswerID { get; set; }
public string AnswerText { get; set; }
}
Edited: My Controllers
[HttpGet]
public ActionResult EditQuestionsPage2()
{
if (ModelState.IsValid)
{
using (var ctx = new AppXamApplicationEntities())
{
var CurrentExamID2 = (string)Session["CurrentExamID2"];
string CurrentExamID2_string = Convert.ToString(CurrentExamID2);
var query = ctx.Questions.Where(x => x.ExamID.Equals(CurrentExamID2_string))
.Select(x => new EditQuestionsAndAnswersViewModel()
{
QuestionID = x.QuestionID,
TypeOfQuestion = x.TypeOfQuestion,
ExamID = x.ExamID,
QuestionsAsked = x.QuestionsAsked,
UserID = x.UserID,
ToSetPreSelectValue= x.QuestionOrder,
// To Order the questions in ascending order
OrderingQuestions = x.QuestionOrder,
// To Display Current Question Number
CurrentQuestionNumber = x.QuestionOrder,
// To Display the dropdownlist as well as set the default selected value to be displayed for each question in the dropdownlist
TotalNoQuestions = ctx.Questions.Where (v=> v.ExamID.Equals(x.ExamID)).Select(v => new SelectListItem
{
Value = v.QuestionOrder.ToString(),
Text = v.QuestionOrder.ToString(),
}).ToList(),
PossibleAnswers = x.Answers.Where(y => y.QuestionID.Equals(x.QuestionID)).Select(y => new EditAnswers()
{
AnswerID = y.AnswerID,
AnswerText = y.AnswerText
}).ToList()
}).ToList().AsQueryable();
var queryOrdered = query.OrderBy(x=> x.CurrentQuestionNumber).ToList();
return View(queryOrdered);
}
}
return View();
}
[HttpPost]
public ActionResult EditQuestionsPage2(string action, string CurrentQnAction, int? CurrentQnNoID, IList<EditQuestionsAndAnswersCollectionModel> MV, string ToRetrieveSelectedValue, AddQuestions _model)
{
if (ModelState.IsValid)
{
if (CurrentQnNo!= null)
{
//Breakpoint placed over here
Debug.WriteLine(MV.Count);
}
}
return View();
}
I'm using PagedList to paginate but it need to has all records in a list and then make the pagination and it will waste a long time to render the page, so, I want to use LIMIT and OFFSET with PagedLit to make a real pagination and waste a short time.
How could I use PagedList with LIMIT and OFFSET to create a real pagination ?
trying
Model
public class SearchUsuarioModel{
public IPagedList<UpUsuarioAdminModel> listaModel { get; set; } //list model
public IPagedList<Usuario> listaObject { get; set; } //list all objects
//Status
public IEnumerable<SelectListItem> status { get; set; }
public int statusSelected { get; set; }
public String nome { get; set; }
public String role { get; set; }
public int limit { get; set; }
public int offset { get; set; }
public int pageSize { get; set; }
public int pageNumber { get; set; }
public SearchUsuarioModel(){
listaModel = new List<UpUsuarioAdminModel>().ToPagedList(1, 50);
}
}
Controller
public ActionResult viewAllAdmin(int? page, String nome, String role, int? offSet){
//model
SearchUsuarioModel model = new SearchUsuarioModel();
model.nome = nome;
model.role = role;
model.limit = 3;
model.offset = offSet ?? 0;
model.pageNumber = page ?? 1;
model.pageSize = model.limit;
//listas
IList<Usuario> _listaObject = new List<Usuario>();
IList<UpUsuarioAdminModel> _listaModel = new List<UpUsuarioAdminModel>();
UsuarioDAO dao = new UsuarioDAO();
try{
_listaObject = dao.findAllOffset(model.limit, model.offset);
} catch (Exception e){
Debug.WriteLine("viewAllAdmin UsuarioController: " + e.Message);
}
if (_listaObject.Count > 0){
foreach (Usuario u in _listaObject){
UpUsuarioAdminModel m = new UpUsuarioAdminModel();
m.id = u.id;
m.nome = u.nome;
m.email = u.email;
m.roleSelected = u.role.ToString();
m.statusDesc = u.status == 1 ? "Ativo" : "Inativo";
m.contrato = u.imgContrato;
if (u.contato != null){
//Debug.WriteLine("Telefone: " + string.IsNullOrEmpty(u.contato.telefone1));
m.telefone1 = string.IsNullOrEmpty(u.contato.telefone1) ? "" : u.contato.telefone1;
}
_listaModel.Add(m);
}
}
model.listaModel = _listaModel.ToPagedList(model.pageNumber, model.limit);
model.listaObject = dao.findAll().ToPagedList(model.pageNumber, model.limit);
return View(model);
}
HTML
<div class="panel panel-red center-block">
<div class="panel-heading bg-red clearfix">
<strong>Usuários do sistema</strong>
<div class="pull-right">
#Html.ActionLink("Novo", "addUsuarioAdmin", "Usuario", new { Class = "text-white glyphicon glyphicon-plus" })
</div>
</div>
<div class="panel-body">
<table class="table table-bordered table-responsive table-striped table-hover" id="tableView">
<thead class="CabecalhoTabela">
<tr>
<th>#ID</th>
<th>Nome</th>
<th>Email</th>
<th>Telefone</th>
<th>Perfil</th>
<th>Status</th>
<th>Controles</th>
</tr>
</thead>
<tbody class="conteudoTabela">
#foreach (UpUsuarioAdminModel m in Model.listaModel){
<tr>
<td class="text-right">#Html.DisplayFor(i => m.id)</td>
<td>#Html.DisplayFor(i => m.nome)</td>
<td class="text-lowercase">#Html.DisplayFor(i => m.email)</td>
<td class="text-center">#Html.DisplayFor(i => m.telefone1)</td>
<td class="text-center">#Html.DisplayFor(i => m.roleSelected)</td>
<td class="text-center">#Html.DisplayFor(i => m.statusDesc)</td>
<td>
#Html.ActionLink(" ", "editUsuarioAdmin", "Usuario", new { id = EncodingParams.encode(Convert.ToString(#m.id)) }, new { Class = "glyphicon glyphicon-pencil", title = "editar" })
#if (!string.IsNullOrEmpty(m.contrato))
{
#Html.ActionLink(" ", "Download", "Usuario", new { id = EncodingParams.encode(Convert.ToString(#m.id)) }, new { Class = "glyphicon glyphicon-file", title = "Contrato" })
}
</td>
</tr>
}
</tbody>
</table>
</div>
<div class="panel-footer">
Pagina #Model.listaObject.PageNumber de #Model.listaObject.PageCount
#Html.PagedListPager(Model.listaObject, page => Url.Action("viewAllAdmin", new { page = Model.pageNumber, offSet = Model.offset }))
</div>
</div>
DAO
public IList<Usuario> findAll(){
ISession _session = getSession();
IList<Usuario> list = _session.CreateQuery("FROM Usuario u ORDER BY u.id")
.List<Usuario>();
return list;
}
public IList<Usuario> findAllOffset(int limit, int offset){
ISession _session = getSession();
IList<Usuario> list = _session.CreateQuery("FROM Usuario u ORDER BY u.id")
.SetFirstResult(offset)
.SetMaxResults(limit)
.List<Usuario>();
return list;
}
I'm trying to display a partial view in a div block named 'productButtonForm' based on a radio button click. The partial view appears to be called, but the passed model has null member variables. Can someone help me figure out where I've gone wrong? Below is what I've got:
Model
public class RetrieveAllModel
{
public Guid ConversationId { get; set; }
public List<RetrieveProductsModel> Products { get; set; }
public RetrieveOffersModel Offers { get; set; }
public int ProductType { get; set; }
}
View
#{
ViewBag.Title = "Easy Order";
int productCount = 0;
}
<legend>Offers/Products</legend>
#using (Html.BeginForm("ShowProductItems", "BrowseShopping"))
{
foreach (var type in Model.Products)
{
if (productCount > 0 && productCount % 5 == 0)
{
<br/>//break after every 5 products
}
#type.Name
#Html.RadioButtonFor(model => model.ProductType, type.ID, Model);
<label> </label>
productCount = productCount + 1;
}
<div class="col-lg-5 col-md-6 col-sm-12" id="productButtonForm">
</div>
}
Controller
public PartialViewResult ShowProductItems()
{
return PartialView("RetrieveProducts", new RetrieveAllModel() {Products = new List<RetrieveProductsModel>()});
}
[HttpPost]
public PartialViewResult ShowProductItems(RetrieveAllModel model)
{
//The passed model only has the ProductType set, every other
//member variable is null
return PartialView("RetrieveProducts", model);
}
Script file
$(function() {
$("[name=ProductType]").on('change',
function() {
var $radio = $(this);
var myurl = "ShowProductItems?ProductType=" + $radio.val();
console.log("We hit the script");
$.ajax({
url: myurl,
type: 'POST',
success: function(data) {
$("#productButtonForm").append(data);
}
});
});
});
I had a few issues going. Aside from what Stephen mentioned above, I had two data models that needed to be represented in the same button group. To address that, I had to use Html.RadioButton instead of RadionButtonFor. Also, I needed to access the controller's established conversation with the client to access the model state of the current view. Once I got those in place, the partial view changes as desired. Below are the changes I made to fix my triggering problem.
Model
public class RetrieveAllModel
{
public Guid ConversationId { get; set; }
public List<RetrieveProductsModel> Products { get; set; }
public RetrieveOffersModel Offers { get; set; }
public string ProductType { get; set; }
}
public class RetrieveCatalogModel
{
public List<BrowseDataItemModel> AvailableBrowseItems { get; set; }
}
public class RetrieveOffersModel : RetrieveCatalogModel
{
public List<int> SelectedServiceIds { get; set; }
}
public class RetrieveProductsModel : RetrieveCatalogModel
{
public int ID { get; set; }
public string Name { get; set; }
public int Count { get; set; }
}
View
#model OrderServiceClient.Models.RetrieveAllModel
#{
ViewBag.Title = "Easy Order";
int productCount = 1;
string offers = "Offers";
}
#using (Html.BeginForm("ShowCatalog", "BrowseShopping"))
{
//since offers are not part of the dynamic product list, they need to be specifically identified
#offers<label> </label>
#Html.RadioButton("catalogName", "Offers", true, new { catalogName = "Offers", conversationid = Model.ConversationId })
<label> </label>
foreach (var type in Model.Products)
{
if (productCount > 0 && productCount % 5 == 0)
{
<br/>//break after every 5 products
}
#type.Name<label> </label>
#Html.RadioButton("catalogName", type.Name, new { catalogName = type.Name, conversationid = Model.ConversationId })
<label> </label>
productCount = productCount + 1;
}
}
...
<div class="row">
#{Html.RenderPartial("RetrieveCatalogs", Model.Offers.AvailableBrowseItems);}
</div>
Partial View
#model List<OrderServiceClient.Models.BrowseDataItemModel>
#if (Model != null)
{
<div class="col-lg-7 col-md-6 col-sm-12 offers-container" id="shoppingcatalog">
<table class="table table-striped">
<tr>
<th>Data Type</th>
<th>Name</th>
<th>Price</th>
<th></th>
</tr>
#foreach (var item in Model)
{
<tr class="offerList">
<td>#item.DataType</td>
<td>#item.Name</td>
<td>#string.Format($"{item.Amount,0:C2}")</td>
<td><a class="addService" dataType="#item.DataType" serviceId="#item.ServiceId" serviceName="#item.Name" amount="#item.Amount">Add</a></td>
</tr>
}
</table>
</div>
}
Controller
public PartialViewResult ShowCatalog()
{
RetrieveCatalogModel rcm = new RetrieveCatalogModel();
rcm.AvailableBrowseItems = new List<BrowseDataItemModel>();
return PartialView("RetrieveCatalogs", rcm.AvailableBrowseItems);
}
[HttpPost]
public PartialViewResult ShowCatalog(string catalogName, Guid conversationid)
{
if (catalogName.Equals("Offers"))
{
RetrieveOffersModel offers = new RetrieveOffersModel();
var response = BrowseShoppingHelper.RetrieveOffers(conversationid, _client);
offers.AvailableBrowseItems = BuildOffersBrowseDataItemsModel(response).ToList();
return PartialView("RetrieveCatalogs", offers.AvailableBrowseItems);
}
else
{
var prodctFolderResponse = BrowseShoppingHelper.RetrieveProductFolders(conversationid, _client);
var output = (RetrieveProductFoldersCommandOutput) prodctFolderResponse.Body.Output;
RetrieveProductsModel rpm = new RetrieveProductsModel{Name = catalogName, AvailableBrowseItems = new List<BrowseDataItemModel>()};
foreach (var folder in output.Folders)
{
if (!catalogName.Equals(folder.Name)) continue;
var items = BuildProductBrowseItemsModel(
(RetrieveProductsInGroupCommandOutput) BrowseShoppingHelper
.RetrieveProductItems(conversationid, _client, folder).Body.Output);
rpm.AvailableBrowseItems.AddRange(items);
break;
}
return PartialView("RetrieveCatalogs", rpm.AvailableBrowseItems);
}
}
Script file
$(function() {
$("[name=catalogName]").on('change',
function () {
var $radio = $(this);
var myurl = "ShowCatalog?catalogName=" + $radio.val() + "&conversationid=" + $(this).attr('conversationid');
console.log("Catalog item is: " + $radio.val() + " and id is: " + $(this).attr('conversationid'));
$.ajax({
url: myurl,
type: 'POST',
success: function (data) {
$("#shoppingcatalog").html(data);
}
});
});
});
I have a view that takes uses a model called newsModels, this uses the IpagedList, however in the same view I have added a partial view that I want to list the 10 most recent news items added to the site, I want this partial view to be included in the newsitems view as well as on other views throughout the site.
What is the best way to do this. I have only succeeded in listing the titles of the newsitems that the IpagedList is showing so not quite right still.
I assume I will need to create a separate controller for the partial view but I just cant find any guidance on how to do this.
can any one offer any advice / guidance
//Models
public class partialNewsMenu
{
public IEnumerable<NewsModels> newsTitle { get; set; }
}
public class NewsModels
{
public int id { get; set; }
public string newsTitle { get; set; }
[AllowHtml]
public string newsDesc { get; set; }
public string imagePath { get; set; }
public string addedBy { get; set; }
public DateTime dateAdded { get; set; }
public bool publishNewsItem { get; set; }
}
//Controller
public ActionResult OpsiumNews(string sortby, int? page)
{
ViewBag.ImageName = "MSLOffice.jpg";
ViewBag.ImageDesc = "Opsium News";
ViewBag.OverlayText = "N/A";
ViewBag.pageTitle = "Opsium News";
ViewBag.Title = "Opsium | News";
if (sortby == null)
{
ViewBag.MostRecent = "Selected";
}
else
{
ViewBag.MostRecent = "";
}
ViewBag.Oldest = "";
ViewBag.PostedBy = "";
ViewBag.ListNewsModels = new SelectList(db.NewsModels, "Id", "newsTitle");
var NewsModelsList = db.NewsModels.Select(s => s.newsTitle);//.Where(s => s.publishNewsItem);
var NewsModels = db.NewsModels.Where(c => c.publishNewsItem);
switch (sortby)
{
case "1":
NewsModels = NewsModels.OrderBy(s => s.dateAdded);
ViewBag.MostRecent = "Selected";
break;
case "2":
NewsModels = NewsModels.OrderByDescending(s => s.dateAdded);
ViewBag.Oldest = "Selected";
break;
case "3":
NewsModels = NewsModels.OrderBy(s => s.addedBy);
ViewBag.PostedBy = "Selected";
break;
default: // Name ascending
NewsModels = NewsModels.OrderBy(s => s.dateAdded);
ViewBag.MostRecent = "Selected";
break;
}
ViewBag.currentsort = sortby;
int pageSize = 1;
int pageNumber = (page ?? 1);
return View("OpsiumNews", NewsModels.ToPagedList(pageNumber, pageSize));
}
//View
#model PagedList.IPagedList<Opsium_website.Models.NewsModels>
#using PagedList.Mvc;
<link href="~/Content/PagedList.css" rel="stylesheet" type="text/css" />
<div class="Sub-content" id="containcontent">
<div class="rightSideHeader">
<div class="container">
<div class="row">
<div class="col-md-15 addBottomMargin">
#using (Html.BeginForm("OpsiumNews", "UsefulInformation", FormMethod.Get))
{
foreach (var item in Model)
{
<p>
Order by
<select name="sortby" id="sortby" onchange="submit();">
<option value="1" #ViewBag.MostRecent>Most Recent</option>
<option value="2" #ViewBag.Oldest>Oldest</option>
<option value="3" #ViewBag.PostedBy>Posted by</option>
</select>
</p>
<div class="col-md-9 addBottomMargin" id="contentText">
<h3>#Html.DisplayFor(model => item.newsTitle)</h3>
<img src="~/Images/NewsImages/#Html.DisplayFor(model => item.imagePath)" alt="#Html.DisplayFor(model => item.newsTitle)" id="newsImage"/>
#MvcHtmlString.Create(item.newsDesc)
<p><b>Date Added:</b>#String.Format("{0:F}", item.dateAdded) - <b>Added By:</b> #Html.DisplayFor(model => item.addedBy)</p>
</div>
}
}
<div class="col-md-2 addBottomMargin" id="contentText">
#{Html.RenderPartial("_NewsTitlesList");}
</div>
<div class="col-md-9 addBottomMargin">
Page #(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) of #Model.PageCount
#Html.PagedListPager(Model, page => Url.Action("OpsiumNews",
new { page, sortby = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter }))
</div>
</div>
</div>
</div>
</div>
</div>
//Partial View
#model IEnumerable<Opsium_website.Models.partialNewsMenu>
#using PagedList.Mvc;
#foreach(var items in Model){
#Html.DisplayFor(model=>items.newsTitle)
}
//error
The model item passed into the dictionary is of type 'PagedList.PagedList1[Opsium_website.Models.NewsModels]', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable1[Opsium_website.Models.partialNewsMenu]'.