I have the this set up and am trying to get lkup_1_txt to show in the page as either text or the selected item in the dropdown.
I have tried the following
#lkup1
and
#Html.DisplayFor(modelItem => item.lkup1)
and
#foreach (var item in Model)
{#Html.DisplayFor(modelItem => item.lkup1)}
This is my structure -
Model for Look Up Reference drop down selection
public class ListItem
{
public string Value { get; set; }
public string Text { get; set; }
}
public class ModelForDropDown
{
public string SelectedItemText { get; set; }
public List<ListItem> ItemListText { get; set; }
}
public class LkupResultRecord
{
public ModelForDropDown lkup_1_txt { get; set; }
public ModelForDropDown lkup_2_txt { get; set; }
}
Controller for the create new lkup1txt dropdown -
public ActionResult LkupRef_Lkup1()
{
return View(lkuprefdao.getValuesForLkupTxtDropDown());
}
[HttpPost]
public ActionResult LkupRef_Lkup1(string lkup_1_txt)
{ return RedirectToAction("LkupRef_Lkup2", "LkupRef", new
{
lkup_1_txt = lkup_1_txt
});
}
Controller for the create new lkup2txt dropdown -
public ActionResult LkupRef_Lkup2()
{
if (lkuprefdao.IsDataRefreshDowntime() == true) { return RedirectToAction("BadgerWeb_RestrictedAccess", "LkupRef"); }
return View(lkuprefdao.getValuesForLkupTxtDropDown());
}
and the view where I want the lkup_1_txt to display -
#using (Html.BeginForm())
{
<table>
<tr>
<td>lkup_1_txt</td>
<td> #Html.DisplayFor(lkup_1_txt) </td>
</tr>
<tr>
<td> lkup_2_txt </td>
<td>#Html.DropDownList("lkup_2_txt", new SelectList(Model.lkup_2_txt.ItemListText, "Value", "Text"), null, new { style = "width: 650px;" })</td>
</tr>
</table>
}
I
It's all still a bit unclear and doesn't make a great deal of sense, but I think you probably want something like this:
1) define lkup_1_txt as a string in your model, to match with the querystring value you're trying to feed to it. Defining it as a complex type like ModelForDropDown (as you did) doesn't appear to make any sense.
public class LkupResultRecord
{
public string lkup_1_txt { get; set; }
public ModelForDropDown lkup_2_txt { get; set; }
}
2) Add a parameter to allow the LkupRef_Lkup2() action method to receive the input value from the redirect (or from a direct request). Right now it is just ignoring the input. And also modify the action method code so you can add the incoming lookup text to the model before passing it to the view.
public ActionResult LkupRef_Lkup2(string lkup_1_txt)
{
if (lkuprefdao.IsDataRefreshDowntime() == true) { return RedirectToAction("BadgerWeb_RestrictedAccess", "LkupRef"); }
LkupResultRecord model = lkuprefdao.getValuesForLkupTxtDropDown();
model.lkup_1_txt = lkup_1_txt; //add the lookup text to the model
return View(model);
}
3) Modify the view so it can read the lookup text from the model property:
<td>lkup_1_txt</td>
<td> #Html.DisplayFor(m => m.lkup_1_txt) </td>
Related
My Model Class
public class DisplaceModel
{
public string Name { get; set; }
public string Address { get; set; }
public string Type { get; set; }
public string Rating { get; set; }
public string PhotoReference { get; set; }
public int Width { get; set; }
public int Height { get; set; }
}
public class DisplaceModelInformation
{
public List<DisplaceModel> Dispaylist { get; set; }
public DisplaceModelInformation()
{
Dispaylist = new List<DisplaceModel>();
}
}
And My Controller
var Display = new DisplaceModelInformation();
XElement generalElement = xdoc1.Element("PlaceSearchResponse");
Display.Dispaylist = (from c in xdoc1.Descendants("result")
select new DisplaceModel()
{
Name = Convert.ToString(c.Element("name").Value),
Address = Convert.ToString(c.Element("vicinity").Value),
Type = keyword,
Rating = (c.Element("rating") != null ? Convert.ToString(c.Element("rating").Value) :null),
PhotoReference = (c.Element("photo") != null ? Convert.ToString(c.Element("photo").Element("photo_reference").Value) : null),
Width = (c.Element("photo") != null ? Convert.ToInt16(c.Element("photo").Element("width").Value) : 0),
Height = (c.Element("photo") != null ? Convert.ToInt16(c.Element("photo").Element("height").Value) : 0)
}).ToList<DisplaceModel>();
return View(Display);
Now I try to display my list of object to view, I tried but I really dont know how to display in mvc view(cshtml) file
My MVC View
#model IEnumerable<FindLocation.Models.DisplaceModelInformation>
#using (Html.BeginForm())
{
<table>
<tbody>
<tr>
<th>NAME</th>
<th>ADDRESS</th>
<th>RATING</th>
</tr>
#foreach (var element in Model)
{
if (element.Dispaylist.Count > 0 )
{
<tr>
<#*td>#element.Dispaylist from c </td>
<td>#Display.Address</td>
<td>#Display.Rating</td>*#
</tr>
}
}
</tbody>
</table>
I am new to UI and I try to extract the list of object but i dont know how to list the object. so please help me....and thanks for your help
Part of the trouble might be coming from the type difference between what you're passing to the view from the controller (DisplaceModelInformation) and the #model definition in the view itself (IEnumerable<DisplaceModelInformation>). Changing one to match the other should help.
I think you have the right idea with #foreach. If your model is an IEnumerable, you would need to iterate over that collection first, then iterate over the DisplayList collection in another inner loop.
The answers to the following question seem to have some good examples of what you're trying to accomplish:
Foreach in a Foreach in MVC View
There are two issues in your code:
In your Controller, you need to return View(new List<DisplaceModelInformation> { Display });, because you specified an IEnumerable model in your View: #model IEnumerable<FindLocation.Models.DisplaceModelInformation>
Use foreach to display each table row:
#foreach (var element in Model)
{
if (element.Dispaylist.Count > 0)
{
foreach (var Display in element.Dispaylist)
{
<tr>
<td>#Display.Name</td>
<td>#Display.Address</td>
<td>#Display.Rating</td>
</tr>
}
}
}
This question already has answers here:
Asp.Net MVC: Why is my view passing NULL models back to my controller?
(2 answers)
Closed 5 years ago.
I need to display a specific form in a view with a model. The model is like that:
This is the final object filled what I need :
public class ObjetTotal
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string Numero { get; set; }
public string Value { get; set; }
}
I choose to cut the form into two differents parts :
First a "static" part where the user can put common values for the differents ObjetsTotal.
Second a "variable" part where the user put differents values for the differents ObjetsTotal.
The final aim is that the user doest'n have to type, the same thing for all the objects ObjetTotal.
So, I create other objects (I don't know if it's a good practice) which represents the differents part of the form.
The static part with MainObjet and the variable part with Numbers. I put these two object into an other object "Mix" which contains one "MainObjet" and a list of "Numbers".
public class MainObjet
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
public class Numbers
{
public string Numero { get; set; }
public string Value { get; set; }
}
public class Mix
{
public MainObjet obj { get; set; }
public IEnumerable<Numbers> num { get; set; }
public Mix()
{
obj = new MainObjet();
num = new List<Numbers>();
}
}
Then I want to render the model Mix in a view to have the two parts of the form.
I've try this :
#model App.Models.Mix
#using (Html.BeginForm()) {
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<fieldset>
<legend>Mix</legend>
<h3>First Properties</h3>
<div>
#Html.TextBoxFor(model => model.obj.Id);
#Html.TextBoxFor(model => model.obj.Name);
#Html.TextBoxFor(model => model.obj.Description);
</div>
<div>
<table>
#for (int i = 0; i < 5; i++)
{
<tr>
<td>
#Html.TextBoxFor(model => model.num[i].Numero)
</td>
<td>
#Html.TextBoxFor(model => model.num[i].Value)
</td>
</tr>
}
</table>
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
But after the submit I get an object Mix null in this ActionResult :
[HttpPost]
public ActionResult Test(Mix obj)
{
return View();
}
Can you explain me how to do that ? May I'm on a wrong way.
Don't consider the design of the form, and I don't know the right type to put to Numbers, Maybe a simple list be enough for that.
The thing I can see is that you are missing the initialization of your model properties in the parameter-less constructor. You should try to update your model code to be:
public class Mix
{
public MainObjet obj { get; set; }
public IEnumerable<Numbers> num { get; set; }
public Mix()
{
obj = new MainObjet();
num = new List<Numbers>();
}
}
As the model binder will instantiate your model, and it will find obj and num to null and will not be able to post the values back.
Hope this helps you.
I am have a table similar to grid that shows all the fields from table.
This is my controller:
public ActionResult Index()
{
DAL.DataManager dal = new DAL.DataManager();
List<LALegalLicensedata> data = new List<LALegalLicensedata>();
data = dal.get_LA_Get_AllDate();
return View(data);
}
and this is my view:
#model IEnumerable<CSAProject.Models.LALegalLicensedata>
<table width="100%" class="display" id="example" cellspacing="0">
<thead>
<tr>
<th>Entity</th>
<th>License Type</th>
<th>State</th>
<th>Location</th>
<th>Data User</th>
</tr>
</thead>
<tbody>
#foreach(var item in Model)
{
<tr>
<td>#item.Entity</td>
<td>#item.License_Type</td>
<td>#item.State</td>
<td>#item.Location</td>
<td>#item.dataUser</td>
</tr>
}
</tbody>
</table>
also in this page I need to show a optionList with checkbox that contains name of the properties from Model, this is my model:
public class LALegalLicensedata
{
public int dataID { get; set; }
public string dataUser { get; set; }
public DateTime Create_Date { get; set; }
public DateTime Modified_Date { get; set; }
public string Modified_By { get; set; }
public string Status { get; set; }
}
and this is how I get the properties name from Model:
LALegalLicensedata model = new LALegalLicensedata();
List<string> PropertyList = GetPropertiesNameOfClass(model);
public List<string> GetPropertiesNameOfClass(object pObject)
{
List<string> propertyList = new List<string>();
if (pObject != null)
{
foreach (var prop in pObject.GetType().GetProperties())
{
propertyList.Add(prop.Name);
}
}
return propertyList;
}
I need to show a PropertyList in the option list how I can do that?
This is the javascript and text to show and hide the column. Instead of static text I like to have names from properties and have them in the option list with checkbox.
$(document).ready(function () {
var table = $('#example').DataTable({
"paging": true
});
$('a.toggle-vis').on('click', function (e) {
//e.preventdefault();
event.preventDefault ? event.preventDefault() : event.returnValue = false;
//Get the column API object
var column = table.column($(this).attr('data-column'));
// Toggle the visibility
column.visible(!column.visible());
});
});
</script>
<div>
Toggle column: <a class="toggle-vis" data-column="0">Entity</a> -
<a class="toggle-vis" data-column="1">License Type</a> -
<a class="toggle-vis" data-column="2">State</a> -
<a class="toggle-vis" data-column="3">Location</a> -
<a class="toggle-vis" data-column="4">Data User</a> -
<a class="toggle-vis" data-column="5">Create Date</a>
</div>
The model you have shown does not match the view you have shown, so assuming your model is in fact (to match the view you have shown)
public class LALegalLicensedata
{
public string Entity { get; set; }
public string License_Type { get; set; }
public string State { get; set; }
public string Location { get; set; }
public string dataUser { get; set; }
}
Then, in the Index() method, add the property names to a ViewBag property
....
ViewBag.PropertyNames = GetPropertiesNameOfClass(new LALegalLicensedata());
return View(data);
I would however recommend that you use a view model with properties List<LALegalLicensedata> Data and List<string> PropertyNames
Then in the view your can loop through the collection to generate you checkboxes
<div>
#foreach(var name in ViewBag.PropertyNames)
{
<label>
<input type="checkbox" class="toggle-column" checked />
<span>#name</span>
</label>
}
</div>
Then modify your script to handle the click() event of each checkbox
var checkBoxes = $('.toggle-column');
$('.toggle-column').click(function() {
var index = checkBoxes.index($(this));
$('tr th').eq(index).toggle();
$('tr td').eq(index).toggle();
});
Refer this fiddle for how the script works.
Edit
Your current GetPropertiesNameOfClass() method will return the property names which in your case will display "License_Type" for the 2nd property, when I suspect you probably want it to be "License Type" (space instead of underscore). To solve this, add a [Display(Name = "License Type")] to the property, and then you can use the following method
private List<string> GetDisplayNames(object model)
{
Type type = typeof(model);
List<string> displayNames = new List<string>();
foreach (var property in type.GetProperties())
{
var attributes = property.GetCustomAttributes(typeof(DisplayAttribute), true);
if (attributes.Length == 0)
{
displayNames.Add(property.Name);
}
else
{
displayNames.Add((attributes[0] as DisplayAttribute).Name);
}
}
return displayNames;
}
This also means you can use <th>#Html.DisplayNameFor(m => m.License_Type)</th> to generate you table headings rather than hard coding.
In my view model, there is a list of element which contains a table of text inputs.
View model > List of element > Table > lots of text inputs
All of this is generated in the view via EditorTemplates.
Everything is bound perfectly to the view when it load (MVC is creating the right IDs and Names of each input. Now I want to add and delete rows and have the binding updated. This means, that all the right numbers are updated in the IDs and Name.
I have an idea of how to do it with pure JavaScript, but that would be very dirty and a pain to update when things change. I would like to do it with an HTML helpers or a model binder but haven't found a way yet!
Anyone have an idea of how to do that?
EDIT : apparently I have more chance to get answered if I post lots of code detail... but in this complex case, that's going to be long, so hang on!
Here is the view model. (Keep in mind that this code is a dumbed down version)
public class MVCViewModel
{
public List<ActivityElement> ActivityElementList { get; set; }
}
public abstract class ActivityElement
{
}
public class Step : ActivityElement
{
public Step()
{
this.Id = Guid.NewGuid();
this.Label = "Basic Step";
}
public Step(string label, AbstractInput input)
: this()
{
this.Label = label;
this.Input = input;
}
public Guid Id { get; set; }
public string Label { get; set; }
public AbstractInput Input { get; set; }
}
public abstract class AbstractInput
{
public object Value { get; set; }
}
public class GridInput : AbstractInput
{
public List<GridCell> Headerlist { get; set; }
public List<GridRow> RowList { get; set; }
}
public class GridRow
{
public List<GridCell> CellList { get; set; }
}
public class GridCell
{
public string ColumnName { get; set; }
public AbstractInput Input { get; set; }
}
public class TextInput: AbstractInput
{
public TextInput(string value)
{
this.Value = value;
}
}
Alright! If somehow you are still with me, that's good! I have put them in the order that they will be used in this particular case.
To dumb this down, the view model contains a list of Step. The first step contains a GridInput as his AbstractInput property. That grid contains rows and each rows contains cells. For this case, let say each cell contains a TextInput as his AbstractInput.
Now, on the view, when this is displayed with EditorTemplates and HtmlHelpers, all the IDs and Names of the inputs are good (therefor the binding is good), as shown here in this HTML output :
<td>
<input id="ActivityElementList_0__Input_RowList_0__CellList_0__Input_ModelType" name="ActivityElementList[0].Input.RowList[0].CellList[0].Input.ModelType" type="hidden" value="knockout_binding_prototype.Models.TextInput">
<input id="ActivityElementList_0__Input_RowList_0__CellList_0__Input_Value" name="ActivityElementList[0].Input.RowList[0].CellList[0].Input.Value" type="text" value="cell 1 row 1">
</td>
<td>
<input id="ActivityElementList_0__Input_RowList_0__CellList_1__Input_ModelType" name="ActivityElementList[0].Input.RowList[0].CellList[1].Input.ModelType" type="hidden" value="knockout_binding_prototype.Models.TextInput">
<input id="ActivityElementList_0__Input_RowList_0__CellList_1__Input_Value" name="ActivityElementList[0].Input.RowList[0].CellList[1].Input.Value" type="text" value="cell 2 row 1">
</td>
What I am trying to do here, is to be able to add and delete row to this table. This is fairly easy... The hard part is making sure all the binding (IDs and Names) are still good. In the case of this particular HTML output, if I delete the first row, I need the IDs and Names of the second row, to become equivalent to the first row IDs and Name.
I have been trying to find the most generic way to do it, and to try and make it JavaScript less as possible. All ideas will be pondered, so don't afraid to say something!
EDIT 2 : OK, as far as deleting rows go, I decided to just hide the delete row and flag it as deleted, so all the biding remains good. Adding row is simple in JavaScript, but I am searching for a way to do it without JavaScript (or only a little bit).
Here is the update in the view model for the delete flag.
public class GridRow
{
public GridRow()
{
IsDeleted = false;
}
public List<GridCell> CellList { get; set; }
public bool IsDeleted { get; set; }
}
Try this way without buggy JS html modifications. You can do delete this way as well. Also you can decide if you want to save the model on every add/delete call or save it after all changes.
Models:
public class SampleModel
{
public List<ItemModel> Items { get; set; }
public SampleModel()
{
Items = new List<ItemModel>();
}
}
public class ItemModel
{
public int Id { get; set; }
public string Name { get; set; }
}
Controller:
[HttpPost]
public ActionResult Add(SampleModel model)
{
model.Items.Add(new ItemModel { Name = "New Item" });
return PartialView("Items");
}
public ActionResult Index()
{
var model = new SampleModel(); // Or get model
return View(model);
}
[HttpPost]
public ActionResult Index(SampleModel model)
{
// Save model to DB
return RedirectToAction("Index");
}
Index.cshtml
#model SampleModel
#using (Html.BeginForm())
{
<div id="container">
#Html.Partial("Items", Model)
</div>
<a id="add" href="javascript:void(0);">Add</a>
<button type="submit">Save</button>
}
<script src="jquery.js"></script>
<script type="text/javascript">
$(function () {
$('#add').on('click', function () {
$.post('#Url.Action("Add")', $('form').serializeModel(), function(html) {
$('#container').html(html);
});
});
});
$.fn.serializeModel = function () {
var model = {};
$(this).serializeArray().map(function (item) {
model[item.name] = item.value;
});
return model;
};
</script>
Items.cshtml:
#model SampleModel
<table>
#for (var i = 0; i < Model.Items.Count; i++)
{
<tr>
<td>
#Html.HiddenFor(m => Model.Items[i].Id)
#Html.TextBoxFor(m => Model.Items[i].Name)
</td>
</tr>
}
</table>
I am sure this is relatively simple, I just keep running into brick walls. I have two entity classes set up like so:
public class Post
{
public int Id { get; set; }
public string Title { get; set; }
public DateTime CreatedDate { get; set; }
public string Content { get; set; }
public string Tags { get; set; }
public ICollection<Comment> Comments { get; set; }
}
public class Comment
{
public int Id { get; set; }
public string DisplayName { get; set; }
public string Email { get; set; }
public DateTime DateCreated { get; set; }
public string Content { get; set; }
public int PostId { get; set; }
public Post Post { get; set; }
}
And I set up my ViewModel like this:
public class PostCommentViewModel
{
public Post Post { get; set; }
public IQueryable<Comment> Comment { get; set; }
public PostCommentViewModel(int postId)
{
var db = new BlogContext();
Post = db.Posts.First(x => x.Id == postId);
Comment = db.Comments;
}
}
And I have my Controller doing this:
public ActionResult Details(int id = 0)
{
var viewModel = new PostCommentViewModel(id);
return View(viewModel);
}
And then the view looks like this:
#model CodeFirstBlog.ViewModels.PostCommentViewModel
<fieldset>
<legend>PostCommentViewModel</legend>
#Html.DisplayFor(x => x.Post.Title)
<br />
#Html.DisplayFor(x => x.Post.Content)
<br />
#Html.DisplayFor(x => x.Post.CreatedDate)
<hr />
#Html.DisplayFor(x => x.Comment)
</fieldset>
The result IS displaying data, but not quite what I want for the comments.
You see that the comments (There are two of them) and just showing the id property on each one "12"
How can I get it to go into and display the comment details specific to this particular post? I imagine a foreach loop is in order, but i cant figure out how to drill into the Model.Comment property correctly.
I tried this:
#foreach(var item in Model.Comment)
{
#Html.DisplayFor(item.DisplayName)
#Html.DisplayFor(item.Content)
#Html.DisplayFor(item.DateCreated)
}
But the error I get is "The type arguments for method 'System.Web.Mvc.Html.DisplayExtensions.DisplayFor(System.Web.Mvc.HtmlHelper, System.Linq.Expressions.Expression>)' cannot be inferred from the usage. Try specifying the type arguments explicitly."
Not sure what I am supposed to do here..
Loop around the comments model:
#model CodeFirstBlog.ViewModels.PostCommentViewModel
<fieldset>
<legend>PostCommentViewModel</legend>
#Html.DisplayFor(x => x.Post.Title)
<br />
#Html.DisplayFor(x => x.Post.Content)
<br />
#Html.DisplayFor(x => x.Post.CreatedDate)
<hr />
#foreach(var comment in Model.Comment) {
#Html.DisplayFor(x => comment)
}
</fieldset>
public class PostCommentViewModel
{
public Post Post { get; set; }
public IQueryable<Comment> Comment { get; set; }
public PostCommentViewModel(int postId)
{
var db = new BlogContext();
Post = db.Posts.First(x => x.Id == postId);
Comment = Post.Comments;
}
}
And did you make Html helper method for Comment class?
Create a DisplayTemplate for your Comment class and it should work, there is no need to iterate over the collection the view engine does it for you.
As per my comment, this is all you need to do to create a display template for your Comment class:
Create a DisplayTemplates subfolder inside your view folder and inside this create a new partial view called Comment.cshtml. Your template could look like this:
#model CodeFirstBlog.ViewModels.Comment
<div class="comment">
#Html.DisplayFor(m => m.DisplayName)
....
</div>
And that's it! If you need more control over how your comment is displayed then you can simple tweak the template to suit.