Using loop to create multiple dropdownlistfor using different lists - c#

I'm trying to create multiple dropdownlistfor components like this:
if (Model.FilaChamado.CamposComboBox != null)
{
for (var i = 0; i < Model.FilaChamado.CamposComboBox.Count; ++i)
{
var lista = Model.FilaChamado.CamposComboBox[i].Itens;
<div class="row">
<div class="col-sm-6">
<label>#Model.FilaChamado.CamposComboBox[i].Nome</label>
#Html.DropDownListFor(x => m => m.CamposPreenchidosComboBox[i], new SelectList(lista), "Selecione", new { #id = "DDLUf", #class = "form-control field" })
#Html.HiddenFor(m => m.FilaChamado.CamposComboBox[i].Nome)
</div>
</div>
}
}
Each dropdownlistfor uses a list of objects stored inside Model.FilaChamado.CamposComboBox[i].Itens. Each object is defined like this:
public class ItemCombobox
{
public int Id { get; set; }
public string Descricao { get; set; }
}
But i'm getting the "The type arguments for method cannot be inferred from the usage" error:
The type arguments for method 'System.Web.Mvc.Html.SelectExtensions.DropDownListFor<TModel,TProperty>(System.Web.Mvc.HtmlHelper<TModel>, System.Linq.Expressions.Expression<System.Func<TModel,TProperty>>, System.Collections.Generic.IEnumerable<System.Web.Mvc.SelectListItem>, string, object)' cannot be inferred from the usage.
What am i missing here?

Try making the list just a list of strings
var lista = Model.FilaChamado.CamposComboBox[i].Itens.Select(i => i.Descricao);
and make the drop down list bound to the strings
#Html.DropDownListFor(x => m => m.CamposPreenchidosComboBox[i].Name, new SelectList(lista), "Selecione", new { #id = "DDLUf"+i.ToString(), #class = "form-control field" })
Make sure to note the #Id should unique for each combobox, although I would recommend not setting this at all as it can mess with the ASP.NET Binding when there are lists of comboboxes. Maybe leave #Id out.

Related

How to use Html.EditorFor with a type List<object>

I am creating a form that a list of Education and work experiences but i am getting an error "Cannot convert lambda expression to type 'Education' because it is not a delegate type " when trying this
#model Resume
#Html.EditorFor(m => m.Fullname, new { htmlAttributes = new { #class = "form-control", placeholder = "Your Full Name" } })
my resume object has a
public List<Education> Educations { get; set; }
also i have a section for Education with a button "Add Another" which duplicates that section thats why it is a list
Do you want to create a list form?
If yes you can use #Html.DropDownList with ViewBag:
Controller:
ViewBag.Educations = EducationsList;
View:
#Html.DropDownList("Educations", null, "", htmlAttributes: new { #class = "form-control"})

SelectListItem not setting via dropdown after extending SelectList class

I am trying to extend the SelectListItem class to add another property called CardColor. However when I try to access the property in my controller I get
NullReferenceException: Object reference not set to an instance of an object....
return View("StringView", c.IssueSelected.CardColor);
Controller:
[HttpPost]
public async Task<ActionResult> CardCreate(UpdateCardFormOptions c)
{
return View("StringView", c.IssueSelected.CardColor);
}
View
#using (#Html.BeginForm())
{
<p><label>Issue Category*:</label> #Html.DropDownListFor(c => #Model.IssueSelected, Model.IssueList, new { #class = "form-control", #style = "width: 350px" })</p>
}
Model:
public IssueSelectListItem IssueSelected { get; set; }
public List<IssueSelectListItem> IssueList = new List<IssueSelectListItem>() {
new IssueSelectListItem() {Text="xxx", Value="yyy",CardColor="pink"},
};
public class IssueSelectListItem : SelectListItem
{
public string CardColor { get; set; }
}
This post gave me a clue, turns out I needed to set the value CardColor in the View, I couldnt just set the object equivalent. My View needed to set CardColor based on my dropdown choice like this:
<p><label>Issue Category*:</label> #Html.DropDownListFor(c => #Model.IssueSelected.CardColor, Model.IssueList, new { #class = "form-control", #style = "width: 350px" })</p>
Not going to accept my own answer, still hoping someone has a better one, this just solved my immediate problem

ViewModel Properties in Query String are not bound when arriving at Controller

I'm working in an ASP.net MVC application, and I have a table of products as shown in the screenshot:
I would like the ability to filter that table of products, and I'd like the filtering to happen via the query string params (as a GET) so that the URL can be shared.
The ViewModel for the page is like this:
public class InventoryReportViewModel
{
public SearchViewModel Search { get; set; } // 2 string props [Type and Term]
public IEnumerable<ProductViewModel> Products { get; set; }
public PaginationViewModel Pagination { get; set; } // 3 int props [currentPage, recordsPerPage, totalRecords]
}
I'm using Razor helpers to draw the filter inputs, like this:
#Html.EditorFor(m => m.Search.Term, new { htmlAttributes = new { #class = "form-control" } })
And also I've set up my form to use GET like so:
#using (Html.BeginForm("Inventory", "Report", FormMethod.Get))
{
// form elements
}
My ReportController.cs has the following method that is relevant to my question here:
public ActionResult Inventory(string SearchTerm, string SearchType, int page = 1)
{
var viewModel = _reportService.GetProducts(page, SearchTerm, SearchType);
return View(viewModel);
}
When I pass a Search term, and click the Filter Results button, I do arrive at my Controller method above, but the SearchTerm and SearchType are null.
I know how to "hack" this to work, for example, if I do this:
<input type="text" name="SearchTerm" class="form-control"/>
Then the search term I input would be picked up by the Controller, but is there no other way?
since you already made a viewmodel for Search
public SearchViewModel Search { get; set; }
you just need to pass it to the controller like this
public ActionResult Inventory(SearchViewModel Search, int page = 1
{
var viewModel = _reportService.GetProducts(page, Search.Term, Search.Type);
return View(viewModel);
}
you were getting null because the textboxes were named as Search.Term that is why it was not matching the parameters.
The form should be post
#using (Html.BeginForm("Inventory", "Report", FormMethod.Post))
{
// form elements
}
This can also be cleaner:
#Html.EditorFor(m => m.Search.Term, new { htmlAttributes = new { #class = "form-control" } })
to
#Html.EditorFor(m => m.Search.Term, new { #class = "form-control" } )
Another question,
In the razor view, do you have a model specified on the first line?

How can I access the model properties from extended attribute when using textboxfor?

Conceptually I would like the following code to work:
#Html.TextBoxFor(x => x.Something, null, new {
#class = "custom",
data_min = x.min,
data_max = x.max,
data_step = x.step
})
Of course it doesn't it seems I can't access the properties min, max etc from the extended attributes section.
How can I implement this?
Thanks.
Just use the Model:
#Html.TextBoxFor(
x => x.Something,
new {
#class = "custom",
data_min = Model.min,
data_max = Model.max,
data_step = Model.step
}
)
Add this property to your model
public IDictionary<string, object> Attributes { get; set; }
Then
#Html.TextBoxFor(model => model.SomeValue, Model.Attributes)

