access Enum Items Inside Index View - razor

i am trying to get enum items value inside Index View to Create drop down list for the items of Enum....but i couldn't....how to get enum items value?
the enum:
public enum ReportType
{
[Display(Name = "None")]
None = 0,
[Display(Name = "NotRelated")]
NotRelated = 1,
[Display(Name = "Violation")]
Violation = 2,
[Display(Name = "HateSpeech")]
HateSpeech = 3
};
the drop down list in View:
<select>
#foreach (var item in Model)
{
#if (item.ReportType.ToString()!=1) {
<option value="0">#item.EventNameAr</option>
}
}
</select>

You can try to use :
#if ((int)item.ReportType != 1) {
<option value="0">#item.EventNameAr</option>
}
But you can use display name instead :
#if (item.ReportType.ToString() != "NotRelated") {
<option value="0">#item.EventNameAr</option>
}

Related

Blazor Two Way Binding <select>/<option>

Running into issues trying to update list options in a select. When Function One button is clicked, it fires functionTwo which returns a new list, that should now be the updated list shown in the <select>/<option>
Can someone educate me on what I am not getting correct?
<button ... #onclick="functionOne">Function One</button>
<select #bind="#SelectedValue">
#foreach (var val in updatedList)
{
<option value="#val">#val</option>
}
</select>
public void functionOne()
{
...
List<string> updatedList ...
updatedList = functionTwo();
...
}
public List<string> functionTwo()
{
...
return strList ;
}
Copy this into index.razor of blazor see if it works
#page "/"
<p>#SelectedValue</p>
<button #onclick="functionOne">Function One</button>
<select #bind="#SelectedValue">
#foreach (var val in updatedList)
{
<option value="#val">#val</option>
}
</select>
#code
{
string SelectedValue { get; set; }
List<string> updatedList = new List<string>();
private void functionOne()
{
updatedList = functionTwo();
}
public List<string> functionTwo()
{
return new List<string> { "AAA", "BBB", "CCC" };
}
}

Set selected items in asp.core razor pages

I'm using ASP Core Razor pages.
This my Edit.cshtml.cs:
[BindProperty]
public List<Microsoft.AspNetCore.Mvc.Rendering.SelectListItem> CCusers { get; set; }
and here I fill CCusers with data:
CCusers =new List<Microsoft.AspNetCore.Mvc.Rendering.SelectListItem>() {
new Microsoft.AspNetCore.Mvc.Rendering.SelectListItem() { Value = "1", Text = "HR", Selected = true },
new Microsoft.AspNetCore.Mvc.Rendering.SelectListItem() { Value = "2", Text = "IT", Selected = false },
new Microsoft.AspNetCore.Mvc.Rendering.SelectListItem() { Value = "3", Text = "Account", Selected = false },
};
In Razor Page, I used two different select:
<select asp-for="CCusers" asp-items="#Model.CCusers" id="CCusers" multiple="multiple" class="selectpicker"> </select>
//and this:
#Html.DropDownList("NewSelect", Model.CCusers, new { #class = "selectpicker", #multiple = "multiple" })
and this the result of both of them:
<select id="CCusers" multiple="multiple" class="selectpicker" name="CCusers">
<option value="1">HR</option>
<option value="2">IT</option>
<option value="3">Account</option>
</select>
<select class="selectpicker" id="NewSelect" multiple="multiple" name="NewSelect">
<option selected="selected" value="1">HR</option>
<option value="2">IT</option>
<option value="3">Account</option>
</select>
The Core Select didn't set the selected item while the #Httml.DropDownList did it.
What I'm missing in the first select?
For Select Tag Helper, you will need to set asp-for which specifies the model proprety name for the select element.
For your issue, you need to define new property for selected CCusers instead of binding the CCusers to asp-for directly.
You could refer code below:
Page
public class EditModel : PageModel
{
[BindProperty]
public int[] SelectedCCuserIds { get; set; }
[BindProperty]
public List<SelectListItem> CCusers { get; set; }
public void OnGet()
{
SelectedCCuserIds = new int[] { 1, 2 };
CCusers = new List<SelectListItem>() {
new SelectListItem() { Value = "1", Text = "HR" },
new SelectListItem() { Value = "2", Text = "IT" },
new SelectListItem() { Value = "3", Text = "Account" },
};
}
public IActionResult OnPost()
{
var result = SelectedCCuserIds;
return RedirectToAction("OnGet");
}
}
View
#page
#model CoreRazor.Pages.EditModel
#{
ViewData["Title"] = "Edit";
}
<h2>Edit</h2>
<form method="post">
<select asp-for="#Model.SelectedCCuserIds" asp-items="#Model.CCusers"
multiple="multiple" class="selectpicker"> </select>
#*#Html.DropDownList("NewSelect", Model.CCusers, new { #class = "selectpicker",
#multiple = "multiple" })*#
<div class="form-group">
<input type="submit" value="Save" class="btn btn-default" />
</div>

