Break line in view from list in MVC 5 - asp.net-mvc

I have a List containing string objects that should be displayed in the view. But i have problems getting the output correctly. In the list there are words like Computer, Screen, Mouse. Now it´s displayed like ComputerScreenMouse and want it displayed like
Computer
Screen
Mouse
I´ve checked the object during run-time and it´s adding the strings correctly like
[0] Computer
[1] Screen
[2] Mouse
This is the code that I´m using
#Html.DisplayFor(m => Model.MyParts, new { htmlAttributes = new { #class = "form-control " } })
I've tried a couple different stuff with foeach loops but nothing seems to work. If i use the #Html.Raw and put in a br tag it prints out the list like this:
ComputerScreenMouse
ComputerScreenMouse
ComputerScreenMouse
#foreach (var item in Model.MyParts)
{
#Html.Raw(Html.DisplayFor(m => Model.MyParts, new { htmlAttributes = new { #class = "form-control " } }) + "</br>")
}
The model looks like this. In the view I´m using #modelGlossary_mvc.Models.Parts
public class DoTestModel
{
public string Stuff{ get; set; }
public string OtherStuff { get; set; }
public List<Parts> Parts { get; set; }
}
public class Parts
{
public List<string> MyParts{ get; set; }
public List<string> SpareParts{ get; set; }
public int NumberOfParts { get; set; }
}

Display(For) / Editor(For) really aren't ideal for List<string> properties. They should be reserved for specialized display and editing templates, or properties that have the [Display] attribute.
Your model property MyParts is a simple list of strings.
public List<string> MyParts{ get; set; }
Keep it simple, output each string (e.g. in an un-ordered list):
<ul>
#foreach(var part in Model.MyParts)
{
<li>#part</li>
}
</ul>
Ok, but what if the MyParts property is a list of PartModel objects? This is where the MVC DisplayFor / EditorFor shines.
PartModel
public class PartModel
{
public string Name { get; set; }
public int Quantity { get; set; }
}
View Model
// your view model
public class Parts
{
// now a list of PartModels not strings
public List<PartModel> MyParts{ get; set; }
public List<string> SpareParts{ get; set; }
public int NumberOfParts { get; set; }
}
Razor View
#model Parts
#Html.DisplayFor(m => m.MyParts)
Display Template for PartModel
#model PartModel
<div>
<span>#Html.DisplayFor(m => m.Name)</span>
<span>#Html.DisplayFor(m => m.Quantity)</span>
</div>
This file can be located in couple places. It's up to you based on how much you need to share it throughout the project:
\Views\Shared\DisplayTemplates\PartModel.cshtml
\Views\\DisplayTemplates\PartModel.cshtml

Depending on how you are wrapping your output in HTML will depend on the outcome. Are you using this in a form? as i generally only use form-control for fields.
Since your output is not HTML you need to try this if you need the form-control.
#foreach (var item in Model.MyParts)
{
#Html.DisplayFor(modelItem => item, new { htmlAttributes = new { #class = "form-control " } })
<br />
}
Without form-control to just display the list:
#foreach (var item in Model.MyParts)
{
#Html.DisplayFor(modelItem => item )
<br />
}
And depending how you have your HTML wrapper you may or may not need the <br />

Related

Dropdown list population from ViewModel