Html.EditorFor Set Default Value

Rookie question.
I have a parameter being passed to a create view. I need to set a field name with a default value.
#Html.EditorFor(model => model.Id)
I need to set this input field with name Id with a default value that is being passed to the view via an actionlink.
So, how can this input field --#Html.EditorFor(model => model.Id) -- get set with a default value.
Would the following work?? Where the number 5 is a parameter I pass into the text field to set default value.
#Html.EditorFor(c => c.PropertyName, new { text = "5"; })
Here's what I've found:
#Html.TextBoxFor(c => c.Propertyname, new { #Value = "5" })
works with a capital V, not a lower case v (the assumption being value is a keyword used in setters typically) Lower vs upper value
#Html.EditorFor(c => c.Propertyname, new { #Value = "5" })
does not work
Your code ends up looking like this though
<input Value="5" id="Propertyname" name="Propertyname" type="text" value="" />
Value vs. value. Not sure I'd be too fond of that.
Why not just check in the controller action if the proprety has a value or not and if it doesn't just set it there in your view model to your defaulted value and let it bind so as to avoid all this monkey work in the view?
The clean way to do so is to pass a new instance of the created entity through the controller:
//GET
public ActionResult CreateNewMyEntity(string default_value)
{
MyEntity newMyEntity = new MyEntity();
newMyEntity._propertyValue = default_value;
return View(newMyEntity);
}
If you want to pass the default value through ActionLink
#Html.ActionLink("Create New", "CreateNewMyEntity", new { default_value = "5" })
Its not right to set default value in View. The View should perform display work, not more. This action breaks ideology of MVC pattern. So the right place to set defaults - create method of controller class.
Better option is to do this in your view model like
public class MyVM
{
int _propertyValue = 5;//set Default Value here
public int PropertyName{
get
{
return _propertyValue;
}
set
{
_propertyValue = value;
}
}
}
Then in your view
#Html.EditorFor(c => c.PropertyName)
will work the way u want it (if no value default value will be there)
I just did this (Shadi's first answer) and it works a treat:
public ActionResult Create()
{
Article article = new Article();
article.Active = true;
article.DatePublished = DateTime.Now;
ViewData.Model = article;
return View();
}
I could put the default values in my model like a propper MVC addict: (I'm using Entity Framework)
public partial class Article
{
public Article()
{
Active = true;
DatePublished = Datetime.Now;
}
}
public ActionResult Create()
{
Article article = new Article();
ViewData.Model = article;
return View();
}
Can anyone see any downsides to this?
Shouldn't the #Html.EditorFor() make use of the Attributes you put in your model?
[DefaultValue(false)]
public bool TestAccount { get; set; }
Shove it in the ViewBag:
Controller:
ViewBag.ProductId = 1;
View:
#Html.TextBoxFor(c => c.Propertyname, new {#Value = ViewBag.ProductId})
This worked for me
In Controlle
ViewBag.AAA = default_Value ;
In View
#Html.EditorFor(model => model.AAA, new { htmlAttributes = new { #Value = ViewBag.AAA } }
For me I need to set current date and time as default value this solved my issue in View add this code :
<div class="form-group">
#Html.LabelFor(model => model.order_date, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.order_date, new { htmlAttributes = new { #class = "form-control",#Value= DateTime.Now } })
#Html.ValidationMessageFor(model => model.order_date, "", new { #class = "text-danger" })
</div>
</div>
This worked for me:
In the controller
*ViewBag.DefaultValue= "Default Value";*
In the View
*#Html.EditorFor(model => model.PropertyName, new { htmlAttributes = new { #class = "form-control", #placeholder = "Enter a Value", #Value = ViewBag.DefaultValue} })*
In the constructor method of your model class set the default value whatever you want.
Then in your first action create an instance of the model and pass it to your view.
public ActionResult VolunteersAdd()
{
VolunteerModel model = new VolunteerModel(); //to set the default values
return View(model);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult VolunteersAdd(VolunteerModel model)
{
return View(model);
}
This is my working code:
#Html.EditorFor(model => model.PropertyName, new { htmlAttributes = new { #class = "form-control", #Value = "123" } })
my difference with other answers is using Value inside the htmlAttributes array
Instead of using controller or html helper.You can also use Jquery to set default value to model attribute.
$('#PropertyName').val(15);

Categories

Resources