how to display items in view dynamically in mvc4 - asp.net-mvc-4

I want to display items in view in mvc dynamically.
following is the code for displaying records in view
#using MvcWcf.ServiceReference1
#model IEnumerable<WcfService.MyAddress>
<table>
<tr>
<td>#Html.DisplayNameFor(model => model.Address1)</td>
<td>#Html.DisplayNameFor(model => model.City)</td>
</tr>
#foreach (var item in Model)
{
<tr>
<td>#Html.DisplayFor(modelItem => item.Address1)</td>
<td>#Html.DisplayFor(modelItem => item.City)</td>
</tr>
}
</table>
my requirement how to display items in th and records dynamically
for example <td>#Html.DisplayNameFor(model => model.Address1)</td><td>#Html.DisplayNameFor(model => model.City)</td>
here i wrote address1 and City because i know the fields.
if i don't know the fields how to display that.
also in displaying records

You can create a generic model with this property
public List<GenericItem> items { get; set; }
than you create your generic item with the property you need, like type (textbox, button, ...), text inside and anything you need
public class GenericItem
{
public enum Type { get; set; }
public string Text { get; set; }
[...]
}
than you must create a custom helper (like a custom editorfor) that accepts a generic model and with that model show on screen the appropriate control with what you have inside your model.
https://www.asp.net/mvc/overview/older-versions-1/views/creating-custom-html-helpers-cs

Related

How to pass all text of input selected row into action?

i have this view in my project.
I want to get the text of input in each row that is selected.
How to pass all text of input selected row into action
<table width="100%" class="table table-striped table-bordered table-hover" id="dataTables-example">
<thead>
<tr>
<th width="45%">Select</th>
<th width="45%">User Name</th>
<th width="5%">Description</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model.TypeList)
{
<tr>
<td>
<input type="checkbox" name=checklist" id="checklist"/>
</td>
<td>
#Html.DisplayFor(modelItem => item.UserName)
</td>
<td>
<input type="text" name="Extradecription"/>
</td>
</tr>
}
</tbody>
my Actions. How can I have the corresponding values of text and checkbox for the Selected rows
public IActionResult Index()
{
return View(repository.GetUser());
}
public IActionResult Save(int[] checklist,string[] Extradecription)
{
repository.Save(checklist,Extradecription);
return View(repository.GetUser());
}
If you try to get two different arrays as you have showed in you controller-action code, there will be a trouble with text for non selected items, the array for check boxes will bind as expected but for descriptions will be different, just to be clear, check the following example:
Assuming We have a list with tree options:
100 - Foo
200 - Bar
300 - Zaz
If We set the following selection for items:
Foo, a
Zaz, c
If We take a look on the request, this is the raw request:
checklist = 100,300
Extradecription = a,null,c
So, the trouble is avoid to bind null descriptions for non selected options, this is complicated, in that case I recommend to you a clear solution:
Create a model to create entity process
Create a model for option
Add a list of option model in create entity model
Initialize the model to create a new entity
Render inputs in view using asp-for tag
Retrieve the request to create a new entity
I'll assume the name of models and properties to show how to bind a typed array in your request, change the names according to your scenario.
Create entity model:
public class CreateEntity
{
public CreateEntity()
{
Items = new List<SelectedItem>();
}
// Step 3
[BindProperty]
public List<SelectedItem> Items { get; set; }
// Another properties
}
Model for option:
public class SelectedItem
{
public bool IsSelected { get; set; }
public int Code { get; set; }
public string Name { get; set; }
public string Desc { get; set; }
}
Rendering the options list:
#for (var i = 0; i < Model.Items.Count; i++)
{
<input asp-for="#Model.Items[i].IsSelected" />#Model.Items[i].Name
<input asp-for="#Model.Items[i].Desc" />
<br/>
}
The GET and POST actions in controller:
[HttpGet]
public IActionResult CreateOption()
{
// Set the items list
var model = new CreateEntity
{
Items = new List<SelectedItem>
{
new SelectedItem{ Code = 100, Name = "Foo" },
new SelectedItem{ Code = 200, Name = "Bar" },
new SelectedItem{ Code = 300, Name = "Zaz" }
}
};
return View(model);
}
[HttpPost]
public IActionResult CreateOption(CreateEntity form)
{
// Retrieve only selected items
var query = form.Items.Where(item => item.IsSelected == true).ToList();
return View();
}
If you want to know more about check boxes in Razor pages, please check this link: Checkboxes in a Razor Pages Form
Please let me know if this answer is useful.

How to pass a textbox value to beginform routevalues

