Сделайте выпадающий список зависимым от другого выпадающего списка в ASP.NET Основной MVC без JS

#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, который почти выполняет эту работу (он доступен), и измените его.