Checkbox not set in ASP.NET MVC 3 - asp.net

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);
}
}
}

Related

Get checked checkbox MVC5

I have searched some articles but none of them fits with my problem. i have this code in my cshtml
#model IEnumerable<MonitoreoIntegrado.Models.Sensores>
#using (Html.BeginForm("Graphics", "Datos_extensometro", FormMethod.Post, new { #class = "form-horizontal", role = "form" }))
{
#Html.AntiForgeryToken()
<div style="margin:0; padding:0; border:none; position:absolute; bottom:5px; right:25px;"><input type="submit" id="enviar" class="btn btn-primary" value="Consultar"></div>
<div style="float:left; width:428px; height:105px; padding:5px; overflow-y: scroll;">
<h4 style="margin-top:0px;">Consultar multiples sensores</h4>
#foreach (var item in Model)
{
#Html.CheckBox("sensoresCB", false, new { value = #item.idSensor.ToString() }) #item.nombre <a class="moverse" objetivo="#(item.idSensor)" href=""><span class="glyphicon glyphicon-map-marker" title="Ir al marcador"></span></a><br />
}
</div>
}
and this in my controller:
[HttpPost]
[ValidateAntiForgeryToken]
[Authorize(Roles = RolesSistema.Administrador + "," + RolesSistema.Lectura)]
public ActionResult Graphics()
{
return View();
}
I need help to receive that checkboxes in my controller and check which of them are checked
You should use unique id's for your inputs. The easiest way:
#for (var i = 0; i < Model.Count(); i++)
{
#Html.CheckBox("sensoresCB["+i.ToString()+"]", false, new { value = Model[i].idSensor.ToString() })
//your other stuff
}
And on controller side:
[HttpPost]
[ValidateAntiForgeryToken]
[Authorize(Roles = RolesSistema.Administrador + "," + RolesSistema.Lectura)]
public ActionResult Graphics(bool[] sensoresCB) //note this
{
return View();
}
So you got the array with your selections. Use index to understand what checkbox it is.
You could extend the model of item with a Checked property or similar.
public class GraphicsViewModel {
public GraphicsItemViewModel[] Items { get; set; }
}
public class GraphicsItemViewModel {
public bool Checked { get; set; }
public long IdSensor { get; set; }
}
Then you can render the checkbox with a binding to this Checked property.
#model GraphicsViewModel
#using (Html.BeginForm(/* ....*/) {
// use a for loop so the array is bound correctly
#for (int i = 0; i < Model.Items.Length; i++) {
#Html.CheckBoxFor(m => m.Items[i].Checked)
// post back IdSensor value so we can access it in the controller
#Html.HiddenFor(m => m.Items[i].IdSensor)
}
}
Your controller should accept a model for the POST data, you can reuse the ViewModel:
[HttpPost]
public ActionResult Graphics(GraphicsViewModel postData) {
bool areAllChecked = postData.Items.All(i => i.Checked);
bool isFirstChecked = postData.Items.First().Checked;
bool isCertainIdChecked = postData.Items.Single(i => i.IdSensor == 1337).Checked;
// ...
}
I would like to mention a helpful point here, that is
If a checkbox is checked, then the postback values will contain a
key-value pair of the form [InputName]=[InputValue]
If a checkbox is not checked, then the posted form contains no
reference to the checkbox at all.
So in a controller action method, you can use the name of the checkbox and get the values which is only checked
ex:
public ActionResult Graphics(bool[] sensoresCB)
{
return View();
}
Hope above information was helpful
Thanks
Karthik
Based on #teo van kot reply I achieved to recover the checkboxes values. This is my working code.
Controller:
[HttpPost]
[ValidateAntiForgeryToken]
[Authorize(Roles = RolesSistema.Administrador + "," + RolesSistema.Lectura)]
public ActionResult Graphics(int[] sensoresCB)//you can receive a string[] as well
{
//code and stuff
return View();
}
View:
#model IEnumerable<MonitoreoIntegrado.Models.Sensores>
#using (Html.BeginForm("Graphics", "Datos_extensometro", FormMethod.Post, new { #class = "form-horizontal", role = "form" }))
{
#Html.AntiForgeryToken()
//some code stuff
#{
int i = 0;
foreach (var item in Model)
{
#Html.CheckBox("sensoresCB[" + i.ToString() + "]", false, new { value = item.idSensor.ToString() }) #item.nombre<br />
i++;
}
}
}

how to pass parameter from partial View to controller class in mvc 4

