I have an SuperVisor Form and I need to show a list of Employees with checkboxes for selection.
Once I click Save , supervisor information and the selected employees id should be saved to DB.
Which is best option to achieve this ?
Model
public class SelectEmployee
{
public int _EmployeeID;
public string _EmployeeName;
public bool _check;
public int EmployeeID { get { return _EmployeeID; } set { _EmployeeID = value; } }
public string EmployeeName { get { return _EmployeeName; } set { _EmployeeName = value; } }
public bool check { get { return _check; } set { _check = value; } }
}
public class DemoManager
{
public static List<SelectEmployee> GetSelectedEmployee()
{
DemoEntities db = new DemoEntities();
var query = (from i in db.EmployeeMasters
select new SelectEmployee { EmployeeID = i.EmployeeID, EmployeeName = i.EmployeeName, check = false }).ToList();
return query;
}
}
View
#using(Html.BeginForm())
{
<table class="table">
#for (var i = 0; i < Model.Count; i++) {
<tr>
<td>
#Html.DisplayFor(modelEmployee => modelEmployee[i].EmployeeID)
</td>
<td>
#Html.CheckBoxFor(modelEmployee => modelEmployee[i].check)
</td>
<td>
#Html.DisplayFor(modelEmployee => modelEmployee[i].EmployeeName)
</td>
</tr>
}
</table>
<input type="submit" value="click" />
}
Controller
public ActionResult Index()
{
return View(DemoManager.GetSelectedEmployee());
}
[HttpPost]
public ActionResult Index(List<SelectEmployee> emp)
{
var query = (from i in emp
where i.check == true
select i);
// Here you can set the insert statements the query will contain only selected items
return View(model);
}
Related
I am stuck in this problem and i cannot solve it.
This is my ViewModel
public class AddOrderReceive
{
public string item_name { get; set; }
public DateTime? date_received { get; set; }
public decimal? quantity_received { get; set; }
public bool IsSelected { get; set; }
public decimal? item_rate { get; set; }
}
This is my View
#model List<newtest.Models.AddOrderReceive>
#if(Model != null && Model.Count > 0)
{
for(var i = 0; i < Model.Count; i++)
{
<tr>
#if(Model[i].quantity_remaining == 0)
{
<td colspan="6" class="text-center">Already Sent</td>
}
else
{
#Html.HiddenFor(r => Model[i].item_id)
<td>#Html.CheckBoxFor(r => Model[i].IsSelected)</td>
<td>#Html.EditorFor(r => Model[i].item_rate)</td>
}
</tr>
}
}
And finally, This is my Controller:
[HttpGet]
public ActionResult AddRAR(int? my_id)
{
try
{
var get_items = (from or in db.orders
where or.id == my_id
select new AddOrderReceive()
{
item_name = or.item_name,
quantity_received = or.quantity_receive,
date_received = or.date_receive,
order_receive_id = or.order_receive_id
}).ToList();
foreach(var t in get_items)
{
var get_remain = (from ra in db.order_detail
where ra.contract_id == t.ca_id && ra.order_receive_id == t.order_receive_id
select new
{
consump_quantity = ra.consump_quantity
});
t.quantity_remaining = t.quantity_received - get_remain.Sum(r => r.consump_quantity) ?? t.quantity_received;
}
return View(get_items);
}
catch(Exception ex)
{
}
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult AddReceivng(List<AddOrderReceive> rc_form)
{
//Some Logic
}
The problem is that whenever I post the form, it is always null. But when I remove this block:
#if(Model[i].quantity_remaining == 0)
{
<td colspan="6" class="text-center">Already Sent</td>
}
It starts working. I don't know what's the problem. I've searched everywhere but still can't figure out the problem here.
Your #if(Model[i].quantity_remaining == 0) block of code, if its executed in the first iteration, means that your collection indexers would not be zero based. The DefaultModelBinder requires that collection indexers start at zero and be consecutive.
You can override this behavior by including a hidden input for the indexer. Note also that an <input> is not a valid child of a <tr>, and should be inside a <td> element.
for(var i = 0; i < Model.Count; i++)
{
#if(Model[i].quantity_remaining == 0)
{
<td colspan="6" class="text-center">Already Sent</td>
}
else
{
<td>
<input type="hidden" name="Index" value="#i" /> // Add this
#Html.HiddenFor(r => r[i].item_id)
#Html.CheckBoxFor(r => r[i].IsSelected)
</td>
<td>#Html.EditorFor(r => r[i].item_rate)</td>
}
}
I am trying to pass complex object from my view to my controller.
I give the ability to the client to create infinity listBox.
How can I transfer this to the controller?
Here is description:
For every CompanyFeedbackTopic, the client can insert infinite CompanyFeedBackQuestion(Text with int).
I have this objects:
public class CompanyFeedbackTopic
{
/***fields***/
private readonly int m_topicId;
private int m_companyFeedbackId;
private int m_formatFeedbackId;
private int m_percent;
private List<CompanyFeedbackQuestion> m_companyFeedbackQuestionList;
/***constractors***/
public CompanyFeedbackTopic(int topicId, int companyFeedbackId, int formatFeedbackId, int percent,
List<CompanyFeedbackQuestion> companyFeedbackQuestionList)
{
m_topicId = topicId;
m_companyFeedbackId = companyFeedbackId;
m_formatFeedbackId = formatFeedbackId;
m_percent = percent;
m_companyFeedbackQuestionList = companyFeedbackQuestionList;
}
/***get/set***/
public int TopicId
{ get { return m_topicId; } }
public int CompanyFeedbackId
{ get { return m_companyFeedbackId; } set { m_companyFeedbackId = value; }}
public int FormatFeedbackId
{ get { return m_formatFeedbackId; } set { m_formatFeedbackId = value; }}
public int Percent
{ get { return m_percent; } set { m_percent = value; }}
public List<CompanyFeedbackQuestion> CompanyFeedbackQuestionList
{ get { return m_companyFeedbackQuestionList; } set { m_companyFeedbackQuestionList = value; }
}
/***functions***/
}
public class CompanyFeedbackQuestion
{
/***fields***/
private readonly int m_questionId;
private int m_topicId;
private string m_question;
private int m_fieldGradeOptions;
/***constractors***/
public CompanyFeedbackQuestion(int questionId, int topicId, string question, int fieldGradeOptions)
{
m_questionId = questionId;
m_topicId = topicId;
m_question = question;
m_fieldGradeOptions = fieldGradeOptions;
}
/***get/set***/
public int QuestionId
{ get { return m_questionId; } }
public int TopicId
{ get { return m_topicId; } set { m_topicId = value; }}
public string Question
{ get { return m_question; } set { m_question = value; } }
public int FieldGradeOptions
{ get { return m_fieldGradeOptions; } set { m_fieldGradeOptions = value; }}
}
And this is the view:
#using (Html.BeginForm("SubmitNewForm", "ManageFeedback", FormMethod.Post))
{
#Html.Label("Choose feedback type: ")
#Html.DropDownListFor(model => model.SelectedFeedbaclType, Model.FeedbackTypesDic.Select(i => new SelectListItem() { Text = i.Value, Value = i.Key.ToString() }), "---")
<div id="formTable">
#foreach (var item in Model.FormatFeedbackDic)
{
<h4>#item.Value</h4>
<table id="#item.Key">
<tr>
<td class="tableHeader">#</td>
<td class="tableHeader">question</td>
<td class="tableHeader">Grade Options</td>
</tr>
<tr>
<td>1</td>
<td>#Html.TextBox("SS", "", new { style = "width:500px" })</td>
<td>#Html.DropDownList("fieldGradeOptions", Model.GetDropDownList()) </td>
</tr>
</table>
<br />
<button onclick="AddNewRow(#item.Key);">+</button>
<hr />
}
</div>
<br />
<button onclick="SubmitForm();">Create new feedback</button>
}
How can I transfer it to the view?
You have to do two things
Replace all the foreach loops with simple for loops. Example -
for(int i = o; i< Model.FormatFeedbackDic.Count; i++){}
2.Replace this line //button onclick="SubmitForm();">Create new feedback// with
/input type = "sumbit" />
Now it will pass the complex model back to controller
I am trying to pass data from controller to view. I have searched the web but could not find a solution.
if I do this it works:
Controller:
var yyy = (from a in Connection.Db.Authorities select a) ;
ViewBag.data = yyy;
View:
#foreach(var item in ViewBag.data)
{
#item.Value
}
But the following code does not work:
Controller:
var yyy = (from a in Connection.Db.Authorities select new {Value = a.Value, TypeCode = a.TypeCode, Return = Calculate(a.Return)}) ;
ViewBag.data = yyy;
View:
#foreach(var item in ViewBag.data)
{
#item.Value
}
It gives "item does not contain a definition for Value" for the view file.
Any help would be great.
Thank you.
-edited: updated the second controller linq query. and corrected the first controller linq query.
It's because You already select Value and Value has no such property as Value. You should change in controller:
var yyy = (from a in Connection.Db.Authorities select a.Value); to
var yyy = (from a in Connection.Db.Authorities select a);
OR change the view to
#foreach(var item in ViewBag.data)
{
#item
}
//////////////////////////////////////////////// EDITS ////////////////////////////////////////////////
Than You should not use anonymous object. You should create ViewModelClass. For Example:
public class AuthoritiesViewModel
{
public string Value { get; set; }
public string TypeCode { get; set; }
public string Return { get; set; }
}
And change your controller:
var yyy = (from a in Connection.Db.Authorities select new AuthoritiesViewModel{ Value = a.Value, TypeCode = a.TypeCode, Return = Calculate(a.Return)});
ViewBag.data = yyy;
and in your view you will be able to use:
<table>
<tr>
<th>Value</th>
<th>TypeCode</th>
<th>Return</th>
</tr>
#foreach(AuthoritiesViewModel item in ViewBag.data)
{
<tr>
<td>#item.Value<td>
<td>#item.TypeCode<td>
<td>#item.Return<td>
</tr>
}
</table>
Also, I have a question to You. Why do You use ViewBag to pass data from controller to view? Why don't You use Model to pass these data to view according to MVC pattern?
//////////////////////////////////////////////// MORE EDITS ////////////////////////////////////////////////
To send more than one query result You can create more complex model. For example:
public class AuthoritiesViewModel
{
public string Value { get; set; }
public string TypeCode { get; set; }
public string Return { get; set; }
}
public class AnotherQueryViewModel
{
public string AnotherQueryValue { get; set; }
public string AnotherQueryTypeCode { get; set; }
public string AnotherQueryReturn { get; set; }
}
public class ModelClass
{
IEnumerable<AuthoritiesViewModel> Authorities { get; set; }
IEnumerable<AnotherQueryViewModel> AnotherQueryResults { get; set; }
}
And change the controller:
var yyy = (from a in Connection.Db.Authorities select new AuthoritiesViewModel{ Value = a.Value, TypeCode = a.TypeCode, Return = Calculate(a.Return)});
// do your another select
var zzz = (from smthing select new AnotherQueryViewModel ...)
// create model instance
ModelClass model = new ModelClass()
{
Authorities = yyy.AsEnumerable(),
AnotherQueryResults = zzz..AsEnumerable()
}
// return view with model
return View("view", model);
and in view you can use:
#model ModelClass
#*display first query result*#
<table>
<tr>
<th>Value</th>
<th>TypeCode</th>
<th>Return</th>
</tr>
#foreach(AuthoritiesViewModel item in Model.Authorities)
{
<tr>
<td>#item.Value<td>
<td>#item.TypeCode<td>
<td>#item.Return<td>
</tr>
}
</table>
#*display second query result*#
<table>
<tr>
<th>Another Query Value</th>
<th>Another Query TypeCode</th>
<th>Another Query Return</th>
</tr>
#foreach(AnotherQueryViewModel item in Model.AnotherQueryResults)
{
<tr>
<td>#item.AnotherQueryValue<td>
<td>#item.AnotherQueryTypeCode<td>
<td>#item.AnotherQueryReturn<td>
</tr>
}
</table>
use sth like this
ViewBag.qualification = new SelectList(db.Lookups.Where(x => x.lookup_type == "Qualification"), "lookup_content", "lookup_content");
I did the Getting Started with ASP.NET MVC 3 (C#) tutorial by Rick Anderson, is a catalog of products, is already working, but, since i added a long list of products, now i need a pagedList to get just a number of products per page, looking around i found an example but isn't working, to my project i added on the Models file this class named IPagedList.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace Presupuestos.Models
{
public interface IPagedList
{
int ItemCount
{
get;
set;
}
int PageCount
{
get;
set;
}
int PageIndex
{
get;
set;
}
int PageSize
{
get;
set;
}
bool IsPreviousPage
{
get;
}
bool IsNextPage
{
get;
}
}
public interface IPagedList<T> : IList<T>, IPagedList
{
}
public class PagedList<T> : List<T>, IPagedList<T>
{
private List<Productos> list;
private int p;
private int p_2;
public PagedList(IQueryable<T> source, int index, int pageSize)
{
this.ItemCount = source.Count();
this.PageSize = pageSize;
this.PageIndex = index;
this.AddRange(source.Skip(index * pageSize).Take(pageSize).ToList());
this.PageCount = (int)Math.Ceiling((double)this.ItemCount / this.PageSize);
}
public PagedList(List<T> source, int index, int pageSize)
{
this.ItemCount = source.Count();
this.PageSize = pageSize;
this.PageIndex = index;
this.AddRange(source.Skip(index * pageSize).Take(pageSize).ToList());
}
public PagedList(List<Productos> list, int p, int p_2)
{
// TODO: Complete member initialization
this.list = list;
this.p = p;
this.p_2 = p_2;
}
public int ItemCount
{
get;
set;
}
public int PageCount
{
get;
set;
}
public int PageIndex
{
get;
set;
}
public int PageSize
{
get;
set;
}
public bool IsPreviousPage
{
get
{
return (PageIndex > 0);
}
}
public bool IsNextPage
{
get
{
return (PageIndex + 1) * PageSize <= ItemCount;
}
}
}
public static class Pagination
{
public static PagedList<T> ToPagedList<T>(this IQueryable<T> source, int index, int pageSize)
{
return new PagedList<T>(source, index, pageSize);
}
public static PagedList<T> ToPagedList<T>(this IQueryable<T> source, int index)
{
return new PagedList<T>(source, index, 10);
}
}
}
Also, i added another class named HTMLHelpers.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Text;
using Presupuestos.Models;
namespace Presupuestos.Models
{
public static class ListPaging
{
public static MvcHtmlString Paging(this HtmlHelper html, IPagedList pagedList, string url, string pagePlaceHolder)
{
StringBuilder sb = new StringBuilder();
// only show paging if we have more items than the page size
if (pagedList.ItemCount > pagedList.PageSize)
{
sb.Append("<ul class=\"paging\">");
if (pagedList.IsPreviousPage && pagedList.PageIndex != 1)
{
// previous link
sb.Append("<li class=\"prev\"><a href=\"");
sb.Append(url.Replace(pagePlaceHolder, (pagedList.PageIndex - 1).ToString()));
sb.Append("\" title=\"Go to Previous Page\">prev</a></li>");
}
for (int i = 0; i < pagedList.PageCount; i++)
{
sb.Append("<li>");
if (i == pagedList.PageIndex)
{
sb.Append("<span>").Append((i + 1).ToString()).Append("</span>");
}
else
{
sb.Append("<a href=\"");
sb.Append(url.Replace(pagePlaceHolder, (i + 1).ToString()));
sb.Append("\" title=\"Go to Page ").Append((i + 1).ToString());
sb.Append("\">").Append((i + 1).ToString()).Append("</a>");
}
sb.Append("</li>");
}
if (pagedList.IsNextPage)
{
// next link
sb.Append("<li class=\"next\"><a href=\"");
sb.Append(url.Replace(pagePlaceHolder, (pagedList.PageIndex + 1).ToString()));
sb.Append("\" title=\"Go to Next Page\">next</a></li>");
}
sb.Append("</ul>");
}
return MvcHtmlString.Create(sb.ToString());
}
}
}
Finally this is the view file, i just added the #using presupuestos.models and the last html.paging at the end:
#model IEnumerable<Presupuestos.Models.Productos>
#using Presupuestos.Models
#{
ViewBag.Title = "Productos";
}
<h2>Catalogo de Productos</h2>
<p>
#Html.ActionLink("Agregar Producto", "Create")
</p>
<table>
<tr>
<th>
Marca
</th>
<th>
Codigo
</th>
<th>
Nombre
</th>
<th>
Envase
</th>
<th>
PresentaciĆ³n
</th>
<th>
Linea
</th>
<th>
Categoria
</th>
<th></th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.marca)
</td>
<td>
#Html.DisplayFor(modelItem => item.codigo)
</td>
<td>
#Html.DisplayFor(modelItem => item.nombre)
</td>
<td>
#Html.DisplayFor(modelItem => item.envase)
</td>
<td>
#Html.DisplayFor(modelItem => item.presentaciĆ³n)
</td>
<td>
#Html.DisplayFor(modelItem => item.linea)
</td>
<td>
#Html.DisplayFor(modelItem => item.categoria)
</td>
<td>
#Html.ActionLink("Editar", "Edit", new { id = item.ID }) |
#Html.ActionLink("Detalles", "Details", new { id = item.ID }) |
#Html.ActionLink("Borrar", "Delete", new { id = item.ID })
</td>
</tr>
}
</table>
<div>
#Html.Paging(new PagedList<Productos>(ViewData.Model.ToList(),1,10), Url.Action("Index","Index", new { page = "PAGENUM" }), "PAGENUM")
</div>
Hope you can help me, i have been stuck with this for one day, just last friday i started using mvc3, the good thing was what my boss needs is what is on the tutorial, but, now that i wanted to do this extra thing (pagedlist) i'm really lost!!
It looks as if in this line
#Html.Paging(new PagedList<Productos>(ViewData.Model.ToList(),1,10), Url.Action("Index","Index", new { page = "PAGENUM" }), "PAGENUM")
you are hardcoding the current page index to be 1.
I'd guess that in your Index action method you need might want to have something representing your current page that you can pass through to your view, and replace the hardcoded 1 with that.
e.g.
public void Index(int page = 1)
{
// ... set up your view model
// ...
// ...
// page is added to the url by your paging helper.
ViewBag.CurrentPage = page;
return View(viewModel);
}
And in the view...
#Html.Paging(new PagedList<Productos>(ViewData.Model.ToList(),#ViewBag.CurrentPage,10), Url.Action("Index","Index", new { page = "PAGENUM" }), "PAGENUM")
Based on what you said in your comment, that the paged list doesn't appear at the bottom of the page, I'd really recommend doing some debugging and seeing which code paths are actually executing. But anyway we can maybe guess the following...
First step is to put a breakpoint in the ListPaging.Paging and check it's actually getting called. If it is, and nothing at all is getting appended to your StringBuilder, then perhaps
if (pagedList.ItemCount > pagedList.PageSize)
{
// ...
is not evaluating to true. I'm assuming there's more items in your list than 10, so it should be true. So maybe the reason this isn't evaluating to true is because neither value is being set.
The constructor that you added looks dubious:
public PagedList(List<Productos> list, int p, int p_2)
{
// TODO: Complete member initialization
this.list = list;
this.p = p;
this.p_2 = p_2;
}
None of the properties that PagedList uses actually get set in here. what's the point of this constructor? What are p and p_2? If this constructor is being called, then ItemCount and PageSize will have no value. I'd suggest getting rid of it and letting the other constructors be called.
I'm trying to initialize my checkbox in controller like the code below, but in the view it's not selected whether it's true or false
controller :
foreach (var item in AssignedUsers)
{
if (dc.App_UserTasks.Any(u => u.UserId == item.UserId && u.TaskId == ProjectTask.Id))
{
Users.Single(u => u.Id == item.Id).IsChecked = true;
}
else
{
Users.Single(u => u.Id == item.Id).IsChecked = false;
}
}
view:
#for (int i = 0; i < Model.Responsibles.Count; i++)
{
#Html.CheckBoxFor(u => u.Responsibles[i].IsChecked)
}
send model from controller to view :
var EPT = new EditProjectTaskModel
{
ProjectId = ProjectTask.ProjectId,
Title = ProjectTask.Title,
ProjectName = ProjectTask.App_Project.ProjectName,
Id = ProjectTask.Id,
Description = ProjectTask.Description,
EstimatedTime = ProjectTask.EstimatedTime,
Status = ProjectTask.Status,
Responsibles = Users.ToList()
};
return PartialView("_EditProjectTask", EPT);
Assuming your User ViewModel looks like this
public class UserViewModel
{
public string Name { set;get;}
public int UserId { set;get;}
public bool IsSelected { set;get;}
}
And you have your main view model has a collection of this UserViewModel
public class EditProjectTaskModel
{
public List<UserViewModel > Responsibles { set; get; }
public EditProjectTaskModel()
{
if(this.Responsibles ==null)
this.Responsibles =new List<UserViewModel >();
}
}
Create an editor template called Responsibles.cshtml with the below content
#model YourNameSpace.UserViewModel
#Html.CheckBoxFor(x => x.IsSelected)
#Html.LabelFor(x => x.IsSelected, Model.Name)
#Html.HiddenFor(x => x.UserId)
Now include that in your main view like this, instead of the loop
#model EditProjectTaskModel
#using (Html.BeginForm())
{
//other elements
#Html.EditorFor(m=>m.Responsibles)
<input type="submit" value="Save" />
}
If you want to get the selected checkboxes on a form submit.
[HttpPost]
public ActionResult Save(EditProjectTaskModel model)
{
List<int> userIDs=new List<int>();
foreach (UserViewModel user in model.Responsibles)
{
if (user.IsSelected)
{
//you can get the selected user id's here
userIDs.Add(user.UserId);
}
}
}