I have a textbox in my mvc view.I want to pass the textbox data in beginform route values.how to do that?
View:
#using (Html.BeginForm("Index", "InwardDetail", FormMethod.Post))
{
<fieldset style="width:80%;margin-left:auto;margin-right:auto;margin-top:20px;min-width:60%">
<div>
<table class="tableView" style="width:100%">
<tr>
<td>
#Html.DevExpress().Label(lbl=>{
lbl.Name = "lblFromDate";
lbl.Text = "From Date";
}).GetHtml()
</td>
<td>
#Html.TextBox("txtFromDate", value: DateTime.Now.ToString("dd/MM/yyyy"), htmlAttributes: new {id="fromDate", Class="textbox",style="width:70px"})
</td>
<td>
#Html.DevExpress().Button(but=>{
but.Name = "butView";
but.Text = "View";
but.UseSubmitBehavior = true;
}).GetHtml()
</td>
</tr>
<tr>
<td colspan="9">
#Html.Partial("InwardDetailPartial")
</td>
</tr>
</table>
</div>
</fieldset>
}
Controller:
public ActionResult Index(string fDate)
{
_unitOfWork = new UnitOfWork();
blInwarddetail = new InwardRegisterBL(_unitOfWork);
var result = blInwarddetail.GetInwardList(fDate);
return View("Index", result);
}
If I click Button the values should be passed to controller.
Your use of #Html.TextBox("txtFromDate", ..) means you generate an input with name="textFromDate". When you submit a form, the name/value pairs of the forms controls are sent - in your case it would be txtFromDate: 27/06/2015.
But the method your posting to does not have a parameter named txtFromDate (only one named fDate). You need to change the method to
[HttpPost]
public ActionResult Index(string txtFromDate)
{
....
}
However there are numerous issues with your code that you should address
First you should create a view model to represent what your wanting to display/edit in a view
public class FilterViewModel
{
[Display(Name = "...")] // some user friendly display name
[Required(ErrorMesage = "Please enter a valid date")]
public DateTime Date { get; set; }
}
Note from the code you have shown it appears your entering a date, not a string so the property should be DateTime (not string). This also ensures that you get client and server validation for the property. I also give your properties a more descriptive name that fDate (I can't begin to guess what that might mean - maybe FinishDate?)
In the GET method
public ActionResult Index()
{
FilterViewModel model = new FilterViewModel();
model.Date = DateTime.Today;
return View(model);
}
And in the view
#model yourAssembly.FilterViewModel
#using (Html.BeginForm())
{
....
#Html.LabelFor(m => m.Date)
#Html.TextBoxFor(m => m.Date, "{0:dd/MM/yyyy}", new { #class = "textbox" })
#Html.ValidationMessageFor(m => m.Date)
....
}
Note that you are now strongly binding to your model property. The second parameter specifies the format string. There seems no need to override the id property (which will be id="Date"), and to add a class name use #class = "..". Note also since you are adding a class name, you should remove style="width:70px" and instead use css. You should also remove the table elements. Html table elements are used for tabular data, not for layout.
And finally the post method will be
[HttpPost]
public ActionResult Index(FilterViewModel model)
{
if (!ModelState.IsValid)
{
return View(model);
}
// model.Date will contain the value enter by the user
}
Finally I would question if this really should be a POST. Form the code, you don't appear to be changing any data and perhaps this should be FormMethod.GET? Or better, use ajax to update the current page based on the filter.

How to add a list<T> to view with a single model

Getting an error while trying to add a grid to my detail page. The error is:
The model item passed into the dictionary is of type 'GridMvc.Html.HtmlGrid1[MyApp.Models.RecipientActivityMetadata]', but this dictionary requires a model item of type 'System.Collections.Generic.List1[MyApp.Models.RecipientActivityMetadata]'.
MVC4 View is a combination of a detail page and a list. I am using a viewmodel that looks like this:
public class FormViewModel()
{
public RecipientMetadata Recipient { get; set; }
public StudentActivityMetadata StudentActivity { get; set; }
public List<RecipientActivityMetadata> RecipientActivites { get; set; }
}
The view top is:
#model MyApp.Models.ViewModels.FormViewModel
and it renders a partial view which contains the list:
#Html.Partial("_grid", Model.RecipientActivites)
and the partial looks like this:
#using GridMvc.Html
#model List<MyApp.Models.RecipientActivityMetadata>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<div>
#Html.Grid(Model).Columns(columns =>
{
columns.Add(c => c.ActCount).Titled("Activity Num");
columns.Add(c => c.ActivityType).Titled("Activity Type");
columns.Add(c => c.FundCode).Titled("FundCode");
columns.Add(c => c.Hours).Titled("Hours");
}).WithPaging(10)
</div>
From Comment to Answer
According to the documentation provided by Grid.Mvc, #Html.Grid uses a partial view _Grid.cshtml. Because your partial view also has same name, the solution is to use a different name for your partial view.

ASP.NET MVC 4 Display data From 2 Model using EF