I want redirect details of specific item after click on is name in home page. How can I do that?
This is home controller of my project:
namespace WEB1.Controllers
{
public class HomeController : Controller
{
private projectDBEntities db = new projectDBEntities();
public ActionResult Index()
{
return View();
}
public ActionResult topPlace()
{
var top_place = db.Places.OrderByDescending(a => a.place_rate).Take(6).ToList();
return PartialView("_topPlace", top_place);
}
public ActionResult topServices()
{
var top_service = db.service_provider.OrderByDescending(a => a.Sp_rate).Take(6).ToList();
return PartialView("_topService",top_service);
}
}
}
This is TDS controller:
namespace WEB1.Controllers
{
public class TDSController : Controller
{
private projectDBEntities db = new projectDBEntities();
public ActionResult Details(int id = 0)
{
Place place = db.Places.Find(id);
if (place == null)
{
return HttpNotFound();
}
return View(place);
}
public ActionResult Index(int? page)
{
var places = db.Places.Include(p => p.city).OrderByDescending(s => s.place_rate);
if(Request.HttpMethod != "GET")
{
page = 1;
}
int pageSize = 5;
int pageNumber =(page ?? 1);
return View(places.ToPagedList(pageNumber, pageSize));
}
public ActionResult Historical(int? page)
{
var places = db.Places.Include(p => p.city).OrderByDescending(s => s.place_rate).Where(s => s.Place_type == "Historical");
if (Request.HttpMethod != "GET")
{
page = 1;
}
int pageSize = 5;
int pageNumber = (page ?? 1);
return View(places.ToPagedList(pageNumber, pageSize));
}
public ActionResult Religious(int? page)
{
var places = db.Places.Include(p => p.city).OrderByDescending(s => s.place_rate).Where(s => s.Place_type == "Religious");
if (Request.HttpMethod != "GET")
{
page = 1;
}
int pageSize = 5;
int pageNumber = (page ?? 1);
return View(places.ToPagedList(pageNumber, pageSize));
}
public ActionResult Scenic(int? page)
{
var places = db.Places.Include(p => p.city).OrderByDescending(s => s.place_rate).Where(s => s.Place_type == "Scenic");
if (Request.HttpMethod != "GET")
{
page = 1;
}
int pageSize = 5;
int pageNumber = (page ?? 1);
return View(places.ToPagedList(pageNumber, pageSize));
}
public ActionResult Educational(int? page)
{
var places = db.Places.Include(p => p.city).OrderByDescending(s => s.place_rate).Where(s => s.Place_type == "Educational");
if (Request.HttpMethod != "GET")
{
page = 1;
}
int pageSize = 5;
int pageNumber = (page ?? 1);
return View(places.ToPagedList(pageNumber, pageSize));
}
protected override void Dispose(bool disposing)
{
db.Dispose();
base.Dispose(disposing);
}
}
}
This is top places partail view:
#model IEnumerable<WEB1.Models.Place>
<div class="homebody">
<h3>Most Populer Places</h3>
#foreach (var item in Model)
{
<div class="span4">
<div class="item1">
<p class="name">#Html.ActionLink(item.Place_name, "Details", "TDS", new { id = item.PID })</p>
<p class="cattype">#Html.DisplayFor(modelItem => item.Place_location)</p>
<p>#Html.DisplayFor(modelItem => item.city.Cityname)</p>
<p>#Html.DisplayFor(modelItem => item.place_rate)</p>
</div>
</div>
}
</div>
You use of
#Html.ActionLink(item.Place_name, "Details", "TDS", new { id = item.PID })
is using this overload and adding the item.PID as a htmlAttribute, not a route value. You need to use this overload so that you code will be
#Html.ActionLink(item.Place_name, "Details", "TDS", new { id = item.PID }, null)

Weird MVC Model behavior in EditorTemplate