First of all, I know this question has been asked many, many times. I've read countless articles and Stack Overflow answers. I've tried to figure this problem out for four days and I think I need help if someone doesn't mind.
I have two databases. The employee database has a field called "DisplayName" -- the second database has a relationship with the first and they work together great. I'm able to call the two databases perfectly in another application.
You can see the in the picture Index Page
that I have a list of people. I want a dropdown below it that lists all display names in the database so employees can add themselves to the list. You'll see a dropdown in the image but it's not populated.
Seems simple. But geez. Part of a problem I'm having is my home controller already has a function to populate the list in the picture so I can't do another on that page. I've tried a lot of suggestions on a lot of sites. I get IEnumerable errors or display reference errors....
Here's my controller (again - it has nothing in it that helps the dropdown):
namespace SeatingChart.Controllers
{
public class HomeController : Controller
{
private ApplicationDbContext db = new ApplicationDbContext();
// GET: Employee
public ActionResult Index()
{
var lists = db.BreakModels
.Include("Employee")
.Include("TimeEntered")
.Include("TimeCleared")
.Include("DisplayName")
.Select(a => new HomeIndexViewModels
{
Employee = a.Employee,
DisplayName = a.EmployeeModels.DisplayName,
TimeEntered = a.TimeEntered,
TimeCleared = a.TimeCleared.Value,
Id = a.EmployeeModels.Id,
});
return View(lists);
}
View:
#model IEnumerable<SeatingChart.Models.HomeIndexViewModels>
#{
Layout = null;
}
#Html.Partial("_Header")
<div class="container_lists">
<div class="container_break col-md-8">
<h5 style="text-align:center">Break List</h5>
<table class="table-bordered col-lg-12">
#if (Model != null)
{
foreach (var item in Model)
{
if (item.TimeCleared == null)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.DisplayName)
</td>
<td>
 BV
</td>
<td>
 #item.TimeEntered.ToString("HH:mm")
</td>
</tr>
}
}
}
</table>
#using (Html.BeginForm())
{
<div class="row site-spaced">
<div class="col-3">
#Html.DropDownList("DisplayName", new SelectList(new List<string>() { "---Dispatcher---" }), new { #class = "required " })
</div>
</div>
<div class="col-3">
<input type="submit" value="Submit" class="site-control" />
</div>
}
</div>
</div>
ViewModel:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Html;
namespace SeatingChart.Models
{
public class HomeIndexViewModels
{
//Break Model
public int BreakId { get; set; }
public int Employee { get; set; }
public DateTime TimeEntered { get; set; }
public DateTime? TimeCleared { get; set; }
//Employee Model
public int Id { get; set; }
public string DisplayName { get; set; }
public string DisplayNames { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public bool NotActive { get; set; }
public int Force { get; set; }
public string EmployeeList { get; set; }
}
}
I hope this is clear enough. I've tried so many different ways with so much code - the errors are different with everything I've tried.
Thanks in advance for your patience and help!
You can add to your viewmodel
public List<SelectListItem> Employees { get; set; }
Then you can populate this list with controller then in view just call it with:
#Html.DropDownListFor(m => m.Id, Model.Employees, new { #class = "form-control", required = "required" })
Update - how to populate list. Should work (but not tested code).
public List<SelectListItem> GetEmployeeForDropdown(List<HomeIndexViewModels> list)
{
List<SelectListItem> empList = new List<SelectListItem>();
try
{
if (list != null && list.Count > 0)
{
foreach (var item in list)
{
empList.Add(new SelectListItem { Text = item.DisplayName, Value = item.Id.ToString() });
}
}
else
{
empList.Add(new SelectListItem { Text = "No items", Value = string.Empty });
}
}
catch (Exception ex)
{
//handle exceptions here
}
return empList;
}
Edit: Remember to use your model in view!

How to set default value to select list in MVC during run time

I have view in which it loop through the model and display the details in editable mode. One of the model value is from a select list like below
#if (Model != null)
{
for (int i = 0; i < Model.provider_service_dtls.Count; i++)
{
<tr>
<td> #Html.DropDownListFor(m => m.provider_service_dtls[i].activity_code_type,
(SelectList)#ViewBag.activity_code_type, "--- Select Activity Code Type ---", new { #class = "m-wrap" })</td>
<td>#Html.TextBoxFor(m => m.provider_service_dtls[i].activity_name)</td>
</tr>
}
}
Here the ViewBag.activity_code_type contain the values Internal & Standard when submitting if user selected Internal its value 1 will pass to controller and if Standard it will be 2 and here the default value will be "--- Select Activity Code Type ---"
Now when i open the same request in edit mode if the model value for provider_service_dtls[i].activity_code_type is 1 the select list should be default select as Internal and Standard if it is 2.
I coded like this
#Html.DropDownListFor(m => m.provider_service_dtls[i].activity_code_type,
(SelectList)#ViewBag.activity_code_type, Model.provider_service_dtls[i].activity_code_type)
But it is not working as expected it is giving the result as below picture
Here it should default selected Internal. What is the change to do achieve the same?
Edited
Model
public partial class provider_service_dtls
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long service_id { get; set; }
public long preapproval_id { get; set; }
public string activity_code_type { get; set; }
public string activity_type { get; set; }
public string activity_type_name { get; set; }
public string activity_code { get; set; }
public string activity_name { get; set; }
public string internal_activity_code { get; set; }
public string internal_activity_name { get; set; }
[ForeignKey("preapproval_id"), InverseProperty("provider_service_dtls")]
public virtual provider_preapproval preapproval { get; set; }
}
Editor template
#model Provider.Models.provider_preapproval
#Html.DropDownListFor(m => m.activity_code_type, (SelectList)ViewData["options"])
View
Inside the for loop i coded like this
#Html.EditorFor(m => m.provider_service_dtls,
new { options = (SelectList)#ViewBag.activity_code_type })
I am getting an error
'System.Web.Mvc.HtmlHelper' does
not contain a definition for 'EditorFor' and the best extension method
overload
'System.Web.Mvc.Html.EditorExtensions.EditorFor(System.Web.Mvc.HtmlHelper,
System.Linq.Expressions.Expression>,
string, object)' has some invalid arguments
Unfortunately #Html.DropDownListFor() behaves a little differently than other helpers when rendering controls in a loop. This has been previously reported as an issue on CodePlex (not sure if its a bug or just a limitation)
Create a custom EditorTemplate for the type in the collection.
In /Views/Shared/EditorTemplates/provider_service_dtls.cshtml (note the name must match the name of the type)
#model yourAssembly.provider_service_dtls
#Html.HiddenFor(m => m.service_id)
#Html.DropDownListFor(m => m.activity_code_type, (SelectList)ViewData["options"], "--- Select Activity Code Type ---")
.... // html helpers for other properties of provider_service_dtls
and then in the main view, pass the SelectList to the EditorTemplate as additionalViewData
#model yourAssembly.provider_preapproval
#using (Html.BeginForm())
{
.... // html helpers for other properties of provider_preapproval
#Html.EditorFor(m => m.provider_service_dtls, new { options = (SelectList)#ViewBag.activity_code_type })
...
The EditorFor() methods accepts IEnumerable<T> and will generate the controls for each item in the collection
Edit
An alternative is to create a new SelectList in each iteration of the for loop, where you need to set the Selected property of SelectList. This means that your ViewBag property must be IEnumerable<T>, not a SelectList, for example in the controller
ViewBag.ActivityCodeTypeList = new[]
{
new { ID = 1, Name = "Internal" },
new { ID = 2, Name = "Standard" }
}
and in the view
for (int i = 0; i < Model.provider_service_dtls.Count; i++)
{
#Html.DropDownListFor(m => m => m.provider_service_dtls[i].activity_code_type,
new SelectList(ViewBag.ActivityCodeTypeList, "ID", "Name", Model.provider_service_dtls[i].activity_code_type),
"--- Select Activity Code Type ---")
}
Simply you can try this by using IEnumerable Model type list like
#Html.DropDownList("ReceiverID", (IEnumerable<SelectListItem>)(m => m.activity_code_type), "--- Select ---", new { #class ="form-control" })
Hope it will work

