Отправить измененную таблицу на контроллер в ASP. NET MVC? - PullRequest
1 голос
/ 18 апреля 2020

У меня есть таблица с данными в представлении ASP. NET MVC. Что я хочу сделать, так это чтобы пользователь мог изменять данные в таблице и нажимать кнопку для отправки нового данные к контроллеру. Мне нужно получить внутренние HTML данные, которые пользователь изменяет в таблице, и отправить эти данные через AJAX вызов метода контроллера.

Проблема заключается в том, что таблица динамически генерируется в представлении Razor, и для возможности получения внутреннего HTML тега мне нужно знать id элемента, который пользователь изменил. Поскольку он генерируется динамически, я не знаю этот идентификатор, поэтому я не могу просто использовать jQuery и извлекать данные из тегов HTML.

Единственное решение, которое, как я думал, будет работать, - это открыть новая страница с новой формулой, и пользователь сможет изменять данные там, но я бы не хотел использовать это решение для создания новой формул и перенаправления на другую страницу.

Еще одно решение, которое мне показалось было бы создать кнопку, которая при нажатии вызывает функцию Javascript, которая берет все внутренние данные HTML из таблицы и отправляет их обратно в контроллер. Затем контроллер проверяет каждую строку в базе данных и, если она изменяется, обновляет базу данных. Это было бы много работы, и я не знаю, будет ли это на самом деле работать.

Я добавил мнение, над которым я работаю здесь:

@using Models;
@using Newtonsoft.Json;

@{
    var lstBID = ViewBag.BIDList as IEnumerable<BID>;
    int[] j = lstBID.Select(id => id.Id).ToArray();
    string s = JsonConvert.SerializeObject(j);

}

@model Models.BID

<head>
  <script>
    var arr = @s;

    $(document).ready(function() {
      console.log(arr);

      var BID = {
        Id: $("#Id").html(),
        Price: $("#Price").html(),
        Quantity: $("#Quantity").html()
      }

      $("#bidupdate").click(function() {
        console.log("Hello")
        $.ajax({
          type: "POST",
          url: "/User/UpdateBID",
          data: BID,
          cache: false,
          async: true,
          dataType: "json",
          success: function(data) {
            alert(data);
          },
        });
      });

    });
  </script>
</head>
<html>

<body>
  <div style="width:100% ;padding-right:30%; float :left">
    <table id="verticalScroll" class="table-editable table table-light table-bordered table-sm" cellspacing="0">
      <thead class="thead-dark">
        <tr>
          <th>
            ID
          </th>
          <th>
            CompanyName
          </th>
          <th>
            Price
          </th>
          <th>
            Quantity
          </th>
        </tr>
      </thead>
      <tbody>

        @foreach (BID b in lstBID) {
          <tr>
            <td id="Id_@b.Id">
              @b.Id
            </td>
            <td>
              @b.CompanyName
            </td>
            <td id="Price_@b.Id" contenteditable="true">
              @b.Price
            </td>
            <td id="Quantity_@b.Id" contenteditable="true">
              @b.Quantity
            </td>
            <td>
              <button type="button" value="Details" class="btn btn-primary" id="@b.Id">Update</button>
            </td>
          </tr>
        }
      </tbody>
    </table>
  </div>
</body>
</html>

1 Ответ

1 голос
/ 18 апреля 2020

Вы не должны использовать id атрибуты в HTML, которые вы создаете в al oop. Это потому, что id атрибуты должны быть уникальными. Вместо этого используйте общие классы. Затем вы можете найти элементы, относящиеся к кнопке, на которую нажали, пройдя через DOM, чтобы найти ближайший общий tr и вызвав find() оттуда.

Обратите внимание, что если вы хотите, чтобы одна кнопка извлекала данные для всей таблицы, это можно сделать довольно просто с помощью map().

См. Пример обоих этих методов в приведенном ниже примере:

jQuery(function($) {
  $(".update-row").on('click', function() {
    let $row = $(this).closest('tr');
    let data = {
      id: $row.find('.id').text().trim(),
      companyName: $row.find('.companyname').text().trim(),
      price: $row.find('.price').text().trim(),
      quantity: $row.find('.quantity').text().trim(),
    }

    console.log(data);

    /* commented out only for this example, as it won't work in a snippet...
    $.ajax({
      type: "POST",
      url: "/User/UpdateBID",
      data: data,
      cache: false,
      dataType: "json",
      success: function(data) {
        console.log(data);
      }
    });
    */
  });

  $('.send-all').on('click', function() {
    let data = $('#verticalScroll tr').map(function() {
      let $row = $(this);
      return {
        id: $row.find('.id').text().trim(),
        companyName: $row.find('.companyname').text().trim(),
        price: $row.find('.price').text().trim(),
        quantity: $row.find('.quantity').text().trim(),
      }
    }).get();
    
    // send data in an AJAX request here... 
  });
});
div {
  width: 100%;
  padding-right: 30%;
  float: left;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
  <table id="verticalScroll" class="table-editable table table-light table-bordered table-sm" cellspacing="0">
    <thead class="thead-dark">
      <tr>
        <th>ID</th>
        <th>CompanyName</th>
        <th>Price</th>
        <th>Quantity</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td class="id">1</td>
        <td class="companyname">Foo bar</td>
        <td class="price" contenteditable="true">1.99</td>
        <td class="quantity" contenteditable="true">10</td>
        <td><button type="button" value="Details" class="btn btn-primary update-row">Update</button></td>
      </tr>
      <tr>
        <td class="id">2</td>
        <td class="companyname">Fizz buzz</td>
        <td class="price" contenteditable="true">10.50</td>
        <td class="quantity" contenteditable="true">2</td>
        <td><button type="button" value="Details" class="btn btn-primary update-row">Update</button></td>
      </tr>
    </tbody>
  </table>
</div>

<button class="send-all">Send all data</button>
...