在“追加”之前和之后的表“添加”,“可编辑”

时间:2018-09-12 20:15:34

标签: javascript jquery html

我有此表数据被追加;但是,我想使其成为可以使用“文本”输入类型添加表数据并在添加表数据之前和之后使表数据“可编辑”的地方。

问题是附件会覆盖我之前添加的先前数据/值。我相信这样做是因为在准备好dom时已填充表格了?

我想使它类似于代码片段,但它没有那样做。

$(document).ready(function () {
var arr1 = generateItem();
if (arr1) {
    var arr2 = [].concat(arr1);
    var tr;
    $.each(arr2, function (i, e) {
        tr = $('<tr>');
        tr.append("<td>" + "<button id='modalBtn" + i + "' type='button' class='btn btn-info' data-toggle='modal' data-target='#myModal'>Info</button>" +
					"<button id='editBtn" + i + "' type='button' class='btn btn-default editBtn' data-target='#editBtn'>Edit</button>" + 
          "<button id='delete" + i + "' type='button' class='btn btn-danger deleteBtn' data-target='#deleteBtn' style='width:50px'>X</button>" + "</td>");
        tr.append("<td>" + (e.Name || "") + "</td>");
        tr.append("<td>" + (e.Email || "") + "</td>");
        tr.append("<td>" + (e.Phone || "") + "</td>");
        $('#parentTableBody').append(tr);

        populateSchoolInfo(i, e);
    });
}
$('#myModal').on('show.bs.modal', function (e) {
    var idx = $(e.relatedTarget).closest('tr').index();
    $('#schoolModalBody tr').hide().filter('[studentidx=' + idx + ']').show();
});
    $('.editBtn').on('click', function () {
            var currentTD = $(this).parents('tr').find('td');
            if ($(this).html() == 'Edit') {
                currentTD = $(this).parents('tr').find('td');
                $.each(currentTD, function () {
                    $(this).prop('contenteditable', true)
                });
            } else {
                $.each(currentTD, function () {
                    $(this).prop('contenteditable', false)
                });
            }
            
                        $(this).html($(this).html() == 'Edit' ? 'Save' : 'Edit')

        });
        
        $('.deleteBtn').on('click', function () {
            $(this).closest('tr').remove();
            return false;
            });
 $("#addBtn").click(function () {
     $("#parentTable").each(function () {
         var tds = '<tr>';
         jQuery.each($('tr:last td', this), function () {
             tds += '<td>' + $(this).html() + '</td>';
         });
         tds += '</tr>';
         if ($('tbody', this).length > 0) {
             $('tbody', this).append(tds);
         } else {
             $(this).append(tds);
         }
     });
});

            
});

function populateSchoolInfo(idx, kid) {
var tr;
$.each(kid.Edu, function (j, v) {
    tr = $('<tr>', {studentidx: idx});
    tr.append("<td>" + (v.School || "") + "</td>");
    tr.append("<td>" + (v.Grade || "") + "</td>");
    tr.append("<td>" + (v.Job || "") + "</td>");
    tr.append("<td>" + (v.Martial || "") + "</td>");
    tr.append("<td>" + (v.ETC || "") + "</td>");
    $('#schoolModalBody').append(tr);
    
});
}

