I'm currently localizing an open source project and I have an issue with Enums.
Here is my Enums.cs (not the whole file, just part of where the issue appears).
public enum ModeratorLevel
{
[Display(Name = "Sahip")]
Owner = 1,
[Display(Name = "Moderatör")]
Moderator = 2,
[Display(Name = "Temizlikçi")]
Janitor = 3,
[Display(Name = "Boyacı")]
Designer = 4,
[Display(Name = "Paylaşımcı")]
Submitter = 99
}
and this is my View (again, not the whole file, contains only the codes that I want to fix)
#{
string subverseName = ViewBag.SubverseName;
var levelsAvailable = Enum.GetValues(typeof(ModeratorLevel)).OfType<ModeratorLevel>();
var currentLevel = ModeratorPermission.Level(User.Identity.Name, subverseName);
levelsAvailable = levelsAvailable.Where(x => x > currentLevel || currentLevel == ModeratorLevel.Owner);
}
#* these areas contain other codes is not related to my issue *#
<div class="form-group">
#Html.Label("foo", htmlAttributes: new {#class = "control-label col-md-2"})
<div class="col-md-4">
#Html.DropDownListFor(model => model.Power, levelsAvailable.Select(x => new SelectListItem() { Text = x.ToString(), Value = ((int)x).ToString() }), new { #class = "form-control"} )
#Html.ValidationMessageFor(model => model.Power, "", new {#class = "text-danger"})
</div>
</div>
#* these areas contain other codes is not related to my issue *#
and this is output;
dropdownlist
aaand now, What I want?
I want to display DisplayNames instead Enum values.
The outpot looks like:
foo = Owner
Moderator
Janitor
Designer
Submitter
But I want to show it looks like:
foo = Sahip
Moderatör
Temizlikçi
Boyacı
Paylaşımcı
But in this change, changes must be only visual. We shouldn't change any code that affects to Enum's function. I just want to show only DisplayNames instead of Enum values.
Thanks.
you can add an extension method :
public static string DisplayName(this Enum value)
{
Type enumType = value.GetType();
var enumValue = Enum.GetName(enumType, value);
MemberInfo member = enumType.GetMember(enumValue)[0];
var attrs = member.GetCustomAttributes(typeof(DisplayAttribute), false);
var outString = ((DisplayAttribute)attrs[0]).Name;
if (((DisplayAttribute)attrs[0]).ResourceType != null)
{
outString = ((DisplayAttribute)attrs[0]).GetName();
}
return outString;
}
and then use it in the view :
#Html.DropDownListFor(model => model.Power, levelsAvailable.Select(x => new SelectListItem() { Text = x.DisplayName(), Value = ((int)x).ToString() }), new { #class = "form-control"} )
Use the EnumDropDownListFor helper
#Html.EnumDropDownListFor(model => model.Power)
Related
I have filled the ViewBag.BankNames using Banks table as
ViewBag.BankNames = new SelectList(db.Banks, "BankId", "BankName", applicationSettings.BankId);
where applicationSettings.BankdId is having the value which I need to show as the selected value in dropdown, then passed the applicationSetting model object to view.
In my View I have used that ViewBag like
#Html.DropDownListFor(model => model.BankId, ViewBag.BankNames as SelectList, "Select Bank", htmlAttributes: new { #class = "form-control" })
It will show me the dropdown list with all values of Bank names but the selected value is Select Bank and not the value which I set as selected value in ViewBag?
Can you assign applicationSettings.BankId to BankId of model property and check..
you are binding #Html.DropDownListFor(model => model.BankId, ViewBag.BankNames as SelectList, "Select Bank", htmlAttributes: new { #class = "form-control" }) but in model.BankId is zero..
Assign Model.BankId = applicationSettings.BankId before returning it to view
In Controller
public ActionResult Index()
{
var banks = new List<Banks>()
{
new Banks()
{
BankId =1,
BankName = "Bank 1"
},
new Banks()
{
BankId =2,
BankName = "Bank 2"
}
};
var list = new SelectList(banks, "BankId", "BankName");
ViewBag.Banks = list;
var modelBanks= new Banks();
modelBanks.BankId = 2;
return View(modelBanks);
}
In View
#model Banks
#using WebApplication3.Models
#Html.DropDownListFor(model => model.BankId, ViewBag.Banks as SelectList,"Select Bank")
I do already have dropdownlist in my ASP.NET MVC 5 project.
I need to remove one of the item parameter call it "Admin"; I want remove it from the list when the page is loaded.
This is my Razor markup:
<div class="form-group">
#Html.LabelFor(model => model.RoleName, htmlAttributes: new { #class = "control-label col-md-3" })
<div class="col-md-9">
#Html.DropDownListFor(model => model.RoleName, Model.VMRoles, new { #class = "form
control input-sm", multiple= "multiple" })
#Html.ValidationMessageFor(model => model.RoleName, "", new { #class = "text-danger" })
</div>
</div>
And this the C# controller:
[HttpGet]
[Authorize]
public ActionResult Create()
{
var vm = new CreateUserViewModel
{
VMSisterConcerns = _sisterConcernService.GetAllSisterConcern().Select(c => new SelectListItem { Text = c.Name, Value = c.ConcernID.ToString() }).ToList(),
VMRoles = _roleService.GetAllRole().Select(r => new SelectListItem { Text = r.Name, Value = r.Name }).ToList(),
ConcernId = User.Identity.GetConcernId().ToString()
};
return View(vm);
}
And this the model:
public ICollection<System.Web.Mvc.SelectListItem> VMRoles { get; set; }
Here is the correct answer thanks for #itsme86 he mention How to understand LINQ .
VMRoles = _roleService.GetAllRole().Where(r => r.name != "Admin").Select(r => new SelectListItem { Text = r.Name, Value = r.Name }).ToList(),
I'm new to MVC, and very new to JQuery. I'm attempting to populate textboxes based on a dropdownlist selection. My Product model contains the fields ProductId, Name, and Price. I want to populate the ProductId and Price fields in my QuoteDetails based upon the product Name chosen. My controller action is as follows:
public ActionResult AddProduct(int quoteId, int quoteDetailId)
{
var items = db.Products.ToList();
ViewBag.ProductData = items;
ViewData["QuoteId"] = quoteId;
ViewData["QuoteDetailId"] = quoteDetailId;
return PartialView("EditQuoteDetail", new QuoteDetail { QuoteId = quoteId, QuoteDetailId = quoteDetailId, ProductId = 1, ProductName = " ", Amount = 1, ListPrice = 0, Discount = 0, Price = 0 });
}
The relevant portion of the partial view EditQuoteDetail is as follows:
#Html.HiddenFor(model => model.QuoteId, new { htmlAttributes = new { #class = "form-control" } })
#Html.HiddenFor(model => model.QuoteDetailId, new { htmlAttributes = new { #class = "form-control" } })
#Html.EditorFor(model => model.ProductId, new { htmlAttributes = new { #id="ProductId", #class = "form-control" } })
#Html.DropDownList("ProductName", new SelectList(ViewBag.ProductData, "Name", "Name"), new { #id = "ProductName" })
#Html.EditorFor(model => model.Amount, new { htmlAttributes = new { #class = "form-control" } })
#Html.EditorFor(model => model.ListPrice, new { htmlAttributes = new { #id="Price", #class = "form-control" } })
#Html.EditorFor(model => model.Discount, new { htmlAttributes = new { #class = "form-control" } })
#Html.EditorFor(model => model.Price, new { htmlAttributes = new { #class = "form-control" } })
The script I am using to attempt to populate the ProductId and Price fields is as follows:
<script type="text/javascript">
$(document).ready(function () {
$('#ProductName').change(function () {
$('#ProductId').val($(this).val());
$('#Price').val($(this).val());
});
});
</script>
But when I make the dropdown list selection, nothing happens. What am I doing wrong? Any help would be much appreciated.
Here's what I think is happening...
(1) #Html.DropDownList("ProductName", new SelectList(ViewBag.ProductData, "Name", "Name"), new { #id = "ProductName" })
This line creates a <select> html element with an id of "ProductName" as expected; though the value of the options within that list are text values. Because you are using the "Name" for both the value and text of the option. For example:
<select id="ProductName" name="ProductName">
<option value="Product 1">Product 1</option>
<option value="Product 2">Product 2</option>
</select>
(2) #Html.EditorFor(model => model.ProductId, new { htmlAttributes = new { #id="ProductId", #class = "form-control" } })
Since you are using the EditorFor Html helper, it is trying to validate an integer (I assume) of the ProductId. Your javascript is trying to insert a String, like "Product 1".
(3) #Html.EditorFor(model => model.ListPrice, new { htmlAttributes = new { #id="Price", #class = "form-control" } })
This has a slightly different issue. The ID of the HTML element will default to "ListPrice" and not be overridden by your #id property in the htmlAttributes object. Side question, do you mean to put #id = "Price" on the "ListPrice" element? Even if you fixup the ID attributes of these elements, you may still run into the data type issue from (2) above.
Try switching the target element to a TextBoxFor as a quick test.
The problem is not in the script you are populating dropdown
ViewBag.ProductData, "Name", "Name" by Name so the id of the dropdown will also be its Name and also ProductId and Price both are int so you cannot set text value in int field
So you should set the ViewBag.ProductData, "Id", "Name" when ever you will run the script it will get the int value of productId
Edit
if you want to get the data based on your Product id you have to make ajax call for that in jquery and you have to make action for that in controller
[HttpPost]
public ActionResult GetProduct(int pId)
{
var data = db.Products.Find(id);
return Json(data);
}
and your view would be
#model CMSUsersAndRoles.Models.QuoteDetail
#{
ViewBag.Title = "EditQuoteDetail";
Layout = null;
}
#{
var quoteId = (int)ViewData["QuoteId"];
var quoteDetailId = (int)ViewData["QuoteDetailId"];
}
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
</head>
<body>
<div id="row">
<table>
#using (Html.BeginCollectionItem("quoteDetail"))
{
<tr>
#Html.HiddenFor(model => model.QuoteId, new { htmlAttributes = new { #class = "form-control" } })
#Html.HiddenFor(model => model.QuoteDetailId, new { htmlAttributes = new { #class = "form-control" } })
#Html.TextBoxFor(model => model.ProductId, new { htmlAttributes = new { #id="ProductId", #class = "form-control" } })
#Html.DropDownList("ProductList", new SelectList(ViewBag.ProductData, "ProductId", "Name"), new { #id = "ProductList" })
#Html.EditorFor(model => model.Amount, new { htmlAttributes = new { #class = "form-control" } })
#Html.TextBoxFor(model => model.Price, new { htmlAttributes = new { #id="Price", #class = "form-control" } }
#Html.EditorFor(model => model.Discount, new { htmlAttributes = new { #class = "form-control" } })
#Html.EditorFor(model => model.ListPrice, new { htmlAttributes = new { #class = "form-control" } })
#Ajax.ActionLink(" ", "DeleteProduct", "QuoteViewModel", new { quoteId = Model.QuoteId, quoteDetailId = (Model.QuoteDetailId) },
new AjaxOptions
{
HttpMethod = "POST",
Confirm = "Are you Sure You Want to Delete " + Model.ProductName,
OnSuccess = "RemoveRow"
},
new { #class = "btn btn-danger glyphicon glyphicon-trash" })
</tr>
}
</table>
</div>
<script type="text/javascript">
$(document).ready(function () {
$('#ProductList').change(function () {
$.post("/QuoteViewModel/GetProduct", { pId: $(this).val() }, function (data) {
$('#ProductId').val(data.ProductId);
$('#Price').val(data.Price);
});
});
});
</script>
</body>
</html>
At last, I found an answer. travis.js started me on the right path when he said the BeginCollectionItem helper was overtaking my HTML, so I had to use id contains syntax to make it work. The working jQuery (in the parent view) is as follows:
<script type="text/javascript">
$(document).ready(function () {
$(document).on("change", '[id*="ProductList"]', function () {
$.post("/QuoteViewModel/GetProduct", { pId: $(this).val() }, function (data) {
$("[id*='ProductId']").val(data.ProductId);
$("[id*='Price']").val(data.Price);
});
});
});
</script>
And the controller action (thanks Usman) is as follows:
[HttpPost]
public ActionResult GetProduct(int pId)
{
var data = db.Products.Find(pId);
return Json(data);
}
Whew!
I would like to change two textboxes when I select option from dropdown but I don't know how can I do it.
I'm using dbml file for connecting to other database. I would like to use 2 properties for 2 textboxes = STOK_FIYAT and STOK_KODU.
private BETASYSEntities db = new BETASYSEntities();
private NETSISDataContext netsisdb = new NETSISDataContext();
public ActionResult Olustur(int FormulID)
{
FormulasyonAyrintilari formulasyonayrintilari = new FormulasyonAyrintilari();
formulasyonayrintilari.FormulID = FormulID;
ViewBag.StokAdi = new SelectList(netsisdb.TBLSTSABIT, "STOK_ADI", "STOK_ADI");
return PartialView("_Olustur", formulasyonayrintilari);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Olustur([Bind(Include = "FormulAyrintilariID,FormulID,StokAdi,StokKodu,StokBirim,StokMiktar,StokFiyat")] FormulasyonAyrintilari formulasyonayrintilari)
{
if (ModelState.IsValid)
{
db.FormulasyonAyrintilari.Add(formulasyonayrintilari);
db.SaveChanges();
string url = Url.Action("Index", "FormulasyonAyrintilari", new { id = formulasyonayrintilari.FormulID });
return Json(new { success = true, url = url });
}
ViewBag.StokAdi = new SelectList(netsisdb.TBLSTSABIT, "STOK_ADI", "STOK_KODU", formulasyonayrintilari.StokAdi);
return PartialView("_Olustur", formulasyonayrintilari);
}
#Html.DropDownList("StokAdi", null, "Lütfen Seçin", htmlAttributes: new { #class = "form-control col-md-3 select2", autocomplete = "off" })
#Html.EditorFor(model => model.StokKodu, new { htmlAttributes = new { #class = "form-control", autocomplete = "off" } })
#Html.EditorFor(model => model.StokFiyat, new { htmlAttributes = new { #class = "form-control", autocomplete = "off" } })
Create an action that returns JsonResult which will receive the value STOK_ADI and returns a JSON Object that has STOK_KODU and STOK_FIYAT
public JsonResult GetValuesForSTOK_ADI(string STOK_ADI)
{
//get the values from the DB for the provided STOK_ADI
return Json(new {STOK_KODU ="value from db",STOK_FIYAT="value from db"},JsonRequestBehavior.AllowGet));
}
In your view, change the declaration for the drop down to add an onchange event that will call the action
#Html.DropDownList("StokAdi", null, "Lütfen Seçin", htmlAttributes: new { #class = "form-control col-md-3 select2", autocomplete = "off",onchange="updateTextBoxes()"})
at the end of the file, create the below javascript function
<script>
function updateTextBoxes()
{
var selectedSTOK_ADI = $("#StokAdi").val();
$.ajax('#Url.Action("GetValuesForSTOK_ADI","ControllerName")').then(function(data){
$("#StokKodu").val(data.STOK_KODU);
$("#StokFiyat").val(data.STOK_FIYAT);
});
}
</script>
I did check all issues about that but I couldn't figure out how to solve it. I need to your help guys.
Here is my code about dropdownlist. When I post the page I got the error message which I mentioned above.
.cshtml
<div class="editor-label">
#Html.LabelFor(model => model.Department, new { #style = " margin-top:12px;display:block;text-align:center" })
</div>
<div class="editor-field">
#Html.DropDownList("Department",(SelectList) ViewBag.Department, new { id = "Department", #class = "form-control", #style = "width:250px; margin-top:5px;margin-left: auto;margin-right:auto; text-align:center;" })
#Html.ValidationMessageFor(model => model.Department.Name)
</div>
model
public ActionResult Index()
{
IEnumerable<SelectListItem> items = db.Department
.Select(c => new SelectListItem
{
Value = c.ID.ToString(),
Text = c.Name
});
var selectList = new SelectList(items,"Value","Text");
ViewBag.Department = selectList;
return View();
}
[HttpPost]
public ActionResult Index(Person model, HttpPostedFileBase photo)
{
if (ModelState.IsValid)
{
Person Person = new Person();
Person.DeparmentID = model.Department.ID;
Person.FirmID = model.Firm.ID;
Person.GraduationDate = model.GraduationDate;
Person.HomeTel = model.HomeTel;
Person.MobileTel = model.MobileTel;
Person.Mail = model.Mail;
Person.Name = model.Name;
Person.Surname = model.Surname;
Person.Position = model.Position;
Person.WorkingSituation = model.WorkingSituation;
if (photo != null && photo.ContentLength > 0)
{
if (photo.ContentLength > 10240)
{
ModelState.AddModelError("photo", "Resim boyutu 10 KB'ı aşamaz.");
return View();
}
var supportedTypes = new[] { "jpg", "jpeg", "png" };
var fileExt = System.IO.Path.GetExtension(photo.FileName).Substring(1);
if (!supportedTypes.Contains(fileExt))
{
ModelState.AddModelError("photo", "Yalnızca jpg, jpeg, png veri tipleri desteklenmektedir.");
return View();
}
var fileName = Path.GetFileName(photo.FileName);
photo.SaveAs(Server.MapPath("~/Upload/") + photo.FileName);
Person.Img = fileName;
}
db.Person.Add(Person);
db.SaveChanges();
ViewBag.ShowConfirmation = "The item was created.";
return RedirectToAction("Index");
}
else
{
return View(model);
}
}
Maybe if you use DropDownListFor instead of DropDownList? You would need to include the listitems in your viewmodel instead of in a viewbag.
Along these lines
#Html.DropDownListFor(m => m.Department, new SelectList(Model.Departments, "Value", "Text", Model.Department), new { #style = "..." })
The second and third parameter of the SelectList constructor define the names of the Value and Text parameters in your SelectListItem list.