#c# #razor #drop-down-menu #asp.net-core-mvc
Вопрос:
Я должен сделать выпадающий список с названиями пластин и из-за выбранного имени показать все подтипы этой пластины. Это выглядит так в коде:
Загородный Класс:
public class Country
{
public List<Plate> plates { get; set; }
public string name { get; set; }
public Country(string jsonRead)
{
plates = JsonConvert.DeserializeObject<List<Plate>>(jsonRead);
}
public IEnumerable<Plate> getAllPlates()
{
return plates.OrderBy(r => r.type);
}
}
Класс пластин:
public class Plate
{
public string type { get; set; }
public List<Subtype> subtypes { get; set; }
public Plate()
{
subtypes = new List<Subtype>();
}
}
Класс подтипа:
public class Subtype
{
public string subtypeName { get; set; }
public string color { get; set; }
public Subtype(string subtype, string color)
{
this.subtypeName = subtype;
this.color = color;
}
}
В контроллере у меня есть поле CountryData
. В нем есть информация обо всех таблицах (я прочитал ее из файла) и функция для просмотра, где я хочу иметь эти 2 раскрывающихся списка:
[Route("Home/CreatePlate/{name}")]
public IActionResult CreatePlate(string name)
{
var model = countryData.GetCountry(name);
return View(model);
}
И, наконец CreatePlate.cshtml
, посмотреть:
@model Generator.Country
@{
ViewData["Title"] = "CreatePlate";
}
<h1>CreatePlate</h1>
<div>
<h4>Country</h4>
<hr />
<dl class="row">
<dt class="col-sm-2">
<select id="Plate" name="Plate" onchange="this.form.submit()">
@if (Model.plates != null)
{
foreach (var Title in Model.plates)
{
<option value="@Title.type">@Title.type</option>
}
}
</select>
<select id="Subtype" name="Subtype" onchange="this.form.submit()">
@if (Model.plates != null)
{
foreach (var Title in Model.plates.Select(r => r))
{
foreach (var subtype in Title.subtypes)
{
<option value="@subtype.subtypeName">@subtype.subtypeName</option>
}
}
}
</select>
</dt>
<dd class = "col-sm-10">
</dd>
</dl>
</div>
На данный момент я показываю все таблички в первом списке, но во втором я получаю ВСЕ подтипы вместо того, что выбрано в первом раскрывающемся списке.
Я видел несколько решений на Stackoverflow, но все они нуждаются в JS (я не знаю этого языка), а также немного отличаются от моей проблемы.
Это мой 1 — й проект в ASP.NET Основной MVC.
Комментарии:
1. Вам нужно подключиться к событию изменения в первом выпадающем списке. JS и jQuery-это варианты.
2.
this.form.submit()
— Я нигде не вижу<form>
. Действительно ли страница публикует что-либо на сервере, когда вы выбираете опцию в первом<select>
? Если да, то какое действие он публикует и где в этом действии вы фильтруете значения для второго<select>
? (В стороне… «без JS» —this.form.submit()
это JavaScript. Если вы собираетесь заниматься какой-либо веб-разработкой, изучение JavaScript будет очень полезно. Попытка избежать этого, но также и использование этого в любом случае и просто непонимание этого затруднят ваше развитие.)3. Я предполагаю, что это должна быть Страна , а не «страна» ….
4. 1. Я видел это решение, но, как я уже сказал, я хотел бы избежать JS и jQuery. Я ничего не могу в этом написать. 2.Я скопировал-вставил это из другого решения в стеке и изменил на свою проблему, чтобы отобразить список. Я знаю это, но в данном случае у меня нет времени изучать JS. Мне не нравится веб-разработка. Может быть, позже я коснусь JS. 3. Да, опечатка. Я изменюсь!
Ответ №1:
Невозможно избежать использования JS. Если вы не хотите изучать JS, по крайней мере, используйте this.form.submit()
.
Вот целая рабочая демонстрация:
Модель:
public class Plate
{
public string type { get; set; }
public List<Subtype> subtypes { get; set; }
public Plate()
{
subtypes = new List<Subtype>();
}
}
public class Subtype
{
public string subtypeName { get; set; }
public string color { get; set; }
public Subtype(string subtype, string color)
{
this.subtypeName = subtype;
this.color = color;
}
}
public class Country
{
public List<Plate> plates { get; set; }
public string name { get; set; }
}
Вид:
@model Country
@{
ViewData["Title"] = "CreatePlate";
}
<h1>CreatePlate</h1>
<form>
<div>
<h4>Country</h4>
<hr />
<dl class="row">
<dt class="col-sm-2">
<select id="Plate" name="Plate" onchange="this.form.submit()">
@if (Model.plates != null)
{
foreach (var Title in Model.plates)
{
<option value="@Title.type" selected="@(ViewBag.SelectedIndex==Title.type?"selected":null)" >@Title.type</option>
}
}
</select>
<select id="Subtype" name="Subtype">
@if (Model.plates != null)
{
foreach (var Title in Model.plates.Select(r => r))
{
foreach (var subtype in Title.subtypes)
{
<option value="@subtype.subtypeName">@subtype.subtypeName</option>
}
}
}
</select>
</dt>
<dd class="col-sm-10">
</dd>
</dl>
</div>
</form>
Контроллер:
public class HomeController : Controller
{
//hard coded the data
List<Country> country = new List<Country>()
{
new Country(){
name="aa",
plates= new List<Plate>()
{
new Plate(){type="p1",subtypes=new List<Subtype>(){new Subtype("sub1","red"),new Subtype("sub2","yellow")}},
new Plate(){type="p2",subtypes=new List<Subtype>(){new Subtype("sub3","green"),new Subtype("sub4","blue")}},
new Plate(){type="p3",subtypes=new List<Subtype>(){new Subtype("sub5","gray")}}
}
}
};
[Route("Home/CreatePlate/{name}")]
public IActionResult CreatePlate(string name, string Plate)
{
ViewBag.SelectedIndex = "p1";
//get all the data of three tables
var model = country.Where(a=>a.name==name).FirstOrDefault();
if (Plate != null)
{
model.plates.Where(a => a.type != Plate).Select(a => a.subtypes).ToList().ForEach(a => a.Clear());
ViewBag.SelectedIndex = Plate; //used to keep the selected item
return View(model);
}
model.plates.ForEach(a => a.subtypes.Clear());
return View(model);
}
}
Комментарии:
1. Я уже проработал это с другом 🙂 Но спасибо тебе!
Ответ №2:
Простой ответ — «Нет». Вы не можете сделать это без использования JS. Если вы занимаетесь веб-разработкой. JS-это в значительной степени основное требование!
Итак, решение… Изучайте JS. Вы знаете C#. Синтаксис тот же самый. Или найдите JS, который почти выполняет эту работу (он доступен), и измените его.