JavaScript для получения пользовательского ввода из редактируемой ячейки таблицы и отправки на сервер через json

#ajax

#ajax

Вопрос:

Я создал таблицу с пятью столбцами динамически. Два (второй и третий столбцы) из пяти столбцов должны быть доступны для редактирования на лету. Каждый раз, когда пользователь нажимает на одну из редактируемых ячеек таблицы, JavaScript должен перехватывать пользовательский ввод и отправлять данные на сервер в формате json. У меня проблема с перехватом пользовательского ввода и отправкой на сервер. Пожалуйста, помогите. Это мой пример кода —

 <!DOCTYPE html>
<html>
<head>
  <title>Editable table</title> 
    <style type="text/css" title="currentStyle">        
        @import "css/table.css"; 
    </style>
    <script type="text/javascript" language="javascript" src="js/jquery.js"></script>   

</head>
<body id="dt_example">
    <div id="container">
        <div class="full_width big">
                Data table<br />                
        </div>

    <div class="editab">
        <table border="1">
            <thead>
                <tr>
                    <th>Contract Number</th>
                    <th>Current Status</th>                     
                    <th>Sale Balance Amount</th>
                    <th>Interest Rate</th>
                    <th>Discount</th>
                </tr>
            </thead>
            <tbody>
                <tr>                
                    <td>00123</td>
                    <td onClick="editTableCell(this)">A30</td>
                    <td onClick="editTableCell(this)">$1,500.00</td>
                    <td>3.99 %</td>
                    <td>140</td>
                </tr>
                <tr>                
                    <td>00234</td>
                    <td onClick="editTableCell(this)">B20</td>
                    <td onClick="editTableCell(this)">$2,500.00</td>
                    <td>3.99 %</td>
                    <td>160</td>
                </tr>
                <tr>                
                    <td>00345</td>
                    <td onClick="editTableCell(this)">C40</td>
                    <td onClick="editTableCell(this)">$3,500.00</td>
                    <td>3.99 %</td>
                    <td>180</td>
                </tr>
                <tr>                
                    <td>00456</td>
                    <td onClick="editTableCell(this)">A20</td>
                    <td onClick="editTableCell(this)">$4,500.00</td>
                    <td>3.99 %</td>
                    <td>200</td>
                </tr>
                <tr>                
                    <td>00567</td>
                    <td onClick="editTableCell(this)">B30</td>
                    <td onClick="editTableCell(this)">$5,500.00</td>
                    <td>3.99 %</td>
                    <td>225</td>
                </tr>
                <tr>                
                    <td>00678</td>
                    <td onClick="editTableCell(this)">C10</td>
                    <td onClick="editTableCell(this)">$6,500.00</td>
                    <td>3.99 %</td>
                    <td>250</td>
                </tr>
                <tr>                
                    <td>00789</td>
                    <td onClick="editTableCell(this)">A30</td>
                    <td onClick="editTableCell(this)">$7,500.00</td>
                    <td>3.99 %</td>
                    <td>300</td>
                </tr>                   
            </tbody>
        </table>
    </div>

</div>
<script type="text/javascript">
    var SelectState = false;
    var SelectedElement = null;
    var TextInput = null;
    var CellText = null;
    var txt     = "test";
    var idcount  = 0;

    function editTableCell( e ){

      if ( SelectState == false ){

        SelectedElement = e;
        CellText = e.innerHTML;     
        e.innerHTML = "";

        var objInput = document.createElement("input");
        objInput.type = 'text';
        objInput.value = CellText;
        objInput.id = "txt"   idcount  ;
        objInput.onkeypress = editTextBox;
        objInput.size = 15;

        TextInput = objInput;
        e.appendChild(objInput);

        SelectState = true;

      } else if (e != SelectedElement) {
        SelectedElement.innerHTML = CellText;
        SelectState = false;
      }
    }

    function editTextBox( e ){

      if (navigator.appName == "Microsoft Internet Explorer"){
        e = window.event;
        key = e.keyCode;
      }

      else if (navigator.appName == "Netscape"){
        key = e.which;
      }

      if ( key == 13 ){
        SelectedElement.innerHTML = TextInput.value;
        SelectState = false;
      }

      else if ( key == 27 ){
        SelectedElement.innerHTML = CellText;
        SelectState = false;
      }
    }   

