I have categories and subcategories as model. And each category includes many subcategories as you may have guessed. The point is that I have a view, and in my view I have a code segment like this one:
<div class="form-group">
#Html.LabelFor(model => model.CategoryID, "Category", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("CategoryID", null, "Please select a category", htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.CategoryID, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.SubcategoryID, "Subcategory", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("SubcategoryID", null, "Please select a subcategory", htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.SubcategoryID, "", new { #class = "text-danger" })
</div>
</div>
Then, in my controller, I have two ViewBag objects, which populate my SelectList objects:
ViewBag.CategoryID = new SelectList(db.Categories, "CategoryID", "CategoryName");
ViewBag.SubcategoryID = new SelectList(db.Subcategories, "SubcategoryID", "SubcategoryName");
Then I wrote some AJAX code, in order to make the values of the DropDownList elements to synchronize. I have the following action and JS code.
[AllowAnonymous]
public JsonResult GetSubcategories(int id)
{
var results = db.Subcategories.Where(s => s.CategoryID == id).Select(x => new { id = x.SubcategoryID, value = x.SubcategoryName }).ToList();
return Json(results, JsonRequestBehavior.AllowGet);
}
JavaScript code with the AJAX call:
$("#CategoryID").change(function () {
$("#SubcategoryID").empty();
$.ajax({
type: 'POST',
url: '/Account/GetSubcategories',
dataType: 'json',
data: { id: $("#CategoryID").val() },
success: function (subcategories) {
$.each(subcategories, function (i, subcategory) {
$("#SubcategoryID").append('<option value="' + subcategory.value + '">' + subcategory.value + '</option>');
});
},
error: function (ex) {
console.log('Failed to retrieve subcategories! ' + ex);
}
});
return false;
});
The point is that, it synchronized the DropDownLists, so whenever I select a category, I only shows subcategories for that selected category. But, I'm not able to submit my form now, whenever I press submit, I get an error message saying that the selected value is not a valid Subcategory. How can I fix it?
EDIT:
When I did some digging with the developer tools, I saw that for my Categories, for the value part I have numbers, which are their corresponding id in the database, but now for my Subcategories for the value part I get a text, meaning the name of the Subcategory.
This
$("#SubcategoryID").append('<option value="' + subcategory.value + '">' + subcategory.value + '</option>');
should be
$("#SubcategoryID").append('<option value="' + subcategory.id + '">' + subcategory.value + '</option>');
Related
I want to get the description and price of the selected artikel, but i want to be able to edit it afterwards so for example you have a standard price which can be adjusted.
Here is what my database looks like.
Here is my view code. (I left out some input fields)
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-group">
#Html.LabelFor(model => model.ArtikelID, "ArtikelID", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("ArtikelID", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.ArtikelID, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ArtikelBeschrijving, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.ArtikelBeschrijving, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.ArtikelBeschrijving, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ArtikelPrijs, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.ArtikelPrijs, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.ArtikelPrijs, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
and the controller for the view.
// GET: Orders/Create
public ActionResult Create()
{
ViewBag.ArtikelID = new SelectList(db.Artikels, "ArtikelID", "ArtikelNummer");
ViewBag.PaardID = new SelectList(db.Paarden, "PaardID", "Naam");
return View();
}
// POST: Orders/Create
// To protect from overposting attacks, enable the specific properties you want to bind to, for
// more details see https://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "OrderID,Ordernummer,PaardID,KlantNaam,PaardNaam,ChipNummer,Levensnummer,ArtikelID,ArtikelBeschrijving,ArtikelPrijs,Datum")] Orders orders)
{
if (ModelState.IsValid)
{
db.Orders.Add(orders);
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.ArtikelID = new SelectList(db.Artikels, "ArtikelID", "ArtikelNummer", orders.ArtikelID);
ViewBag.PaardID = new SelectList(db.Paarden, "PaardID", "Naam", orders.PaardID);
return View(orders);
}
This is essentially what i want.
I've tried searching everywhere, but i couldn't find anything similar to what i want. Hopefully you guys can help me out.
Below is a work demo, you can refer to it.
1.Add id to ArtikelID, ArtikelBeschrijving,ArtikelPrijs, like below:
#Html.DropDownList("ArtikelID", null, htmlAttributes: new { #class = "form-control" ,#id="list" })
#Html.EditorFor(model => model.ArtikelBeschrijving, new { htmlAttributes = new { #class = "form-control" ,#id="id01"} })
#Html.EditorFor(model => model.ArtikelPrijs, new { htmlAttributes = new { #class = "form-control", #id="id02" } })
2.Add below <script> to your Create view.
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script type="text/jscript">
$(function() {
$("#list").change(function() {
var selectedid = $('option:selected').val();
$.ajax({
url: "/YourControllerName/GetDropDownList",
data: {
id: selectedid
},
type: "Post",
dataType: "Json",
success: function(result) {
document.getElementById('id01').value = result.beschrijving;
document.getElementById('id02').value =result.prijs;
},
error: function() {
}
});
});
});
</script>
3.In your Controller, add GetDropDownList action like below:
[HttpPost]
public IActionResult GetDropDownList(int id)
{
var result = db.Artikels.FirstOrDefault(m => m.ArtikelID == id);
return Json(result);
}
Result:
Update get id
I have a registration form and there is two inputs for password and password confirmation. When I enter distinct values I wanted it to show the error message as 'Passwords should match' or something. So I googled it and found out that update-package should fix this problem. Then I applied this solution in order to fix my problem, now, neither my error message shows up nor my submit button works.
My Registration View:
<div class="container-fluid">
#using (Html.BeginForm("Register", "User", FormMethod.Post, new { #class = "col-12" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal p-3 m-3 w-100 d-flex flex-column align-items-center">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group w-100">
<label class="form-control-label col-md-12">Kullanıcı adı</label>
<div class="col-md-12">
#Html.EditorFor(model => model.User.kullaniciAdi, new { htmlAttributes = new { #class = "form-control", #required = "required" } })
#Html.ValidationMessageFor(model => model.User.kullaniciAdi, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group w-100">
<label class="form-control-label col-md-12">Firma adı</label>
<div class="col-md-12">
#Html.EditorFor(model => model.User.firmaAdi, new { htmlAttributes = new { #class = "form-control", #required = "required" } })
#Html.ValidationMessageFor(model => model.User.firmaAdi, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group w-100">
<label class="form-control-label col-md-12">Şifre</label>
<div class="col-md-12">
#Html.EditorFor(model => model.User.sifre, new { htmlAttributes = new { #class = "form-control", #required = "required", #type = "password" } })
#Html.ValidationMessageFor(model => model.User.sifre, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group w-100">
<label class="form-control-label col-md-12">Şifre tekrar</label>
<div class="col-md-12">
#Html.EditorFor(model => model.User.sifreTekrar, new { htmlAttributes = new { #class = "form-control", #required = "required", #type = "password" } })
#Html.ValidationMessageFor(model => model.User.sifre, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group w-100">
<label class="form-control-label col-md-12">E-mail</label>
<div class="col-md-12">
#Html.EditorFor(model => model.User.mail, new { htmlAttributes = new { #class = "form-control", #required = "required", #type = "text" } })
#Html.ValidationMessageFor(model => model.User.mail, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group w-100">
<label class="form-control-label col-md-12">Telefon</label>
<div class="col-md-12">
#Html.EditorFor(model => model.User.telefon, new { htmlAttributes = new { #class = "form-control", #type = "text", #required = "required" } })
#Html.ValidationMessageFor(model => model.User.telefon, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group w-100">
<label class="form-control-label col-md-12">Ülkeniz</label>
#Html.EditorFor(model => model.Address.ulkeID, new { htmlAttributes = new { #class = "form-control", #type = "text", #readonly="readonly", #Value="Türkiye" } })
</div>
<div class="form-group w-100">
<label class="form-control-label col-md-12">Bulunduğunuz il</label>
<select class="form-control col-md-12" name="Address.sehirID" id="il" required></select>
</div>
<div class="form-group w-100">
<label class="form-control-label col-md-12">Bulunduğunuz ilçe</label>
<select class="form-control col-md-12" name="Address.ilceID" id="ilce" disabled required>
<option>Bir İl Seçiniz</option>
</select>
</div>
<div class="form-group w-100">
<label class="form-control-label col-md-12">Açık adresiniz</label>
<div class="col-md-12">
#Html.EditorFor(model => model.Address.acikAdres, new { htmlAttributes = new { #class = "form-control", #type = "text", #required = "required" } })
#Html.ValidationMessageFor(model => model.Address.acikAdres, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group w-100">
<label class="form-control-label col-md-12">Oluşturulma Tarihi</label>
<div class="col-md-12">
#Html.EditorFor(model => model.User.olusturulmaTarihi, new { htmlAttributes = new { #class = "form-control", #type = "text", #readonly="readonly", #Value=sqlFormat } })
#Html.ValidationMessageFor(model => model.Address.acikAdres, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group w-100">
<div class="col-md-offset-2 col-md-12">
<input type="submit" value="Kaydol" class="btn btn-success" />
</div>
</div>
</div>
}
</div>
Register Action:
[HttpPost]
public ActionResult Register(RegisterVM model)
{
tblKullanici user = null;
tblAdres address = null;
if(model != null)
{
db = new DatabaseContext();
user = model.User;
address = model.Address;
db.tblKullanici.Add(user);
db.tblAdres.Add(address);
db.SaveChanges();
if (db.SaveChanges() > 0)
{
Session["login"] = model.User;
return RedirectToAction("Index", "App");
}
}
ViewBag.Message = "Kayıt işlemi sırasında hata oluştu!";
return View(model);
}
jQuery
<script>
// ajax call to bring district and city info dynamically according to the city value
$(function () {
$.ajaxSetup({
type: "post",
url: "/User/IlIlce",// target
dataType: "json"
});
$.extend({
ilGetir: function () {
$.ajax({
//sending data
data: { "tip": "ilGetir" },
success: function (sonuc) {
//check result if ok then append it to selectlist
if (sonuc.ok) {
$.each(sonuc.text, function (index, item) {
var optionhtml = '<option value="' + item.Value + '">' + item.Text + '</option>';
$("#il").append(optionhtml);
});
} else {
$.each(sonuc.text, function (index, item) {
var optionhtml = '<option value="' + item.Value + '">' + item.Text + '</option>';
$("#il").append(optionhtml);
$("body").append(optionhtml);
});
}
}
});
},
ilceGetir: function (cityID) {
$.ajax({
// then we get the districts with cityID
data: { "ilID": cityID, "tip": "ilceGetir" },
success: function (sonuc) {
// deleting records
$("#ilce option").remove();
if (sonuc.ok) {
// disabled to false
$("#ilce").prop("disabled", false);
$.each(sonuc.text, function (index, item) {
var optionhtml = '<option value="' + item.Value + '">' + item.Text + '</option>';
$("#ilce").append(optionhtml);
});
} else {
$.each(sonuc.text, function (index, item) {
var optionhtml = '<option value="' + item.Value + '">' + item.Text + '</option>';
$("#ilce").append(optionhtml);
});
}
}
});
}
});
// invoke ilGetir to get city values
$.ilGetir();
// on change in city value
$("#il").on("change", function () {
// we get the id of selected value
var cityID = $(this).val();
// and pass it to the ilceGetir function to get the districts
$.ilceGetir(cityID);
});
});
</script>
and the method that ajax call goes:
public JsonResult IlIlce(int? ilID, string tip)
{
db = new DatabaseContext();
List<SelectListItem> sonuc = new List<SelectListItem>();
bool isSuccessful = true;
try
{
switch (tip)
{
case "ilGetir":
// we assign the city values in db to sonuc(result) variable
foreach (var sehir in db.tblSehir.ToList())
{
sonuc.Add(new SelectListItem
{
Text = sehir.sehirAdi,
Value = sehir.sehirID.ToString()
});
}
break;
case "ilceGetir":
// we will fetch districts with sehirID(cityID)
foreach (var ilce in db.tblİlce.Where(il => il.bagliOlduguSehirID == ilID).ToList())
{
sonuc.Add(new SelectListItem
{
Text = ilce.ilceAdi,
Value = ilce.ilceID.ToString()
});
}
break;
default:
break;
}
}
catch (Exception e)
{
// if we encounter an error
isSuccessful = false;
sonuc = new List<SelectListItem>();
sonuc.Add(new SelectListItem
{
Text = e.Message,
Value = "Default"
});
}
// i return the results as json
return Json(new { ok = isSuccessful, text = sonuc });
}
ilce means: district
sehir/il both means: city
sifre: password
kullaniciAdi: username
telefon: phone number
ulke: country
ilGetir : fetch city
ilceGetir: fetch district
kullanici: user
adres: address
sonuc: result
tip: type
I want to auto-populate a textbox based on dropdown selection in MVC, using jquery, razor view and controller, from a model called Supplier, that has SupplierID, and Company_Registration_Number as variables. I have managed to do it as cascade dropdown, but i'm failingto populate #Html.EditorFor.
My controller :
public JsonResult GetCompanyRegistrationNumberId(int id)
{
var suppliers = db.Suppliers.Where(p => p.SupplierID == id).ToList();
var result = (from r in suppliers
select new
{
id = r.SupplierID,
name = r.Company_Registration_Number
}).ToList();
return Json(result, JsonRequestBehavior.AllowGet);
}
My JQuery:
$(function () {
if ($("#SupplierID").val() == '0') {
var productDefaultValue = "<option value='0'>--Select a category first--</option>";
$("#Company_Registration_Number").html(productDefaultValue).show();
}
$("#SupplierID").change(function () {
var selectedItemValue = $(this).val();
alert("cert");
var ddlProducts = $("#Company_Registration_Number");
$.ajax({
cache: false,
type: "GET",
url: '#Url.Action("GetCompanyRegistrationNumberId", "Order")',
data: { "id": selectedItemValue },
success: function (data) {
ddlProducts.html('');
$.each(data, function (id, option) {
ddlProducts.append($('<option></option>').val(option.id).html(option.name));
});
},
error: function (xhr, ajaxOptions, thrownError) {
alert('Found error to load product!!.');
}
});
});
});
My Razor view:
<div class="form-group">
#Html.LabelFor(model => model.Company_Registration_Number, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Company_Registration_Number, new { #id = "Company_Registration_Number" })
#Html.ValidationMessageFor(model => model.Company_Registration_Number, "", new { #class = "text-danger" })
</div>
</div>
Thanks in advance.
I'm trying to populate a dropdown list with concatenated items to be used in a form . I have gotten the dropdown list to display those concatenated strings but I think it's failing to get an ID. (I'can't submit the form, dropdown blinks when I click submit), I take it this means no ID is being passed
Controller:
public ActionResult AdminCreate()
{
var query = (from e in db.Employees
select e.FullName + "-" + e.EmployeeID + "-" + e.Site.SiteName);
SelectList empList = new SelectList(query);
ViewBag.empList = empList;
return View();
}
View:
<div class="form-group">
#Html.LabelFor(model => model.EmployeeID, "Employee", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor((model => model.Employee.EmployeeID), (SelectList)ViewBag.empList, "--Select--", htmlAttributes: new { #class = "form-control"})
#Html.ValidationMessageFor(model => model.EmployeeID, "", new { #class = "text-danger" })
</div>
</div>
Make your query and SelecList as follows:
var employeeList = db.Employees.Select(e => new
{
e.EmployeeID
FullName = e.FullName + "-" + e.EmployeeID + "-" + e.Site.SiteName
}).ToList()
SelectList empList = new SelectList(employeeList,"EmployeeID","FullName");
In your #Html.DropDownListFor replace model.Employee.EmployeeID with model.EmployeeID as follows:
#Html.DropDownListFor(model => model.EmployeeID, (SelectList)ViewBag.empList, "--Select--", htmlAttributes: new { #class = "form-control"})
I have a pair of cascading drop down lists for Type & Sub Type. These work perfectly when testing in debug mode locally but once I publish to IIS the sub type list doesnt populate and is blank. I dont get any error messages.
I have tried this in IE9 & also Google Chrome V46 but get the same result.
The controllers are:
public ViewResult StartRA()
{
var user = User.Identity.Name;
string userName = user.Substring(7);
var creator = Peopledb.People.FirstOrDefault(x => x.Username == userName);
var creatorContractId = (int)Session["LoggedContractId"];
StartRiskAssessmentViewModel viewModel = new StartRiskAssessmentViewModel
{
RiskAssessment = new RiskAssessment(),
CreatorId = creator.PersonId,
CreatorContractId = creatorContractId,
Assessor = creator.FirstName + " " + creator.LastName,
Locations = Peopledb.Locations.Where(x => x.Dormant == false).OrderBy(x => x.LocationName).ToList(),
Types = db.Types.Where(x => x.Dormant == false).ToList(),
};
return View(viewModel);
}
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult SubTypeList(int typeId)
{
var subTypes = db.SubTypes.Where(x => x.Dormant == false && x.TypeId == typeId).ToList();
if (HttpContext.Request.IsAjaxRequest())
return Json(new SelectList(
subTypes,
"SubTypeId",
"SubTypeName"), JsonRequestBehavior.AllowGet
);
return View(subTypes);
}
And the Razor view is:
#model RACentral.ViewModels.StartRiskAssessmentViewModel
#{
ViewBag.Title = "Start RA";
}
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<h3 class="col-md-offset-2">Type</h3>
<div class="form-group">
#Html.LabelFor(model => model.TypeId, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.TypeId, new SelectList(Model.Types, "TypeId", "TypeName", 0), "Please Select", new { #class = "form-control", #id = "Types" })
#Html.ValidationMessageFor(model => model.TypeId, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.SubTypeId, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
<select id="SubTypes" name="SubTypeId" class="form-control"></select>
#Html.ValidationMessageFor(model => model.SubTypeId, "", new { #class = "text-danger" })
</div>
</div>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-primary" /> #Html.ActionLink("Cancel", "IndexLoggedIn", "Home", null, new { #Class = "btn btn-danger" })
</div>
</div>
</div>
}
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
<script type="text/javascript">
$(function () {
$("#Types").change(function () {
$.getJSON('#Url.Action("SubTypeList","RiskAssessment")' {
var items = "<option>Please Select</option>";
$.each(data, function (i, subtype) {
items += "<option value='" + subtype.Value + "'>" + subtype.Text + "</option>";
});
$("#SubTypes").html(items);
});
});
</script>
}
You can do this using $.ajax and it might be easier for you to see what's happening
$(function () {
$("#Types").change(function () {
$.ajax({
type: "get", // can change to post easily
data: {typeId: $(this).val()}, // or this.value
url: "#Url.Action("SubTypeList", "RiskAssessment")" // use url helper here
}).done(function (data) {
var items = "<option>Please Select</option>";
$.each(data, function (i, subtype) {
items += "<option value='" + subtype.Value + "'>" + subtype.Text + "</option>";
});
$("#SubTypes").html(items);
});
});
});
using the url helper in your code was the right direction, you just needed to include your params also.
$.getJSON(
"#Url.Action("SubTypeList", "RiskAssessment")",
{ typeId: $(this).val() })
.done(function (data) {
var items = "<option>Please Select</option>";
$.each(data, function (i, subtype) {
items += "<option value='" + subtype.Value + "'>" + subtype.Text + "</option>";
});
$("#SubTypes").html(items);
});