Reputation: 23
I am using MVC 4 Visual Studio 2012 with Razor.
I am generating a table based off of several tables pulled into a dataset from a remote call to a SQL server.
I want to be able to output these tables onto the webpage and then create two columns of checkboxes beside them in order to assign them to one area or another (it essentially sorts data into accepted and not accepted, while allowing some to continue pending if a decision has not been made).
I currently have all the tables in the dataset being assigned to datatables in the controller and then exported to the razor page. I do not have a model set up for this as of yet and I'm not sure what I would require in one if I did.
This is my current View:
@{
ViewBag.Title = "Requisitions";
}
<table class="table">
<thead>
<tr>
@foreach (System.Data.DataColumn col in Model.Columns)
{
<th class ="td">@col.Caption</th>
}
</tr>
</thead>
<tbody>
@foreach(System.Data.DataRow row in Model.Rows)
{
<tr>
@foreach (var cell in row.ItemArray)
{
<td class="td">@cell.ToString()</td>
}
</tr>
}
</tbody>
</table>
This is my current controller:
DataTable R = new DataTable();
public void GetData()
{
string connString = "Data Source=.;database=dataBase;Integrated Security=SSPI";
DataSet dataset = new DataSet();
SqlDataAdapter adapter = new SqlDataAdapter("dbo.procApprovalSelectPending", connString);
using (adapter)
{
adapter.SelectCommand.CommandType = CommandType.StoredProcedure;
adapter.Fill(dataset);
}
int count = dataset.Tables.Count;
for (int i = 0; i < dataset.Tables.Count; i++)
{
// Do something for each recordset (11 recordsets)
if (i == 0)
{
R = dataset.Tables[i];
}
}
dataset.Dispose();
adapter.Dispose();
}
public ActionResult Rs()
{
GetData();
return View(R);
}
I have more datatables than shown but they were removed to conserve space.
To sum it up, I would like two checkbox columns that are aligned with each row that is created from the datatable that allow me to choose that portion of data to send back to the server what has been changed with it, and creating a dynamic checkbox for each row was giving me an error such that :
@foreach(System.Data.DataRow row in Model.Rows)
{
<tr>
@foreach (var cell in row.ItemArray)
{
<td class="td">@cell.ToString()</td>
}
<td class="td">@Html.CheckBoxFor(m => m.Checkbox)</td>
</tr>
}
"An expression tree may not contain a dynamic operation"
Thanks in advance!
Upvotes: 2
Views: 23149
Reputation: 580
Use Following pattern
I have Created one static Class that is called as CommonUtilities it is giving me FormCollection,Checkboxname and valueofKey
public static class CommonUtilities
{
public static List<string> GetCheckboxSelectedValue(FormCollection frm, string checkboxname, string value)
{
List<string> retls = new List<string>();
var fileIds = frm[value].Split(',');
var selectedIndices = frm[checkboxname].Replace("true,false", "true").Split(',').Select((item, index) =>
new {
item= item,
index= index
}).Where(row=>row.item =="true")
.Select(row => row.index).ToArray();
if (selectedIndices.Count() > 0)
{
retls.AddRange(selectedIndices.Select(index => fileIds[index]));
}
return retls;
}
}
Controller
List<string> selectedKeypair = CommonUtilities.GetCheckboxSelectedValue(frm, "m.BoolSelectedVal", "m.Key");
view
@foreach (MVCCareerModule.Models.Requirement m in Model.RequirementSearchResult)
{
<tr>
<td>
@Html.CheckBoxFor(modelitem => m.Apply)
@Html.HiddenFor(modelitem => m.Req_ID, new { Value = m.Req_ID })
</td>
</tr>
}
You will receive all Selected IDs in selectedKeypair
Upvotes: 1
Reputation:
You should create a view model to represent the properties you want to display, including 2 additional boolean properties for 'accepted' and 'not accepted'. Assuming your columns are ID and Name
public class MyModel
{
public int ID { get; set; }
public string Name { get; set; }
public bool Accepted { get; set; }
public bool NotAccepted { get; set; }
}
and create a collection based on each row in your table that you want to display
public ActionResult Rs()
{
List<MyModel> items = new List<MyModel>();
// Populate items from your datatable
return View(items);
}
then in your view
@model List<MyModel>
@using (Html.BeginForm()
{
<table>
@for (int i = 0; i < Model.Count; i++)
{
<tr>
<td>@Html.TextBoxFor(m => m[i].ID)</tr>
<td>@Html.TextBoxFor(m => m[i].Name)</tr>
<td>@Html.CheckBoxFor(m => m[i].Accepted)</tr>
<td>@Html.CheckBoxFor(m => m[i].NotAccepted)</tr>
</tr>
}
</table>
<input type="submit" value="Save" />
}
then in your post method
[HttpPost]
public ActionResult Rs(List<MyModel> model)
{
foreach(MyModel item in model)
{
if(item.Accepted) {.. // do something
else if (item.NotAccepted) { .. // do something else
else {.. // do another thing
}
}
Upvotes: 5