kendo multiselect, send selected values to controller

I'm new to ASP.NET mvc and kendo ui framework and have the following issue:
I have a partialview in a window with a multiselect which receives its values out of the database. the view looks like:
#model SoftwareAdminInterface.Models.Administration.Pattern
<div id="myContentPopupEditRole_div">
#using (Ajax.BeginForm("SetCombi", "Pattern", new { }, new AjaxOptions() { HttpMethod = "post", UpdateTargetId = "myContentPopupEditRole_div" }))
{
<center>
<br />
<table class="table_no_borders">
<tr>
<td style="width: 300px">
#(
Html.Kendo().MultiSelectFor(model => model.RegExId)
.MaxSelectedItems(2)
.Name("RegExID")
.DataTextField("RegExName")
.DataValueField("RegExID")
.Placeholder("Select Patterns...")
.AutoBind(false)
.DataSource(source => {
source.Read(read =>
{
read.Action("GetPatternsForCombi", "Pattern");
})
.ServerFiltering(true);
})
)
</td>
</tr>
</table>
<button class="k-button k-button-icontext k-grid-custom" id="get" type="submit">#Resources.General.BtnSave</button>
</center>
}
</div>
I'm using a model which looks like this:
public class Pattern
{
[ScaffoldColumn(false)]
public int RegExID { get; set; }
[Display(Name = "RegEx")]
[Required]
public string RegExName { get; set; }
[UIHint("GridForeignKey")]
public int CategoryID { get; set; }
public string CategoryName { get; set; }
public string ColumnName { get; set; }
public string RegExTable { get; set; }
[UIHint("GridForeignKey")]
public int? TableID { get; set; }
public string Version { get; set; }
public string Description { get; set;
}
in the SetCombi function which is called in the patterncontroller, I only want to receive the two ID's of the selected objects out of the multiselect, but I've no idea how they should be send to the controller.
thx in advance for your help
I think you have two options:
1) Change RegExID to be a string and then I believe they would come across as comma separated values.
2) (The better option) Add a ViewModel which has many of the same properties as your Pattern model above. The main difference for this is that you would have
public List<int> RegExIDs { get; set; }
Then in your controller you would take the new ViewModel as an argument to your post method and parse out the values in the list as necessary.

ASP .NET MVC4 Adding new items to view and model binding