How is it possible that in a razor EditorTemplate the following commands generate a different value for the same ViewModel:
#Html.TextAreaFor(model => model.Value)
#Model.Value
And no, in the Value get property, the value is not changed
Update 1:
Sorry guys for the short message, you know, tired, frustrated...
Made a sample, got rid of all the partials and templates.
Give the textbox number 1, hit add, number 2, hit add, number 3, hit add.
The remove number 2.
The result is an out of sync between the textbox and the displayed value.
Controller:
public class HomeController : Controller
{
public ActionResult Index()
{
TestModel testModel = TestModel.Create();
Session["model"] = testModel;
return View("Index", testModel);
}
[HttpPost]
public ActionResult Submit(TestModel submitModel, string submit)
{
// merge values in current form
var testModel = Session["model"] as TestModel;
if (testModel == null) throw new Exception("No current model found.");
testModel.MergeFieldValues(submitModel);
if (submit.StartsWith("Add_"))
{
var rowGroupId = Guid.Parse(submit.Substring("Add_".Length));
TestRowGroup rowGroup = testModel.Groups.SelectMany(g => g.RowGroups).Single(rg => rg.RowGroupId == rowGroupId);
rowGroup.AddFieldRow();
}
if (submit.StartsWith("Del_"))
{
var fieldRowId = Guid.Parse(submit.Substring("Del_".Length));
testModel.RemoveFieldRow(fieldRowId);
}
return View("Index", testModel);
}
}
Model:
public class TestModel
{
public List<TestGroup> Groups { get; set; }
public static TestModel Create()
{
var testModel = new TestModel { Groups = new List<TestGroup>() };
var grp = new TestGroup { RowGroups = new List<TestRowGroup>() };
var rowGrp = new TestRowGroup { RowGroupId = Guid.NewGuid(), FieldRows = new List<TestFieldRow>() };
var fldRow = new TestFieldRow { FieldRowId = Guid.NewGuid(), Fields = new List<TestFormField>() };
var fld = new TestFormField { FieldId = Guid.NewGuid() };
fldRow.Fields.Add(fld);
rowGrp.FieldRows.Add(fldRow);
grp.RowGroups.Add(rowGrp);
testModel.Groups.Add(grp);
return testModel;
}
public void MergeFieldValues(TestModel src)
{
foreach (var srcField in src.Groups.SelectMany(g => g.RowGroups.SelectMany(rg => rg.FieldRows.SelectMany(fr => fr.Fields))))
{
var destField = Groups.SelectMany(g => g.RowGroups.SelectMany(rg => rg.FieldRows.SelectMany(fr => fr.Fields))).FirstOrDefault(f => f.FieldId == srcField.FieldId);
if (destField == null) throw new Exception("Field not found during merge");
destField.Value = srcField.Value;
}
}
public void RemoveFieldRow(Guid fieldRowId)
{
foreach (var group in Groups)
{
foreach (var rowGroup in group.RowGroups)
{
rowGroup.FieldRows.RemoveAll(fieldRow => fieldRow.FieldRowId == fieldRowId);
}
}
}
}
public class TestGroup
{
public List<TestRowGroup> RowGroups { get; set; }
}
public class TestRowGroup
{
public List<TestFieldRow> FieldRows { get; set; }
public Guid RowGroupId { get; set; }
public void AddFieldRow()
{
var newRow = new TestFieldRow
{
Fields = new List<TestFormField>()
};
newRow.FieldRowId = Guid.NewGuid();
var fld = new TestFormField { FieldId = Guid.NewGuid() };
newRow.Fields.Add(fld);
FieldRows.Add(newRow);
}
}
public class TestFieldRow
{
public Guid FieldRowId { get; set; }
public List<TestFormField> Fields { get; set; }
}
public class TestFormField
{
public Guid FieldId { get; set; }
public string Value { get; set; }
}
View:
#model FieldTest.Models.TestModel
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
</head>
<body>
#using (Html.BeginForm("Submit", "Home", FormMethod.Post))
{
for (int g = 0; g < Model.Groups.Count; g++)
{
for (int rg = 0; rg < Model.Groups[g].RowGroups.Count; rg++)
{
for (int fr = 0; fr < Model.Groups[g].RowGroups[rg].FieldRows.Count; fr++)
{
for (int f = 0; f < Model.Groups[g].RowGroups[rg].FieldRows[fr].Fields.Count; f++)
{
#Html.HiddenFor(model => model.Groups[g].RowGroups[rg].FieldRows[fr].Fields[f].FieldId)
#Model.Groups[g].RowGroups[rg].FieldRows[fr].Fields[f].Value
#Html.TextBoxFor(model => model.Groups[g].RowGroups[rg].FieldRows[fr].Fields[f].Value)
<button onclick="return confirm('Are you sure you would like to remove this row?');" type="submit" value="#string.Format("Del_{0}", Model.Groups[g].RowGroups[rg].FieldRows[fr].FieldRowId)" name="submit">Remove</button>
<hr />
}
}
<button type="submit" value="#string.Format("Add_{0}", Model.Groups[g].RowGroups[rg].RowGroupId)" name="submit">Add</button>
}
}
<input type="submit" value="Submit" name="submit" />
}
</body>
</html>
More importantly, are you sure this is an EditorTemplate problem? If you put the code in your main view, does it also happen? Did you try that? Or did you assume it was an EditorTemplate problem?
Since you neglected to provide any context for your question, all we can do is guess. More than likely, you have modified the contents of the view model in a post operation, and are now surprised that the Html helpers are using the old value rather than the value from the model.
If so, this is "by design", and a well documented (hundreds if not thousands of questions already here on SO about this issue). The MVC Helpers prefer the contents of the ModelState over the model itself in post operations. You have to clear the ModelState in order to work around it.

CheckBox List in ASP.net MVC3

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);
}

ASP.NET MVC 3 Telerik Razor grid with editable foreign key dropdown column