function generateItem() {
var kids = [{
    Name: "Gina",
    Email: "gina@email.com",
    Phone: "211-456-1234",
    Edu: [{School: "college", Grade: "Freshmen", Job: "Student", Martial: "S", ETC: " "},
        {School: "college2", Grade: "Freshmen2", Job: "Student2", Martial: "S2", ETC: "2"},
        {School: "college3", Grade: "Freshmen3", Job: "Student3", Martial: "S3", ETC: "3"}]
    },
    {
        Name: "Mark",
        Email: "mark@email.com",
        Phone: "144-411-2312",
        Edu: [{School: "highschool", Grade: "senior", Job: "cashier", Martial: "S", ETC: "honors"}]
    },
    {
        Name: "Jake",
        Email: "jake@email.com",
        Phone: "333-211-1111",
        Edu: [{School: "highschool", Grade: "senior", Job: "cashier", Martial: "S", ETC: "honors"}]
    }
];
return kids;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>

<table id="parentTable">
    <thead>
    <tr class="category">
        <th></th>
        <th>Name</th>
        <th>Email</th>
        <th>Phone</th>
    </tr>
    </thead>
                        
    <tbody id="parentTableBody">
<td><button id='addBtn' type='button' class='btn btn-success' data-target='#addRow'>Add Row</button></td>
    <td><input type="text" class="form-control" name="name" id="name" placeholder="name"></td>
    <td><input type="text" class="form-control" name="email" id="email" placeholder="email"></td>
    <td><input type="text" class="form-control" name="phone" id="phone" placeholder="phone"></td>
    </tbody>
</table>

<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <div class="modal-body">
                <h3>Info</h3>

                <div class="well well-sm overflow-auto">
                    <table class="table table-striped table-hover table-condensed" id="schoolTable">
                        <thead>
                        <tr>
                            <th>School</th>
                            <th>Grade</th>
                            <th>Job</th>
                            <th>Martial</th>
                            <th>Etc</th>
                        </tr>
                        </thead>
                        <tbody id="schoolModalBody">
                        </tbody>
                    </table>
                </div>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-info" data-dismiss="modal">Close</button>
            </div>
        </div>
    </div>
</div>

2 个答案:

答案 0 :(得分:1)

这就是问题–为什么要创建一种完全不同的机制来添加行而不是表的初始填充?在功能上完全相同。

如果您查看addRow处理程序,实际上并没有从输入中获取数据-您似乎只是在克隆东西。

如果我们将创建表格行的HTML DOM片段的逻辑放入其自身的函数createRow()中,该怎么办?可以期望有一个索引和一个对象,并使用它们来填充行的单元格。然后,我们可以简单地将该行追加到#parentTableBody的末尾,然后将该对象完全添加到school集合中。

将代码提取到其自身功能中的好处是,当您创建新学生时,您将使用完全相同的功能!您将创建索引和学生对象,但随后将调用createRow(),然后追加该行,并将新的学生记录添加到学校。没有任何东西可以被克隆或重新添加-它只是在做与往常相同的事情。

这是我根据上述建议重构您的代码的方式,并注释了所有内容。我坚信评论,并使用console.log或某种调试器!

$(document).ready(function() {
  // create the original collection of student records.
  let arr1 = generateItem();
  if (arr1) {
    // clone that collection into a second array (?)
    let arr2 = [...arr1];
    // For each member of the student collection, create a table row.
    $.each(arr2, function(index, element) {
      // createRow() creates the DOM student row.
      let myRow = createRow(index, element);
      // Stick that row we just created into the parent table.
      $('#parentTableBody').append(myRow);
      // Add that student into the actual school info.
      populateSchoolInfo(index, element);
    });
  }

  $('#myModal').on('show.bs.modal', function(e) {
    var idx = $(e.relatedTarget).closest('tr').index();
    $('#schoolModalBody tr').hide().filter('[studentidx=' + idx + ']').show();
  });
  $("#parentTableBody").on('click', '.editBtn', function() {
    var currentTD = $(this).parents('tr').find('td');
    if ($(this).html() == 'Edit') {
      currentTD = $(this).parents('tr').find('td');
      $.each(currentTD, function() {
        $(this).prop('contenteditable', true)
      });
    } else {
      $.each(currentTD, function() {
        $(this).prop('contenteditable', false)
      });
    }

    $(this).html($(this).html() == 'Edit' ? 'Save' : 'Edit')

  });

  $("#parentTableBody").on('click', '.deleteBtn', function() {
    $(this).closest('tr').remove();
    return false;
  });
  /****
   * When the add button is clicked, we first create a new Student object.
   *  By doing this, we can then re-use the same createRow function we
   *  used when we created each initial row, thus ensuring the same result.
   ****/
  $("#addBtn").click(function() {
    // Get all the text input fields for this form.
    let inputs = $(this).parent().siblings().find("input[type='text']");
    // Create an empty student object.
    let myStudentObj = {};
    // Iterate over all the text inputs, and create properties for the student
    //  Each text input name will become the property name.
    inputs.each(function(index, input){
      /***
       * This is a complicated conversion: as the createRow has been defined to
       *  expect a Titlecase property (first letter is capitalized), but the input
       *  names are lower case, we need to retrieve the input name, convert it
       *  to all lowercase (just to be safe), then convert the first char to upper.
       ***/
      let propName = $(input).prop("name")
                             .toLowerCase();
      propName = propName.replace(propName[0], propName[0].toUpperCase());
      // Now, create a property on the object with the proper value.
      myStudentObj[propName] = $(input).val();
      // And let's also blank that input field, so we can create a new student easily.
      $(input).val("");
    });
    
    /***
     * A little more funkiness: the index is the object's position in an array, or list.
     *   As we have been adding the records sequentially, the number of rows is the index
     *   of the last row. Adding one to that will give us the index of the current student.
     ***/
    let myStudentIndex = $("#parentTableBody tr.student-row").length,
        
    // And we can create that DOM fragment, as we did when we initialized the list above.
        myRow = createRow(myStudentIndex, myStudentObj);
    // add our newly created DOM fragment to the parent container.
    $("#parentTableBody").append(myRow);
    
    // Add the student to the school collection itself.
    populateSchoolInfo(myStudentIndex, myStudentObj)
    

  });


});

function populateSchoolInfo(idx, kid) {
  var tr;
  $.each(kid.Edu, function(j, v) {
    tr = $('<tr>', {
      studentidx: idx
    });
    tr.append("<td>" + (v.School || "") + "</td>");
    tr.append("<td>" + (v.Grade || "") + "</td>");
    tr.append("<td>" + (v.Job || "") + "</td>");
    tr.append("<td>" + (v.Martial || "") + "</td>");
    tr.append("<td>" + (v.ETC || "") + "</td>");
    $('#schoolModalBody').append(tr);

  });
}

function generateItem() {
  var kids = [{
      Name: "Gina",
      Email: "gina@email.com",
      Phone: "211-456-1234",
      Edu: [{
          School: "college",
          Grade: "Freshmen",
          Job: "Student",
          Martial: "S",
          ETC: " "
        },
        {
          School: "college2",
          Grade: "Freshmen2",
          Job: "Student2",
          Martial: "S2",
          ETC: "2"
        },
        {
          School: "college3",
          Grade: "Freshmen3",
          Job: "Student3",
          Martial: "S3",
          ETC: "3"
        }
      ]
    },
    {
      Name: "Mark",
      Email: "mark@email.com",
      Phone: "144-411-2312",
      Edu: [{
        School: "highschool",
        Grade: "senior",
        Job: "cashier",
        Martial: "S",
        ETC: "honors"
      }]
    },
    {
      Name: "Jake",
      Email: "jake@email.com",
      Phone: "333-211-1111",
      Edu: [{
        School: "highschool",
        Grade: "senior",
        Job: "cashier",
        Martial: "S",
        ETC: "honors"
      }]
    }
  ];
  return kids;
}
/****
* createRow() -- create the student row DOM fragment.
* index = the student index
* obj = the student object, formatted like:
* obj = { Name: "name", Email: "email", Phone: "555-555-5555", <other optional fields>}
*
* returns a td DOM node containing the student info.
****/
function createRow(index, obj) {
  // console.log(obj);
  tr = $('<tr class="student-row">');
  tr.append("<td>" + "<button id='modalBtn" + index + "' type='button' class='btn btn-info' data-toggle='modal' data-target='#myModal'>Info</button>" +
    "<button id='editBtn" + index + "' type='button' class='btn btn-default editBtn' data-target='#editBtn'>Edit</button>" +
    "<button id='delete" + index + "' type='button' class='btn btn-danger deleteBtn' data-target='#deleteBtn' style='width:50px'>X</button>" + "</td>");
  tr.append("<td>" + (obj.Name || "") + "</td>");
  tr.append("<td>" + (obj.Email || "") + "</td>");
  tr.append("<td>" + (obj.Phone || "") + "</td>");

  return tr;
}
<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" />
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.bundle.min.js"></script>

<table id="parentTable">
  <thead>
    <tr class="category">
      <th></th>
      <th>Name</th>
      <th>Email</th>
      <th>Phone</th>
    </tr>
  </thead>

  <tbody id="parentTableBody">
    <td><button id='addBtn' type='button' class='btn btn-success' data-target='#addRow'>Add Row</button></td>
    <td><input type="text" class="form-control" name="name" id="name" placeholder="name"></td>
    <td><input type="text" class="form-control" name="email" id="email" placeholder="email"></td>
    <td><input type="text" class="form-control" name="phone" id="phone" placeholder="phone"></td>
  </tbody>
</table>

<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
  <div class="modal-dialog" role="document">
    <div class="modal-content">
      <div class="modal-body">
        <h3>Info</h3>

        <div class="well well-sm overflow-auto">
          <table class="table table-striped table-hover table-condensed" id="schoolTable">
            <thead>
              <tr>
                <th>School</th>
                <th>Grade</th>
                <th>Job</th>
                <th>Martial</th>
                <th>Etc</th>
              </tr>
            </thead>
            <tbody id="schoolModalBody">
            </tbody>
          </table>
        </div>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-info" data-dismiss="modal">Close</button>
      </div>
    </div>
  </div>
</div>

请注意,这没有任何有效性检查,它只是接受这三个字段的任何值并创建该Student对象。验证是整个“ NOTHER对话”。

答案 1 :(得分:0)

 $('.editBtn').on('click', function () {...

此代码在执行时会添加一个事件侦听器,之后添加的每个DOM元素均不会触发任何操作。

要使事情正常进行,您必须先听document上的事件,然后再听您想要的元素:

 $(document).on('click', '.editBtn', function () {...