In ASP.NET MVC, I\'ve an action which takes user input about rows and columns and then it navigates to the action which generates required number of rows and columns based on th
to get value horizontally you have to put name attribute in your view like
<table class="table table-striped table-advance table-hover">
<thead>
<tr>
<th class="col-wg-15">Name</th>
<th class="col-wg-5 t1_td_per">Allocation Percentage</th>
<th class="col-wg-5">Allocation</th>
</tr>
</thead>
<tbody>
@{
foreach (var item in Model.t1_List)
{
<tr>
<td>
@item.Name
</td>
<td class="t1_td_per">
<input type="text" name="t1_txtper-@item.BId" id="t1_txtper-@item.BId" value="@item.AllocationPercentage" class="t1_AllocationPer" maxlength="20" placeholder="Allocation Percentage" style="text-align:right;" />
</td>
<td>
<input type="text" name="t1_txtamt-@item.BId" id="t1_txtamt-@item.BId" value="@item.AllocationAmount" class="t1_AllocationAmt decimalval" maxlength="20" placeholder="Allocation" style="text-align:right;" />
</td>
</tr>
}
}
</tbody>
</table>
and then at the time of post or in action method you can get this as
Dictionary<decimal, decimal> _d_amt = new Dictionary<decimal, decimal>();
Dictionary<decimal, decimal> _d_per = new Dictionary<decimal, decimal>();
foreach (var key in _frm.AllKeys)
{
if (key.ParseString().Contains("t1_txtamt-"))
{
decimal _val = _frm[key].ParseString().ParseDecimal();
decimal _id = key.Replace("t1_txtamt-", "").ParseString().ParseDecimal();
_d_amt.Add(_id, _val);
}
else if (key.ParseString().Contains("t1_txtper-"))
{
decimal _val = _frm[key].ParseString().ParseDecimal();
decimal _id = key.Replace("t1_txtper-", "").ParseString().ParseDecimal();
_d_per.Add(_id, _val);
}
}
foreach (var item in _model.t1_List)
{
AllocationClass _litem = new AllocationClass();
_litem.BId = item.BId;
_litem.Name = item.Name;
_litem.AllocationPercentage = (from p in _d_per where p.Key == item.BId select p.Value).FirstOrDefault().ParseDecimal();
_litem.AllocationAmount = (from p in _d_amt where p.Key == item.BId select p.Value).FirstOrDefault().ParseDecimal();
_list.Add(_litem);
}
Create view models that represent what you want to display/edit
public class TableVM
{
public TableVM()
{
Rows = new List<RowVM>();
}
public TableVM(int rows, int columns) : this()
{
for(int i = 0; i < rows; i++)
{
Rows.Add(new RowVM(columns));
}
}
public List<string> Headers { get; set; } // for columns headers
public List<RowVM> Rows { get; set; }
}
public class RowVM
{
public RowVM()
{
Cells = new List<CellVM>();
}
public RowVM(int columns) : this()
{
for(int i = 0; i < columns; i++)
{
Cells.Add(new CellVM());
}
}
public List<CellVM> Cells { get; set; }
}
public class CellVM
{
public string Value { get; set; }
}
and in the GET method, initialize a new TableVM
and return it to the view
TableVM model = new TableVM(5, 5); // 5 x 5 grid
model.Headers = new List<string>{ "col 1", "col 2", "col 3", col 4", "col 5" };
return View(model);
View
@model TableVM
....
<table>
<thead>
<tr>
@foreach(string header in Model.Headers)
{
<th>@header</th>
}
</tr>
</thead>
<tbody>
@for(int r = 0; r < Model.Rows.Count; r++)
{
<tr>
for (int c = 0; c < Model.Rows[r].Cells.Count; c++)
{
<td>@Html.TextBoxFor(m => m.Rows[r].Cells[c].Value</td>
}
</tr>
}
</tbody>
</table>
Then change you POST method to accept the model
[HttpPost]
public ActionResult Enter(TableVM model)
You can now access each row/column using indexers, for example model.Rows[1].Cells[2].Value
will return the value of the 3rd column in the second row
Simplest way would be to post the number of rows and columns back with the input values:
<div class="container" style='width:@(240 * Model.Columns.Capacity)px;overflow-y:auto'>
<div class="row">
@using (Html.BeginForm())
{
<table style='width:100%' class='table table-condensed'>
<tbody>
@for (int k = 0; k < Model.Rows.Capacity; k++)
{
<tr>
@for (int i = 0; i < Model.Columns.Capacity; i++)
{
<td>
@Html.TextBox("name" + k + i, null, new { @class = "form-control" })
</td>
}
</tr>
}
</tbody>
</table>
<input name="rows" type="hidden" value="@Model.Rows.Capacity"/>
<input name="columns" type="hidden" value="@Model.Columns.Capacity"/>
<input type="submit" name="name" value="Submit" class="btn btn-primary" />
}
</div>
Once you have these, you can use them to work out how many iterations to do and the input names to query:
[HttpPost]
public ActionResult Enter(FormCollection form)
{
var data = new List<List<string>>();
var rows = int.Parse(form["rows"]);
var columns = int.Parse(form["columns"]);
for (var r = 0; r < rows; r++)
{
var rowData = new List<string>();
for (var c = 0; c < columns; c++)
{
rowData.Add(form[string.Format("name{0}{1}", r, c)]);
}
data.Add(rowData);
}
return View(data);
}