I create a website for my wife. She's a teacher and she would like to have a possibility to create exercises for their students. The case is that she would like to create for instance the following exercise:
Exercise 1: Fill the sentence using a correct word:
My wife is 30 ............. old
I live in this city for 30 .........
I have the following model:
public class Exercise
{
[Key]
public Guid Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public ExerciseType Type { get; set; }
public DifficulityLevel DifficulityLevel { get; set; }
public List<ExerciseItem> Items { get; set; }
public DateTime TimeOfCreation { get; set; }
public DateTime TimeOfModification { get; set; }
}
public class ExerciseItem
{
[Key]
public Guid Id { get; set; }
public string Content { get; set; }
public List<ExerciseItemOption> Options { get; set; }
public ExerciseItemOption CorrectSelection { get; set; }
}
I creates a View for my Exercise. I can fill in the basic properties like Name, Description, Difficulity Level and Type. Then I would like to create a button "Add exercise item". When clicked, a partial view (or something else) should be added dynamically where new ExerciseItem can be provided.
I've tried to following:
I've added a button
#Ajax.ActionLink("Add exercise item",
"AddExerciseItem",
"Exercise", new AjaxOptions() { HttpMethod="GET", InsertionMode = InsertionMode.InsertBefore, UpdateTargetId="ExerciseItems"})
and the appropriate div:
<div id="ExerciseItems"></div>
My action method looks as follows:
public ActionResult AddExerciseItem()
{
return PartialView("ExerciseItem", new ExerciseItem());
}
and the partial view:
#model ElangWeb.Models.ExerciseItem
<fieldset>
<legend>ExerciseItem</legend>
#Html.HiddenFor(model => model.Id)
<div class="editor-label">
#Html.DisplayNameFor(model => model.Content)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Content, new { style = "width:200px" })
</div>
</fieldset>
It works fine. However when I click button for creating a whole exercise, I do not have ExerciseItem collection in my model:
public ActionResult Create(Exercise exercise)
{
using (PersistanceManager pm = new PersistanceManager())
{
exercise.Id = Guid.NewGuid();
exercise.TimeOfCreation = DateTime.Now;
exercise.TimeOfModification = DateTime.Now;
pm.ExcerciseRepository.Add(exercise);
}
return RedirectToAction("Index");
}
How should I change the code in order to bind my list of added ExerciseItem objects to my model Exercise?
Check out this article about model binding. You basically need to create special names for the exercise items so that they get bound correctly.
e.g. partial:
#model ElangWeb.Models.ExerciseItem
<fieldset>
<legend>ExerciseItem</legend>
<label>content</label>
<input type="hidden" name="ExcersiseItem.Index" value="SomeUniqueValueForThisItem" />
<input type="text" name="ExcersiseItem[SomeUniqueValueForThisItem].Name" value="#Model.Content" />
</fieldset>
You can also look at my answer to this question MVC3 Non-Sequential Indices and DefaultModelBinder. Thanks Yarx for finding it, I was actually trying to find it :)

How to have one RadioButtons group display in EditorTemplates in ASP.Net MVC(3)

I have a list of items from which I want the user to be able to input some value select one
But the radio-buttons generated by the EditorTemplate are named like "Item[x].SelectedItemId" so they are totally independent from each other and I can't get the value...
Let's go show some code.
The model:
public class FormModel
{
public List<ItemModel> Items { get; set; }
public int SelectedItemId { get; set; }
}
public class ItemModel
{
public int ItemId { get; set; }
public string ItemName { get; set; }
public string SomeString { get; set; }
}
The view:
#model FormModel
#using (Html.BeginForm())
{
#Html.EditorFor(m => m.Items)
}
The editor template:
#model ItemModel
#Html.RadioButton("SelectedItemId", Model.ItemId)
#Model.ItemName <br/>
#Html.TextBoxFor(m => m.SomeString) <br/>
UPDATE
This is what I want:
This is what I get:
As a result, FormModel.SelectedItemId never gets the value of any radio-button.
What am I doing wrong?
It appears as though you are aware that setting the names for radio buttons to be the same is necessary to make them work. However, when you do that in an editor template by using the line of code #Html.RadioButton("SelectedItemId", Model.ItemId), MVC 3 will take into consideration that you are in an editor template for Items and prepend items[n].
This would create a name of something like name="Items[0].SelectedIndex". This would be fine if it weren't for the fact that the next radio button would be `name="Items[1].SelectedIndex".
One way to solve this is to not use an editor template and use a foreach loop instead. Here is some code that I was able to get functional. I confirmed that model-binding worked for the SelectedIndex.
#model FormModel
#{
ViewBag.Title = "Index";
}
#using (Html.BeginForm())
{
foreach (var item in Model.Items)
{
#Html.RadioButtonFor(x => x.SelectedItemId, item.ItemId)
#item.ItemName <br/>
#Html.TextBoxFor(m => item.ItemName) <br/>
}
<input type="submit" value = "submit" />
}
I had same problem, and we solved it with this piece of code.
#Html.RadioButton("", Model.Id, Model.Selected, new { Name = "deliveryMethod" })
You need to put Name property explicitly, so it will be used instead name that you get after EditorFor executes.

Resources