I am trying to create an Ajax Telerik grid in Razor that has an updateable foreign key column that shows a dropdown list. I've copied my page pretty much like the example, and everything works. I can add new records, delete them and edit them. The only thing that doesn't work is that I get a textfield with the integer when I update a record in my grid, instead of a dropdown list with all the possibilities of the foreign key table.
Anyone have any ideas on how I could fix this? See code below.
Telerik grid:
#(Html.Telerik().Grid<EditableAccount>()
.Name("Grid")
.ToolBar(commands => commands.Insert().ButtonType(GridButtonType.Text).ImageHtmlAttributes(new { style = "margin-left:0" }))
.DataBinding(dataBinding => dataBinding.Ajax()
.Insert("InsertAccount", "Administration")
.Update("SaveAccount", "Administration")
.Delete("DeleteAccount", "Administration"))
.DataKeys(keys => { keys.Add(a => a.AccountId); })
.Columns(columns =>
{
columns.ForeignKey(b => b.BankId, (IEnumerable)ViewData["Banks"], "ID", "Name").Width(50);
columns.Bound(a => a.AccountNumber).Width(110);
columns.Command(commands =>
{
commands.Edit().ButtonType(GridButtonType.Image);
commands.Delete().ButtonType(GridButtonType.Image);
}).Width(16);
})
.Editable(editing => editing.Mode(GridEditMode.InLine))
.Pageable()
.Scrollable()
.Sortable()
)
Controller:
[GridAction]
public ActionResult Accounts()
{
ViewData["Banks"] = db.Banks.Select(b => new { Id = b.BankId, Name = b.Name });
return View(new GridModel(accountRepository.All()));
}
[AcceptVerbs(HttpVerbs.Post)]
[GridAction]
public ActionResult InsertAccount()
{
//Create a new instance of the EditableProduct class.
EditableAccount account = new EditableAccount();
//Perform model binding (fill the product properties and validate it).
if (TryUpdateModel(account))
{
//The model is valid - insert the product.
accountRepository.Insert(account);
}
//Rebind the grid
return View(new GridModel(accountRepository.All()));
}
[AcceptVerbs(HttpVerbs.Post)]
[GridAction]
public ActionResult SaveAccount(int id, int bankId)
{
EditableAccount account = new EditableAccount
{
AccountId = id,
Bank = db.Banks
.Where(b => b.BankId == bankId)
.Select(b => b.Name).SingleOrDefault(),
BankId = bankId
};
TryUpdateModel(account);
accountRepository.Update(account);
return View(new GridModel(accountRepository.All()));
}
[AcceptVerbs(HttpVerbs.Post)]
[GridAction]
public ActionResult DeleteAccount(int id)
{
//Find a customer with ProductID equal to the id action parameter
EditableAccount account = accountRepository.One(a => a.AccountId == id);
if (account != null)
{
//Delete the record
accountRepository.Delete(account);
}
//Rebind the grid
return View(new GridModel(accountRepository.All()));
}
Model:
public class EditableAccount
{
[ScaffoldColumn(false)]
public int AccountId { get; set; }
[Required]
[UIHint("GridForeignKey")]
[DisplayName("Bank")]
public int BankId { get; set; }
public string Bank { get; set; }
[Required]
[DisplayName("AccountNumber")]
public int AccountNumber { get; set; }
}
Repository:
public IList<EditableAccount> All()
{
IList<EditableAccount> result =
(from account in db.Accounts
select new EditableAccount
{
AccountId = account.AccountId,
Bank = account.Bank.Name,
BankId = account.BankId,
AccountNumber = account.AccountNr
}).ToList();
return result;
}
public EditableAccount One(Func<EditableAccount, bool> predicate)
{
return All().Where(predicate).FirstOrDefault();
}
public void Insert(EditableAccount insertedAccount)
{
Account account = new Account();
account.BankId = insertedAccount.BankId;
account.AccountNr = insertedAccount.AccountNumber;
db.Accounts.InsertOnSubmit(account);
db.SubmitChanges();
}
public void Update(EditableAccount updatedAccount)
{
Account account = db.Accounts.SingleOrDefault(a => a.AccountId == updatedAccount.AccountId);
account.BankId = updatedAccount.BankId;
account.AccountNr = updatedAccount.AccountNumber;
db.SubmitChanges();
}
public void Delete(EditableAccount deletedAccount)
{
Account account = db.Accounts.SingleOrDefault(a => a.AccountId == deletedAccount.AccountId);
db.Accounts.DeleteOnSubmit(account);
db.SubmitChanges();
}
Someone answered my question on the Telerik forums:
http://www.telerik.com/community/forums/aspnet-ajax/grid/asp-net-mvc-razor-grid-with-editable-foreign-key-dropdown-column.aspx

Resources