Каскадное раскрывающееся меню отбрасывает «Пожалуйста, выберите»

Наконец-то у меня правильно работает пара каскадных выпадающих списков. К сожалению, при выборе элемента в первом загружается второй и сразу же отбрасывается нулевое значение «Пожалуйста, выберите». Я нашел, как вставить SelectListItem с Text="Please Select", Value="0", но не решаюсь это сделать. Если возможно, я хотел бы использовать встроенное нулевое значение.

У меня есть все это в автоматически сгенерированном наборе контроллеров и представлений, и в настоящее время я работаю над страницей «Создать».

Контроллер:

// GET: Books/Create
    public ActionResult Create()
    {
        ViewBag.AuthorID = new SelectList(db.Authors, "AuthorID", "AuthorName");
        //ViewBag.SeriesID = new SelectList(db.Series, "SeriesID", "SeriesName");
        ViewBag.SeriesID = new SelectList(db.Series.Where(v => v.SeriesID == 0), "SeriesID", "SeriesName");
        return View();
    }

    // POST: Books/Create
    // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
    // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create([Bind(Include = "BookID,BookName,AuthorID,SeriesID")] Book book)
    {
        if (ModelState.IsValid)
        {
            db.Books.Add(book);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        ViewBag.AuthorID = new SelectList(db.Authors, "AuthorID", "AuthorName", book.AuthorID);
        ViewBag.SeriesID = new SelectList(db.Series, "SeriesID", "SeriesName", book.SeriesID);
        return View(book);
    }

    public JsonResult GetSeries(int id)
    {
        SelectList list = new SelectList(db.Series.Where(v => v.AuthorID == id), "SeriesID", "SeriesName");

        return Json(new SelectList(db.Series.Where(v => v.AuthorID == id), "SeriesID", "SeriesName"));
    }

Просмотр:

    <script type="text/javascript">
    $(document).ready(function () {
        //Dropdownlist Selectedchange event
        $("#AuthorID").change(function () {
            $("#SeriesID").empty();
            $.ajax({
                type: 'POST',
                url: '@Url.Action("GetSeries")', // calling json method
                dataType: 'json',
                data: { id: $("#AuthorID").val() },
                success: function (series) {
                    // contains the JSON formatted list passed from the controller
                    $.each(series, function (i, ser) {
                        $("#SeriesID").append('<option value="' + ser.Value + '">' + ser.Text + '</option>');
                    }); // adding option
                },
                error: function (ex) {
                    alert('Failed to retrieve series.' + ex);
                }
            });
            return false;
        })
    });
    </script>
    @using (Html.BeginForm())
    {
    @Html.AntiForgeryToken()

    <div class="form-horizontal">
        <h4>Book</h4>
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        <div class="form-group">
            @Html.LabelFor(model => model.BookName, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.BookName, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.BookName, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.AuthorID, "Author", htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.DropDownList("AuthorID", null, "Please Select", htmlAttributes: new { @class = "form-control" })
                @Html.ValidationMessageFor(model => model.AuthorID, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.SeriesID, "Series", htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.DropDownList("SeriesID", null, "Please Select", htmlAttributes: new { @class = "form-control" })
                @Html.ValidationMessageFor(model => model.SeriesID, "", 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>
    }

Чего бы это ни стоило, я также пытался выяснить каскадные раскрывающиеся списки следующим образом, но так и не заработал. Я думал, что, возможно, следуя формату, используемому в методе «public ActionResult Create()», я смогу обойти потерю нулевого значения.

Я также подумал попробовать скрестить их; вызовите метод контроллера через Json и загрузите через ViewBag, но мое понимание методов, по-видимому, недостаточно развито, чтобы осуществить это (если это возможно).

Сбой контроллера:

[HttpPost]
[ActionName("GetSeries")]
public ActionResult GetSeries(int id)
{
    ViewBag.SeriesID = new SelectList(db.Series.Where(v => v.AuthorID == id), "SeriesID", "SeriesName");
    return View();
}

Отказ просмотра:

@using (Html.BeginForm("GetSeries", "Books", FormMethod.Post, new { id = "0" })) 
{
    <div class="form-group">
        @Html.LabelFor(model => model.AuthorID, "Author", htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.DropDownList("AuthorID", null, "Please Select",
              htmlAttributes: new
              {
                  @class = "form-control",
                  onchange = "$('#AuthorID').submit()", 
                  name = "action:GetSeries" })
            @Html.ValidationMessageFor(model => model.AuthorID, "", new { @class = "text-danger" })
        </div>
    </div>
}

@using (Html.BeginForm()
{
     // All the other stuff from the view here.
}

person bookwyrmk    schedule 28.10.2014    source источник


Ответы (1)


Вам нужно создать его в функции ajax (вызов empty очищает все параметры, поэтому вам нужно добавить его обратно). Обратите также внимание, что здесь нет встроенного нулевого значения! Параметр «Выберите», добавленный помощником html, когда вы используете перегрузку, которая принимает optionLabel, и вы используете ajax для повторного заполнения раскрывающегося списка, а не помощника html.

$("#AuthorID").change(function () {
  $("#SeriesID").empty().append($('<option></option>').text('Please select'));
  ...

Обратите внимание: вам не нужно создавать список выбора в методе GetSeries() (это просто ненужные накладные расходы)

public JsonResult GetSeries(int id)
{
  var data = db.Series.Where(v => v.AuthorID == id).Select(s => new
  {
    Value = s.SeriesID,
    Text = s.SeriesName
  }
    return Json(data));
}
person Community    schedule 28.10.2014
comment
Спасибо за исправление моего словоблудия; был не совсем уверен, как это назвать. Так что append() прекрасно работает. Но мои данные теперь отображаются как «неопределенные». Пустой() стирает что-то еще, что мне нужно добавить обратно? Кроме того, выбрасывает ли empty() буквально все, кроме идентификатора? - person bookwyrmk; 29.10.2014
comment
Нет, проблема в коде контроллера. Он не возвращал действительные данные (я обновил его - использовал двоеточие вместо запятой - ааа). Если это не работает, проверьте, что это работает, используя ваш исходный код. Если это работает, отладьте код, который я предоставил выше, чтобы увидеть, есть ли какие-либо другие ошибки. - person ; 29.10.2014
comment
Я уже заметил это и дополнительное ) в операторе return. Не исправил это, и я попробовал это с моим исходным кодом - без костей. - person bookwyrmk; 29.10.2014
comment
Ха, нашел! в javascript View у меня был «series.Text», и он должен быть «ser.Text». Огромное спасибо! - person bookwyrmk; 29.10.2014