Set MVC SelectList text to two fileds [duplicate]

How would I generate a select list, where the text field, is made up of two or more text columns, eg: Where I have a Description and Rate field in my database, I want to combine these to show:
Large--£200
Medium--£150
Small--£100
Controller code is:
var stands = db.Stands.Where(s => s.ExhibitorID == null).ToList();
ViewBag.StandID = new SelectList(stands,"StandID", "Description" + "-- £" + "Rate");
...and my view is (currently):
<div class="editor-field">
#Html.DropDownList("StandID", "--Select--")
</div>
...but the "Description" + "-- £" + "Rate"); won't run:
DataBinding:
'System.Data.Entity.DynamicProxies.Stand_63F8C9F623B3C0E57D3008A57081AFCD9C39E1A6B79B0380B60840F1EFAE9DB4'
does not contain a property with the name 'Description--£Rate'.
Thanks for any help,
Mark
You could create a new anonymous class using a simple LINQ projection, and then use the SelectList(IEnumerable, string, string) constructor overload to specify the value and text fields to be used for the <option> elements i.e.:
var stands =
db.Stands
.Where(s => s.ExhibitorID == null)
.Select(s => new
{
StandID = s.StandID,
Description = string.Format("{0}-- £{1}", s.Description, s.Rate)
})
.ToList();
ViewBag.StandID = new SelectList(stands, "StandID", "Description")
Edit
In C#6 and later, string interpolation makes for better reading than string.Format
...
Description = $"{s.Description}-- £{s.Rate}"
If you project to a strong ViewModel class name (instead of to an anonymous class), you will undoubtedly want to replace the magic strings with the safety of the nameof operator:
ViewBag.StandID = new SelectList(stands, nameof(Stand.StandID), nameof(Stand.Description));
var stands = db.Stands.Where(s => s.ExhibitorID == null).ToList();
IEnumerable<SelectListItem> selectList = from s in stands
select new SelectListItem
{
Value = s.StandID,
Text = s.Description + "-- £" + s.Rate.ToString()
};
ViewBag.StandID = new SelectList(selectList, "Value", "Text");
You can create a partial Model class
public partial class Stand
{
public string DisplayName
{
get
{
return this.Description + "-- £" + this.Rate.ToString();
}
}
}
Then in your View
var stands = db.Stands.Where(s => s.ExhibitorID == null).ToList();
ViewBag.StandID = new SelectList(stands,"StandID", "DisplayName");
The Format of the constructor that you are using is
SelectList(IEnumerable items, string dataValueField, string dataTextField).
So when you use it the way you have you are actually telling it to bind to the TextField called "Description-- £Rate" and if this is not what the field is called coming in the from the DB it won't know what you are indicating.
Either of the two methods described above will work as long as the value you have in your dataValueField matches the name of the property you put the Value in and the dataTextField matches the property name of where you put the Text, perhaps a mix of the two solutions above. (Only because I prefer lambda expressions over linq.) and using a selectlist item prevents it from have to do a ToList on the collection after the transform. you are actually creating the objects that naturally bind to a select list.
You also may want to put in checks on the description or rate to make sure they aren't empty before putting them into the list
var stands = db.Stands.Where(s => s.ExhibitorID == null)
.Select(s => new SelectListItem
{
Value = s.StandID.ToString(),
Text = s.Description + "-- £" + s.Rate.ToString()
});
ViewBag.StandID = new SelectList(stands, "Value", "Text");
I did this by modifying my View Model, here are my code:
The View Model
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using MvcEsosNew.Models;
using System.Web.Mvc;
namespace MvcEsosNew.ViewModels
{
public class EntitlementViewModel
{
public int EntitlementCount { get; set; }
public Entitlement Entitlement { get; set; }
public SelectList Member { get; set; }
public SelectList Job_Grade { get; set; }
public SelectList Department { get; set; }
public SelectList Esos_Batch { get; set; }
}
public class department_FullName
{
public int deptID { get; set; }
public string deptCode { get; set; }
public string deptName { get; set; }
public string fullName { get { return deptCode + " - " + deptName; } }
}
}
The Controller
public void getAllDepartment(EntitlementViewModel entitlementVM)
{
var department = from Department in db.Departments.Where(D => D.Status == "ACTIVE").ToList()
select new department_FullName
{
deptID = Department.id,
deptCode = Department.department_code,
deptName = Department.department_name
};
entitlementVM.Department = new SelectList(department, "deptID", "fullName");
}
The View
<div class="form-group row">
<div class="col-sm-2">
#Html.LabelFor(model => model.Entitlement.department_id)
</div>
<div class="col-sm-10">
#Html.DropDownListFor(model => model.Entitlement.department_id, Model.Department, new { #class="form-control" })
#Html.ValidationMessageFor(model => model.Entitlement.department_id)
</div>
</div>
The result:

