Получить ID из всех отмеченных флажков - PullRequest
0 голосов
/ 12 февраля 2020

На странице в приложении Razor MVC из модели написано несколько строк, например:

@foreach (var item in Model)
    {
    // write lots of data
    @Html.CheckBoxFor(item.Id) // incorrect syntax, I know
    }
<input type="button" value="Update" onclick="Update();" />

javascript, запускаемый с кнопки, должен получить item.Id (который является уникальным целым числом) из каждого отмеченного флажка, помещает идентификаторы в массив и передает массив другой функции. Это то, с чем я работаю до сих пор:

function Update() {
    var ids = document.getElementsByName("myCheckbox");
    var idList = new Array(ids.length);
    for (var i = 0; i < ids.length; i++) {
        if (ids[i].checked {
        idList.push(ids[i]);
        }
    }
    $.ajax({
        type: "POST",
        url: "@Url.Action("Update", "Home")",
        data: idList,
        success: function (data) {
        },
        error: function (data) {
            console.log(data);
        }
    });
}

Как мне добавить одно и то же имя ко всем флажкам и сделать их идентификатором item.Id?

Редактировать

Я попытался C предложить Мерфи, сделав класс для флажков:

    public class ToBeUpdated
    {
        public int ID { get; set; }
        public bool IsSelected { get; set; }
    }

И затем добавить список в класс, который в модели:

        public List<ToBeUpdated> ToBeUpdatedList { get; set; }

Однако я не могу понять, как написать CheckBoxFor. Его / ее предложение было:

@Html.CheckboxFor(modelItem => modelItem.SomeNameList[i].IsSelected)

Но я делаю не для l oop, а для foreach:

foreach (var item in Model)

Поэтому мне пришлось сделать это вместо:

@Html.CheckBoxFor(modelItem => item.ToBeUpdatedList.Find(m => m.ID == item.Id).IsSelected)

Тогда у меня есть кнопка, которая отправляет меня к функции в моем контроллере:

<input type="button" value="Update" onclick="location.href='@Url.Action("UpdateStatuses", "Home")'" />

        public IActionResult UpdateStatuses(IEnumerable<FileData> model)
        {
            // iterate through the items in the model
        }

Проблема в том, что когда я попадаю в UpdateStatuses, модель пуста, хотя у меня была тонна флажков, которые я проверил перед нажатием кнопки. Модель в представлении имеет вид

@model IEnumerable<MyData>

И MyData - это простой класс:

    public class MyData
    {
        public int Id { get; set; }
        public List<ToBeUpdated> ToBeUpdatedList { get; set; }
    }

Редактировать 2: Наконец-то найдено решение

Я сделал свои флажки так:

<input type="checkbox" name="chkUpdateThis" id="@item.Id" />

И затем я мог, с помощью кода TJ, отредактировать мой javascript, чтобы сделать это:

    function UpdateStatuses() {
        const ids = [...document.querySelectorAll("[name=chkUpdateThis]")].filter(({checked}) => checked).map(({id}) => id)
        var idList = new Array();
        for (var i = 0; i < ids.length; i++) {
            idList.push(parseInt(ids[i]));
        }
        $.ajax({
            type: "POST",
            url: "@Url.Action("UpdateStatuses", "Home")",
            data: ({ ids: idList }),
            success: function (data) {
            },
            error: function (data) {
                console.log(data);
            }
        });
    }

Тогда я могу позвонить функция UpdateStatuses в моем контроллере Home:

public IActionResult UpdateStatuses(List<int> ids)

Так как TJ не опубликовал предложение, чтобы я мог поставить флажок, я передам его C Мерфи, который также был полезным. Я не воспользовался его предложением, но я не хочу ставить себе флажок, хотя решение, которое я выбрал, здесь.

Ответы [ 2 ]

2 голосов
/ 12 февраля 2020
@Html.CheckBoxFor(model => model.Id, new { Name = "myCheckbox" })
1 голос
/ 12 февраля 2020

По аналогии с комментарием Hereti c Обезьяна, вам, вероятно, следует создать класс. Не зная, что ваш Update ActionResult делает в вашем контроллере, я не могу дать вам полный ответ, но вы могли бы следовать этой общей структуре:

Модель:

public class SomeNameViewModel
{
     public List<SomeName> SomeNameList { get; set; }
}

public class SomeName
{
     public int Id { get; set; }
     public bool IsSelected { get; set; }
}

Вид:

@model ProjectName.Models.SomeNameViewModel

@for (var i = 0; i < Model.Count(); i++)
{
     <table>
          <tr>
               <td>@Html.HiddenFor(modelItem => modelItem.SomeNameList[i].Id)</td>
               <td>@Html.CheckboxFor(modelItem => modelItem.SomeNameList[i].IsSelected)</td>
          </tr>
     </table>                  
}

Редактировать (из-за информации, предоставленной в комментарии):

(заметьте, я также настроил предыдущий раздел, чтобы использовать ViewModel вместо списка нового класса )

Затем вы должны настроить свой ActionResult таким образом, чтобы вместо этого принять класс ViewModel в качестве аргумента и выполнить обновление базы данных следующим образом:

Контроллер:

public ActionResult Update(SomeNameViewModel viewModel)
{
     List<int> selectedIds = new List<int>();

     foreach(var row in viewModel.SomeNameList)
     {
          if(row.IsSelected == true)
          {
               selectedIds.Add(row.Id);
          }
          else
          {
               // wasn't selected, so do nothing
          }
     }

     // Now you have a list of Ids (selectedIds) that were selected 
     // and can then be passed to your other function
}

Второе редактирование:

Я думаю, что все еще существует некоторая путаница вокруг требований бизнеса относительно того, что вы пытаетесь выполнить sh.

Причиной ошибки было то, что я предположил, что вы передавать эти идентификаторы (в виде класса модели представления ToBeUpdated) в ActionResult вместо передачи IEnumerable<FileData>. Вот почему он пуст, когда достигает вашего контроллера. Структура MVC (Model View Controller) требует передачи информации в виде модели (класса) в контроллер из представления (и наоборот).

Пожалуйста, предоставьте полный список моделей вместе с более подробным объяснением того, чего вы пытаетесь достичь и почему.

Причина, по которой я использовал a для l oop вместо foreach l oop, состоит в том, чтобы убедиться, что список сериализован с уникальным индексы для каждого элемента в списке. Единственная причина, по которой вам нужно использовать флажки, - это определить, какие идентификаторы должны быть обновлены. Логика c для определения того, что будет обновляться, должна использоваться на стороне контроллера. Думайте о флажке как о поле ввода для логического (true / false, 0/1) свойства. Цель уникального идентификатора - всего , чтобы идентифицировать ваши уникальные записи данных. Логическое значение (поле флажка на стороне просмотра) просто для того, чтобы ваш конечный пользователь определил указанные c записи, которые необходимо обновить. Независимо от вашей модели, вы должны добавить логическое свойство (как я дал как пример) чтобы пользователь определил, какие записи обновлять, и вызовите команду SQL update с вашего контроллера ONLY для записей из вашего списка / IEnumerable, которые имеют значение true для вашего IsSelected свойство.

...