/*      var attrName  = "":
    var attrValue = "";
    if ($('#test1')
    {
        attrName=  "editField01";
        attrValue = $(#test1).val();
    }
    if ($('#test2')
    {
        attrName=  "editField02";
        attrValue = $(#test2).val();
    }

    if ($('#test3')
    {
        attrName=  "editField03";
        attrValue = $(#test3).val();
    }

     var values = '{"'   attrName   '":'   attrValue   '}';
      $.ajax({
        url: serverUrl   "/abc/contract/"   poolId,
        async: false,
        type: "PUT",
        data: JSON.stringify(values),
        dataType: 'json',
        processData: false,
        contentType: 'application/json',
        success: showResponse(json) {
          // TODO: What info is returned in the data structure?
          showResponse;
        },
        error: function(err) {
          alert("Failed to update the attribute");
          htmlErrorDialog(err.responseText);
        }
      });*/

    function showResponse(json)  { 
      if(json.success){
        // handle successful response here
        alert("user input from column sent successfully!");
      } else {
        // handle unsuccessful response here
        alert("user input fail to send. Please try again");
      }
    } 
    </script>
</body>
</html>
  

Ответ №1:

На самом деле вы не передаете данные json в showResponse :

     success: showResponse(json) {
      // TODO: What info is returned in the data structure?
      showResponse;
    },
  

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

     success: function(json) {
      // check that json is an actual object via an alert
      // alert(json);
      showResponse(json);
    },
  

РЕДАКТИРОВАТЬ: Хорошо, после долгой работы у меня есть простой тестовый пример для создания полей, доступных для редактирования. Пожалуйста, обратите внимание, что он использует jquery, а комментарии являются встроенными:

 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"  "http://www.w3.org/TR/html4/strict.dtd">

<html lang="en">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Test</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js"></script>
    <!-- Date: 2011-05-10 -->
</head>
<body>
    <form>
    <table border="1">
        <thead>
            <tr>
                <th>Contract Number</th>
                <th>Current Status</th>                     
                <th>Sale Balance Amount</th>
                <th>Interest Rate</th>
                <th>Discount</th>
            </tr>
        </thead>
        <tbody>
            <tr>         
                <!-- The "identifier" class makes it so we have an id
                    to pass to our ajax script so we know what to change -->       
                <td class="identifier">00123</td>
                <td class="editable">A30</td>
                <td class="editable">$1,500.00</td>
                <td>3.99 %</td>
                <td>140</td>
            </tr>                   
        </tbody>
    </table>
    </form>     
    <script type="text/javascript">
        // bind our event handler to all td elements with class editable
        $('td.editable').bind('click', function() {
            // Only create an editable input if one doesn't exist
            if(!$(this).has('input').length) {
                // Get the text from the cell containing the value
                var value = $(this).html();
                // Create a new input element with the value of the cell text
                var input = $('<input/>', {
                    'type':'text',
                    'value':value,
                    // Give it an onchange handler so when the data is changed
                    // It will do the ajax call
                    change: function() {
                        var new_value = $(this).val();
                        // This finds the sibling td element with class identifier so we have
                        // an id to pass to the ajax call
                        var cell = $(this).parent();
                        // Get the position of the td cell...
                        var cell_index = $(this).parent().parent().children().index(cell);
                        // .. to find its corresponding header
                        var identifier = $('thead th:eq(' cell_index ')').html();
                        //ajax post with id and new value
                        $(this).replaceWith(new_value);
                    }
                });
                // Empty out the cell contents...
                $(this).empty();
                // ... and replace it with the input field that has the value populated
                $(this).append(input);
            }
        });
    </script>
</body>
  

Комментарии:

1. Спасибо, onteria. Почему-то всякий раз, когда я раскомментирую код из «var attrName = «»;» вкл., мой код для создания редактируемой ячейки таблицы не будет выполняться. Кроме того, я все еще не могу понять, как передать пользовательский ввод из любой редактируемой таблицы на сервер после того, как пользователь закончит вводить данные.

2. @C.L. Я обновил свой ответ небольшим тестовым примером, используя строку и jquery, чтобы сделать строки доступными для редактирования. Пожалуйста, проверьте код еще раз и посмотрите, поможет ли он вам понять, где работает вызов AJAX.

3. Спасибо, onteria. Ваш код отлично работает. Если мне нужно отправить введенные пользователем данные из редактируемой ячейки таблицы на сервер в формате json, имея заголовок столбца в качестве ключа и пользовательский ввод в качестве значения, чтобы данные можно было отправлять в формате {«Сумма баланса продажи»: «2000 долларов»} на обновляемый сервер, как изменить вызов ajax для этого?

4. @C.L. обновил код для этого. Пожалуйста, смотрите var identifier новое значение, которое использует соответствующую ячейку заголовка вместо.

5. onteria, огромное спасибо за помощь с действительно эффективным кодом и комментариями, которые объясняют, для чего предназначен каждый оператор. Код AJAX обновляет введенную пользователем ячейку таблицы ввода. При этом те же данные будут передаваться на сервер для обновления базы данных. Верно?