Post html select to MVC Controller. Finding a better way

I'm just looking for a better way to do the following :
I've got an html select :
<form method="post" action="/Account/ChangeUserRole">
<select name="Val" onchange="this.form.submit();" class="span2">
#foreach (var r in ViewBag.UserRoles)
{
#if (u.UserRole.ID == r.ID)
{
<option selected="selected" value="#u.ID/#r.ID">#r.Name</option>
}
else
{
<option value="#u.ID/#r.ID">#r.Name</option> // <-- better way?
}
}
</select>
</form>
I'm posting it as "userid/roleid" and on the controller side doing a string.Split on / to split u.ID and r.ID
I would like to know if it's possible to post it so my controller get's them in this way :
[HttpPost]
public IActionResult ChangeUserRole(int UserID, int RoleID)
Instead of this witchcraft:
[HttpPost]
public IActionResult ChangeUserRole(string Val)
{
char[] splitChar = new char[] { '/' };
string[] s = Val.Split(splitChar);
int UserID = Convert.ToInt32(s[0]);
int RoleID = Convert.ToInt32(s[1]);
}
Sorry for the long post. Hope my question makes sense.
I'm not such a big fan of html helpers.
Side note:
I'm using MVC 6, ASP 5 - RC1
Appreciate the help
Cheers!
The best solution is to use the TagHelpers to build your dropdown. Let's start by creating a view model specific to this view.
public class UserRoleEditVm
{
public List<SelectListItem> Roles { set; get; }
public int RoleId { set; get; }
public int UserId { set; get; }
}
In your get action, create an object of this, load the property values and send it to the view.
public IActionResult Create()
{
// User Id and Role list is hard coded for demo. You may replace it with real data.
var v = new UserRoleEditVm {UserId = 45};
v.Roles = new List<SelectListItem>
{
new SelectListItem {Value = "1", Text = "Admin"},
new SelectListItem {Value = "2", Text = "Editor"},
new SelectListItem {Value = "3", Text = "Reader"}
};
return View(v);
}
And in your view, which is strongly typed to our view model, we will like Tag helpers to for creating the HTML markup.
#model UserRoleEditVm
<form asp-action="ChangeUserRole" asp-controller="Account">
<select asp-for="RoleId" asp-items="#Model.Roles">
<option>Please select one role</option>
</select>
<input type="hidden"asp-for="UserId"/>
<input type="submit"/>
</form>
And in your HttpPost action method, you can use an object of our view model as the parameter and the Model binder will map the posted form values to property values of that object.
[HttpPost]
public ActionResult ChangeUserRole(UserRoleEditVm model)
{
var userId = model.UserId;
var roleId = model.RoleId;
// to do : Do something with the above 2 values
// to do :Save and redirect (PRG pattern)
// return RedirectToAction("Success");
}

How does a multiple select list work with model binding in ASP.NET MVC?

If you have a select list set to multiple in ASP.NET MVC, how does the modelbinding work?
What does it return for your selected items, an array?
<SELECT NAME="toppings" MULTIPLE SIZE=5>
<option value="mushrooms">mushrooms</option>
<option value="greenpeppers">green peppers</option>
<option value="onions">onions</option>
<option value="tomatoes">tomatoes</option>
<option value="olives">olives</option>
</SELECT>
Yes, by default a multiselectlist will post through an array of the selected values.
This article has further information, including how to use strongly-typed views with a multiselectlist.
From the linked "article":
Your model or view model class needs a collection property for the IDs for the selected option items, e.g. List<int> ToppingIds.
In the controller action method to which the form containing your multi-select-list POSTs, you can access the selected option items thru the collection property you added to the model or view model class.
Yes, it returns an array.
View model:
public class MyViewModel
{
public int[] SelectedIds { get; set; }
public IEnumerable<SelectListItem> Items { get; set; }
}
Controller:
public ActionResult Index()
{
var model = new MyViewModel
{
// fetch the items from some data source
Items = Enumerable.Select(x => new SelectListItem
{
Value = x.Id,
Text = "item " + x.Id
})
};
return View(model);
}
View:
#model MyViewModel
#Html.ListBoxFor(x => x.SelectedIds, Model.Items)
In VegTableViewmodel:
public IEnumerable<MultiSelectList> Vegetables { get; set; }
In the Controller:
Get vegetables list, and then pass it to the VegTableViewModel's Vegetables property.
viewmodel.Vegetables = vegetables .Select(d => new MultiSelectList(d.VegName));
In the View:
#Html.ListBoxFor(m => m.L, new MultiSelectList(Model.Vegetables.Select(d => d.Items))