I'm start learning ASP.NET MVC 4 and stuck displaying Data From 2 model in 1 File
Here's my Model
public class mst_item
{
[Key]
[DisplayName("Item Code")]
[Required]
public string item_code{get;set;}
[DisplayName("Item Name")]
[Required]
public string item_name{get;set;}
[DisplayName("Unit")]
[Required]
public mst_item_unit unit_id{ get; set; }
}
public class mst_item_unit
{
[Key]
public int unit_id { get; set; }
[DisplayName("Unit")]
public string unit_name { get; set; }
}
Then My Controller :
public ActionResult Item()
{
var list_item = db.mst_item.Include("mst_item_unit").ToList();
return View(list_item);
}
Then How to display the unit_name based on the mst_item.unit_id in View using INNER JOIN or Include? something like :
#foreach (var item in Model)
{
#Html.DisplayFor(modelItem => item.item_name)
#Html.DisplayFor(modelItem => item.unit_name)
}
I get stuck here, But I success while displaying the mst_item data without joining mst_item_unit (just display the ID based on mst_item.unit_id) before.
You just have a couple of issues:
The parameter to Include should be a navigation property on your entity, not the table name. In other words, change it to:
var list_item = db.mst_item.Include("unit_id").ToList();
You have to access the properties of this second entity through the navigation property. In other words, this is the view code you would need:
#foreach (var item in Model)
{
#Html.DisplayFor(modelItem => item.item_name)
#Html.DisplayFor(modelItem => item.unit_id.unit_name)
}
That said, you've also got some stylistic problems here, which since you're new, I'll point out.
Class and property names should be camel-cased, i.e. MstItem, rather than mst_item.
Navigation properties should be named after the objects they connect to, i.e. unit_id should be something like MstItemUnit, or just Unit, if you prefer. That removes the need to specify a display name for it, as well.
The use of the _id suffix on this navigation property is particularly troubling, because it implies that this property is an int or Guid - you know, something that could be used an id - whereas actually you're referencing a full-fledged object.
While not as important, it makes little sense to repeat the class name or a portion thereof in the property names of that class. For example, unit_name should just be Name. Obviously, it's the name of the unit, because that's the class.
With those in place, your code becomes much more readable and "human". For example:
#Html.DisplayFor(m => item.Name)
#Html.DisplayFor(m => item.Unit.Name)
You should be creating a ViewModel that will relate both your models, populate that ViewModel in your controller and use that in your View. The below link is very much your case.
Multiple Models in a Single View (C# MVC3)

How to Use Two Same Model in a View? [MVC4]

I'm trying to create a status update page where I want a user to insert status message in Index page and also, I want to show all inserted all status messages in the same Index page.
This is my Model code:
public class Statuses
{
[Key]
public int StatusID { get; set; }
[DataType(DataType.MultilineText)]
[Required]
public string message { get; set; }
}
public class StatusContext : DbContext
{
public DbSet<Statuses> Status { get; set; }
}
And, I used #Html.EditorFor(model => model.message) in the Index.cshtml page.
To show the editor, I used the following model in View.
#model LearnStart.Models.Statuses
However, to show all the status messages below the Multiline TextArea, I think I'm supposed to use the below one.
#model IEnumerable<LearnStart.Models.Statuses>
How to use both model in same view so that I can display both the text area (to insert the status message) and to list all available status messages below it?
First, you should not be passing your entities directly to your view. The recommended best practice is to use View Models, which are models tailored specifically to your view.
Second, when using a view model you can now do this, since it's not tied to your data model entities:
public class MyActionViewModel {
public List<StatusesViewModel> StatusList {get;set;}
public StatusesViewModel CreatedStatus {get;set}
}
Then in your view:
#model MyActionViewModel
#Html.EditorFor(x => x.CreatedStatus)
.............................................
#Html.DisplayFor(x => x.StatusList)
Then you can create two templates, an EditorTemplate and a DisplayTempate:
In ~/Views/Shared/EditorTemplates/StatusesViewModel.cshtml
#model StatusesViewModel
#using(Html.BeginForm()) {
#Html.EditorFor(x => x.Message)
<input type="submit" value="Create Status" />
}
In ~/Views/Shared/DisplayTemplates/StatusesViewModel.cshtml
#model StatusesViewModel
<div>
<span>#Model.Message</span>
</div>
The thing that's nice about using the templates is that they will automatically iterate over your collection.. no foreach or for statement is used. A single EditorFor works on the entire collection, then renders the template based on the type, which in this case translates to StatusViewModel.cshtml
Easy way is to put a list inside Viewbag and show list in View as shown :-
Controller :
Public Actionresult Myaction()
{
.........
Viewbag.data = //bind list of messages here
return View();
}
View :
#model LearnStart.Models.Statuses
.........
.........
.........
#if(Viewbag.data != null){
<table>
#foreach(var item in Viewbag.data)
{
<tr><td>#item.message</td></tr>
}
</table>
}