I have a dynamically generated gridview which is made of table and textbox controls and an add and remove button.
The add button calls a jquery function which adds new row at the bottom of the grid and the remove button removes a particular row.
Problem:
Assuming I have 5 rows from the database and I add a new row and perform a count to check the number of textboxs I discover that it count only newly added textbox.
View:
#{
for (var i = 0; i < Model.Image_Count; i++ )
{
<tbody id="image-row">
<tr>
<td class="left">
<table>
<tr>
<td>
<img class="img-tag" id="img-row-tag" src="#Model.Product_ImageLink[i]" alt="no-image" />
#Html.HiddenFor(x => x.Product_ImageLink[i])
</td>
</tr>
<tr>
<td>
<a id="lnk" onclick="_file_upload(this);" class="button">Upload File</a>
<input id="file_row" class="file-tag" onchange="readURL_(this, i);" type="file" name="file_row" />
<div class="validation-area">
#Html.ValidationMessageFor(x => x.Product_ImageLink[i])
</div>
</td>
</tr>
</table>
</td>
<td class="right">
#Html.TextBoxFor(x => x.Product_SortOrder[i])
</td>
<td class="left"><a onclick="$('#image-row' + i).remove();" class="button">-</a></td>
</tr>
</tbody>
}
}
JQuery:
var attribute_row = 1;
function addattribute(){
html = '<tbody id="attribute-row' + attribute_row + '">';
html += ' <tr>';
html += ' <td class="left">#Html.TextBoxFor(x=>x.AttributeName)<div class="validation-area">#Html.ValidationMessageFor(x => x.AttributeName)</div></td>';
html += ' <td class="right"><input type="text" name="Attribute_SortOrder" id="Attribute_SortOrder"></td>';
html += ' <td class="left"><a onclick="$(\'#attribute-row' + attribute_row + '\').remove();" class="button">-</a></td>';html += ' </tr>';
html += '</tbody>';$('#attribute tfoot').before(html);
attribute_row++;$('#Attribute_Count').val(attribute_row);
}
Model:
public bool[] IsDefault { get; set; }
public string Image_Link { get; set; }
public string Image_Path { get; set; }
public string[] Product_ImageLink { get; set; }
public int[] Product_SortOrder { get; set; }
public int Image_Count { get; set; }
public int iCount { get; set; }
Controller:
public ActionResult Products(int? id)
{
if (id == null)
{
}
else
{
var y = _repository.GetProductImage(id);
List<string> _Product_ImageLink = new List<string>();
List<int> _Product_SortOrder = new List<int>();
foreach (var z in y)
{
_Product_ImageLink.Add(z.Product_ImageLink);
_Product_SortOrder.Add(z.Product_SortOrder);
}
model.Product_SortOrder = _Product_SortOrder.ToArray();
model.Product_ImageLink = _Product_ImageLink.ToArray();
}
return View(model);
}
[HttpPost]
public ActionResult Products(ProductModel _model, int? id)
{
if (ModelState.IsValid)
{
if (_model.ProductId == 0)
{
}
else
{
int jCount = _model.Product_ImageLink.Count();
}
}
else
{
_Message("Error", "Please check the form carefully for errors!");
}
ViewBag.IsButtonClick = true;
return View(_model);
}
What you can do is maybe initialize your javascript variable with Razor:
var attribute_row = #Model.Image.Count();
Hope it'll help you!
Sebastien
Related
public class Libro
{
public string Titolo { get; set; }
public string Autore { get; set; }
public string Editore { get; set; }
public int ISBN { get; set; }
public int Pagine { get; set; }
public decimal Prezzo { get; set; }
public int Quantità { get; set; }
public Libro BuildLibro(string input)
{
Libro result = null;
if (!String.IsNullOrEmpty(input))
{
var inputArray = input.Split('*');
if (inputArray.Length >= 6)
{
result = new Libro();
result.Titolo = inputArray[0];
result.Autore = inputArray[1];
result.Editore = inputArray[2];
if (!string.IsNullOrEmpty(inputArray[3]))
{
int.TryParse(inputArray[3], out int num);
result.ISBN= num;
}
if (!string.IsNullOrEmpty(inputArray[4]))
{
int.TryParse(inputArray[4], out int num);
result.Pagine = num;
}
if (!string.IsNullOrEmpty(inputArray[5]))
{
decimal.TryParse(inputArray[5], out decimal num);
result.Prezzo = num/100;
}
if (!string.IsNullOrEmpty(inputArray[6]))
{
int.TryParse(inputArray[6], out int num);
result.Quantità = num;
}
}
}
return result;
}
}
}
in the Index.cshtml
<table class="table">
<tr>
<th>
Titolo
</th>
<th>
Autore
</th>
<th>
Editore
</th>
<th>
Prezzo(€)
</th>
</tr>
#foreach (var line in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => line.Titolo)
<p> Visualizza la scheda </p>
</td>
<td>
#Html.DisplayFor(modelItem => line.Autore)
</td>
<td>
#Html.DisplayFor(modelItem => line.Editore)
</td>
<td>
#Html.DisplayFor(modelItem => line.Prezzo)
</td>
</tr>
}
</table>
</body>
</html>
I have created a model of a book based on a list of a file.txt in order to display a table with all the books available, their author, publisher and price, now, for each book, I should be able to open a descriptive sheet also containing ISBN , pages and quantities. From paragraph in the html below #Html.DisplayFor(modelItem => line.Titolo) I inserted a link to the About.cshtml, but I don't know what code to write inside and what to write in the controller too?
this is my controller at the moment:
public ActionResult Index()
{
var fileInput = Reader.Read("C:/Users/test/source/repos/Books/Books/App_Data/Libri.txt");
var libriList = new List<Libro>();
if (fileInput != null)
{
for (var i = 1; i < fileInput.Count; i++)
{
var libri = new Libro();
libri = libri.BuildLibro(fileInput[i]);
if (libri != null)
{
libriList.Add(libri);
}
}
}
Session["currentLibriList"] = libriList;
return View(libriList);
}
public ActionResult About(string titoloId)
{
var myFilteredList = new List<Libro>();
if (Session["currentLibriList"] != null)
{
var lookupList = (List<Libro>)(Session["currentLibriList"]);
myFilteredList = (List<Libro>)lookupList.Where(x => x.Titolo == titoloId);
}
return View(myFilteredList);
}
and this is About.cshtml
<html>
<body>
<table class="table">
#foreach (var line in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => line.Titolo)
</td>
<td>
#Html.DisplayFor(modelItem => line.Autore)
</td>
<td>
#Html.DisplayFor(modelItem => line.Editore)
</td>
<td>
#Html.DisplayFor(modelItem => line.Prezzo)<p>€</p>
</td>
<td>
#Html.DisplayFor(modelItem => line.Pagine)
</td>
<td>
#Html.DisplayFor(modelItem => line.Quantità)
</td>
<td>
#Html.DisplayFor(modelItem => line.ISBN)
</td>
</tr>
}
</table>
</body>
</html>
You can use Url.Action helper to send the line.Titolo to your Controller method and get your data:
<td>
<p><a class="btn btn-default" href="#Url.Action("About","Home", new { titoloId = line.Titolo })">#line.Titolo</a></p>
</td>
Your Index method will store the data in a Session variable and then you retrieve this Session in your About method and cast it to the List<Libro> type. Once you get the list, then you can filter it out based on the titolId. Your last step would be to send this filtered list to your About view. You need to build your About view as per your requirement with the filtered data.
public ActionResult About(string titoloId)
{
var myFilteredList= new List<Libro>();
//Get data for titoloId
if (Session["currentLibriList"] != null)
{
var lookupList = (List<Libro>)(Session["currentLibriList"]);
myFilteredList=lookupList.Where(x=>x.Titolo == titoloId);
}
return View(myFilteredList);
}
public ActionResult Index()
{
var fileInput = Reader.Read("C:/Users/test/source/repos/Books/Books/App_Data/Libri.txt");
var libriList = new List<Libro>();
if (fileInput != null)
{
for (var i = 1; i < fileInput.Count; i++)
{
var libri = new Libro();
libri = libri.BuildLibro(fileInput[i]);
if (libri != null)
{
libriList.Add(libri);
}
}
}
//Set your session here
Session["currentLibriList"]=libriList;
return View(libriList);
}
I have a view:
#using(Html.BeginForm())
{
<div>
<table id="dimensionFeedbackTable">
<tbody>
#for(int i = 0; i < 6; i++)
{
<tr>
<td>
<div>
<p>
<text>
Rate #i
</text>
</p>
</div>
</td>
#foreach(var item in Model.DeptList)
{
<td>
<div style="text-align: center;">
#Html.RadioButtonFor(m => item.DepartmentValue, i,
new
{
id = i,
style = "min-height:45px;"
})
</div>
</td>
}
</tr>
}
</tbody>
</table>
<button id="submitComment" value="submit">
#{
<text>Submit</text>
}
</button>
</div>
}
Model in that view is EmployeeModelClass. Here it is:
public class EmployeeModelClass
{
public int Id
{
get; set;
}
public IEnumerable<DepartmentModelClass> DeptList
{
get; set;
}
}
public class DepartmentModelClass
{
public string DepartmentCode
{
get; set;
}
[Range(1, 6)]
public int? DepartmentValue
{
get; set;
}
}
My controller:
[HttpPost]
public ActionResult Index(EmployeeModelClass emp, IEnumerable<DepartmentModelClass> qec)
{
emp.DeptList = qec;
return View(emp);
}
I am trying to accomplish next:
Each row should be group for it self. For example Rate 1 row can have only one radio button selected. Now, these buttons should be bound. If second radio button is selected in any row then its value (DepartmentValue) should be set to 2. So when I submit, I get a collection of which radio buttons are selected.
I've tried a lot of combinations with setting proper model and binding it. Also tried html helper method RadioButton, but still no luck to return the values. Closest that I managed to get is returning a collection but although radio buttons are selected in Controller, collection is not null but values (DepartmentValues) are null.
Also, there are similar answers here but for some reason none of them is working for me. Any help and pointing direction are appreciated. Losing my mind over a simple thing.
One more thing, I tried with creating partials view but still now luck. I read online that is a bad practice to place for/foreach loop in a view and tried to simplify it but this approach is also not working.
Thanks
I notice few issues -
for loop and foreach loop are opposite.
Should use for for array of controls instead of foreach
Do not explicitly assign id to radio buttons new { id = i, ...})
View
#model DemoMvc.Models.EmployeeViewModel
#using (Html.BeginForm())
{
<div>
<table id="dimensionFeedbackTable">
<tbody>
#for (int i = 0; i < Model.DepartmentViewModels.Count; i++){
<tr>
<td>
<div>
<p>
<text>
Rate #Model.DepartmentViewModels[i].DepartmentCode
</text>
</p>
</div>
</td>
#for (int j = 1; j <= 6; j++)
{
<td>
<div style="text-align: center;">
#Html.RadioButtonFor(m =>
Model.DepartmentViewModels[i].DepartmentValue,
j, new { style = "min-height:45px;" })
#j
</div>
</td>
}
</tr>
}
</tbody>
</table>
<button id="submitComment" value="submit">Submit</button>
</div>
}
Model
public class EmployeeViewModel
{
public int Id { get; set; }
public IList<DepartmentViewModel> DepartmentViewModels { get; set; }
}
public class DepartmentViewModel
{
public string DepartmentCode { get; set; }
public int? DepartmentValue { get; set; }
}
Controller
public ActionResult Index()
{
// This could come from database.
var model = new EmployeeViewModel
{
DepartmentViewModels = new List<DepartmentViewModel>
{
new DepartmentViewModel{ DepartmentCode = "ABC", DepartmentValue = 1},
new DepartmentViewModel{ DepartmentCode = "DEF", DepartmentValue = 2},
new DepartmentViewModel{ DepartmentCode = "GHI", DepartmentValue = 3},
}
};
return View(model);
}
[HttpPost]
public ActionResult Index(EmployeeViewModel model)
{
return View(model);
}
Result
Posted Value
I am working on a project in dot Net + share-point,
In there controller get sharepoint list record & create a list of list object.
In view catch the object as one model and dilplay in a table.
Table view
enter image description here
Index.cshtml
#using( Html.BeginForm() )
{
<table id = "timeTrackingView" border="1" >
<tr>
<th>Projects</th>
#for (var date = #Model.Dates.AddDays(-(#Model.DateRange-1)); date <= #Model.Dates; date = date.AddDays(1))
{
<th >#date.Day/#date.Month/#date.Year</th>
}
</tr>
#{ double[] totalForToday = new double[#Model.DateRange];}
#for (int i = 0; i < #Model.TimeTrakings.Count; i++)
{
//var projectName = #Model.TimeTrakings[i][0].ProjectName;
int index = 0;
<tr>
<td>
#Model.TimeTrakings[i][0].ProjectName
</td>
#for (int j = 0; j < Model.TimeTrakings[i].Count(); j++)
{
totalForToday[index] = totalForToday[index] + #Model.TimeTrakings[i][j].Hours;
var time = #Html.EditorFor(model => #Model.TimeTrakings[i][j]);
<td>#time</td>
#*#Html.EditorFor(model => #Model.TimeTrakings[i][j].Hours)*#
index++;
}
</tr>
}
<tr>
<td>Total for day</td>
#foreach(var tot in totalForToday)
{
<td>#tot</td>
}
</tr>
</table>
<input type="submit" name="SubmitBtn"/>
}
I am trying to get table data into controller.. help me im my code only gettinh hours, need get project name date & hours together.
My controller.
[HttpPost]
public ActionResult Index(TimeTracking timeTracking)
{
////do the logic here
return View(this.ReceiveTimeTrackingData());
}
I Used two mode-:
Model1
public class TimeTrackingDetails
{
public string ProjectName { get; set; }
public DateTime Date { get; set; }
public double Hours { get; set; }
}
Model 2-:
public class TimeTracking
{
public List<List<TimeTrackingDetails>> TimeTrakings { get; set; }
}
If you need project name you should create an input. Now in your code you have just plain text with this line:
#Model.TimeTrakings[i][0].ProjectName
Just add another line onder it:
#Model.TimeTrakings[i][0].ProjectName
// this line will create additional hidden input and on form post it will be sended to server.
#Html.HiddenFor(x => x.TimeTrakings[i][0].ProjectName)
I'm working on a small project. The intention is to maintain the presences of a couple of users on some specific dates. This dates are first chosen by the user.
Therefor I use a view model. This will provide all possible data with a check box in a table to show to the user.
In the view itself I walk every day in the given view modeland I let the view generate a tag and an editor object (Html.EditorFor ()). All this is surrounded by the form creation (# Html.BeginForm ()). Rendering the view is not the problem.
The problem is when I try to return the view model. The viewmodel object that I receive is an object with null - objects in themselves. Like it has been created by the default constructor.
Controller:
[HttpGet]
public ActionResult OpldagenLt()
{
var lt = _gebruikerRepository.GeefTraject(_gebruikerRepository.TrajectId);
List<DatumModel> data = new List<DatumModel>();
foreach (Opleidingdag opldag in lt.GeefOpleidingdagenKleinerDanOfGelijkAanVandaag())
data.Add(new DatumModel(opldag));
List<ToekomstModel> toekomst = new List<ToekomstModel>();
foreach (Opleidingdag opldag in lt.GeefOpleidingdagenGroterDanVandaag())
toekomst.Add(new ToekomstModel(opldag));
DataModel datamod = new DataModel();
datamod.Datums = data;
datamod.Toekomst = toekomst;
if (lt.ControleerAantalOpleidingdagen())
{
_gebruikerRepository.GekozenDagen = GekozenDagen(datamod) as List<Opleidingdag>;
return RedirectToAction("Index", "Aanwezigheid");
}
return View(datamod);
}
[HttpPost]
public ActionResult OpldagenLt(DataModel model)
{
if (!ModelState.IsValid)
{
return View(model);
}
_gebruikerRepository.GekozenDagen = GekozenDagen(model) as List<Opleidingdag>;
return RedirectToAction("Index", "Aanwezigheid");
}
public ICollection<Opleidingdag> GekozenDagen(DataModel datamod)
{
List<Opleidingdag> dagen = new List<Opleidingdag>();
foreach (DatumModel datum in datamod.Datums)
{
dagen.Add(datum.Dag);
}
return dagen;
}
View:
#using(#Html.BeginForm( "OpldagenLt", "Leertraject", FormMethod.Post))
{
<div>
<table>
<tr>
<th colspan="2">reeds begonnen dagen</th>
</tr>
#foreach (var item in #Model.Datums)
{
<tr>
<td>#Html.DisplayFor(modelItem => item.Dag.Dag.Day)/#Html.DisplayFor(modelItem => item.Dag.Dag.Month)/#Html.DisplayFor(modelItem => item.Dag.Dag.Year)</td>
<td>#Html.EditorFor(modelItem => item.Checked)</td>
</tr>
}
</table>
</div>
<div id="toekomst">
<table>
<tr>
<th>Dagen in de toekomst</th>
</tr>
#foreach (var item in #Model.Toekomst)
{
<tr>
<td>#Html.DisplayFor(modelItem => item.Dag.Dag.Day)/#Html.DisplayFor(modelItem => item.Dag.Dag.Month)/#Html.DisplayFor(modelItem => item.Dag.Dag.Year)</td>
</tr>
}
</table>
</div>
<div>
<p><input type="submit" value="Volgende"/></p>
</div>
}
Model:
using System;
using System.Collections.Generic;
using ProjectII.Models.domain;
namespace ProjectII.Viewmodels
{
public class DataModel
{
public DataModel()
{
Datums = new List<DatumModel>();
}
public ICollection<DatumModel> Datums { get; set; }
public ICollection<ToekomstModel> Toekomst{ get; set; }
}
public class DatumModel
{
public DatumModel()
{
Dag = new Opleidingdag(new DateTime().Date);
Checked = true;
}
public DatumModel(Opleidingdag opldag)
{
Dag = opldag;
Checked = true;
}
public Opleidingdag Dag { get; set; }
public bool Checked { get; set; }
}
public class ToekomstModel
{
public ToekomstModel()
{
Dag = new Opleidingdag(new DateTime().Date);
}
public ToekomstModel(Opleidingdag opldag)
{
Dag = opldag;
}
public Opleidingdag Dag { get; set; }
}
}
Thanks in advance for the help
With the way you construct your view, the ModelBinder cannot differantiate between the different elements in the list, and doesn't recognize them as items in the list. Try constructing the view like this:
#{ int datumteller = 0; }
#foreach (var item in #Model.Datums)
{
<tr>
<td>#Html.DisplayFor(modelItem => #Model.Datums[datumteller].Dag.Dag.Day)/#Html.DisplayFor(modelItem => #Model.Datums[datumteller].Dag.Dag.Month)/#Html.DisplayFor(modelItem => #Model.Datums[datumteller].Dag.Dag.Year)</td>
<td>#Html.EditorFor(modelItem => #Model.Datums[datumteller].Checked)</td>
</tr>
datumteller++;
}
#{ int toekomstteller = 0; }
#foreach (var item in #Model.Toekomst)
{
<tr>
<td>#Html.DisplayFor(modelItem => #Model.Toekomst[toekomstteller].Dag.Dag.Day)/#Html.DisplayFor(modelItem => #Model.Toekomst[toekomstteller].Dag.Dag.Month)/#Html.DisplayFor(modelItem => #Model.Toekomst[toekomstteller].Dag.Dag.Year)</td>
</tr>
toekomstteller++
}
#stephen: thanks for the help.
with keeping your answer in my mind I finally succeeded returning those data.
I changed the foreach into a for
and changed ICollection to a List
Model:
using System;
using System.Collections.Generic;
using ProjectII.Models.domain;
namespace ProjectII.Viewmodels
{
public class DataModel
{
public List<DatumModel> Datums { get; set; }
public List<ToekomstModel> Toekomst{ get; set; }
}
public class DatumModel
{
public DatumModel()
{
Dag = new Opleidingdag(new DateTime().Date);
Checked = true;
}
public DatumModel(Opleidingdag opldag)
{
Dag = opldag;
Checked = true;
}
public Opleidingdag Dag { get; set; }
public bool Checked { get; set; }
}
public class ToekomstModel
{
public ToekomstModel()
{
Dag = new Opleidingdag(new DateTime().Date);
}
public ToekomstModel(Opleidingdag opldag)
{
Dag = opldag;
}
public Opleidingdag Dag { get; set; }
}
}
view:
#model ProjectII.Viewmodels.DataModel
#using(#Html.BeginForm())
{
<div>
<table>
<tr>
<th colspan="2">reeds begonnen dagen</th>
</tr>
#for (int i = 0; i < Model.Datums.Count; i++)
{
<tr>
<td>#Html.DisplayFor(modelItem => Model.Datums[i].Dag.Dag.Day)/#Html.DisplayFor(modelItem => Model.Datums[i].Dag.Dag.Month)/#Html.DisplayFor(modelItem => Model.Datums[i].Dag.Dag.Year)</td>
<td>
#Html.EditorFor(modelItem => Model.Datums[i].Checked)
</td>
</tr>
}
</table>
#*#for (int i = 0; i < Model.Datums.Count; i++)
{
<div> #Html.DisplayFor(x => Model.Datums[i].Dag.Dag)
#Html.CheckBoxFor(x => Model.Datums[i].Checked) </div>
}*#
</div>
<div id="toekomst">
<table>
<tr>
<th>Dagen in de toekomst</th>
</tr>
#foreach (var item in #Model.Toekomst)
{
<tr>
<td>#Html.DisplayFor(modelItem => item.Dag.Dag.Day)/#Html.DisplayFor(modelItem => item.Dag.Dag.Month)/#Html.DisplayFor(modelItem => item.Dag.Dag.Year)</td>
</tr>
}
</table>
</div>
<div>
<p><input type="submit" value="Volgende"/></p>
</div>
}
Now I recieve a model with the right values
thanks for the help people
I'm trying to so a simple form to send some data. My form have a list of checkboxes and next to each box, a name and a role of person. What I want to do : recover the list of person that box have been checked.
I've created a model that way to do that :
public class CoupleModel
{
public Boolean isSelected { get; set; }
public String name {get; set;}
public String login { get; set; }
public String role { get; set; }
public CoupleModel(String name, String login, String role)
{
this.name = name;
this.login = login;
this.role = role;
this.isSelected = false;
}
public CoupleModel()
{
this.isSelected = false;
}
}
My form looks like this :
#using (Html.BeginForm("CreateInventory", "Home"))
{
#Html.Action("PersonListInventory")
<button type="submit" class="btn btn-primary">Validate creation</button>
}
And the PartialView linked to it is this one :
#model List<MyApp.Models.CoupleModel>
<table class="table table-striped table-bordered"">
<tbody>
#for (int i = 0; i < Model.Count(); i++) {
<tr>
<td>
#Html.EditorFor(m => m[i].isSelected)
</td>
<td>
#Html.EditorFor(m => m[i].name)
</td>
<td>
#Html.EditorFor(m => m[i].role)
</td>
</tr>
}
</tbody>
</table>
And then, in my controller view, I just want to list the name of the people where the box have been checked :
[HttpPost]
public ActionResult CreateInventory(List<CoupleModel> model)
{
String res = "";
foreach (var item in model) {
if (item.isSelected)
{
res += "selected : " + item.login + "<br>";
}
else
{
res += item.login + "<br>";
}
}
ViewBag.Res = res;
return View();
}
But only the "isSelected" part is set, that's to say that login is always blank when displaying. Why isn't it set ? Do I need to do some particular binding ?
that's to say that login is always blank when displaying.
That's perfectly normal. You don't have a corresponding field in your form. You need to add it as a hidden field:
#Html.HiddenFor(m => m[i].login)
You need to add #Html.HiddenFor(..)s for the fields you want to pass along.
The result:
#for (int i = 0; i < Model.Count(); i++) {
#Html.HiddenFor(m => m[i].login)
<tr>
<td>
#Html.EditorFor(m => m[i].isSelected)
</td>
<td>
#Html.EditorFor(m => m[i].name)
</td>
<td>
#Html.EditorFor(m => m[i].role)
</td>
</tr>
}
On the side, please use the .NET naming convention.