首页 > 解决方案 > 当有人仅使用 PHP 和 HTML 在表单中输入内容时,如何创建新的表格行?

问题描述

嘿,每次有人在表单中输入内容时,我都会尝试创建一个新行。现在我只有在用户只能做一行的地方。每次有人输入内容时,它都会用新输入清除第一行,但我希望它在每次有人在表单中输入新内容时用新信息创建一个新行。

下面的 HTML 代码

<form id="form" method="post" action="toDoList.php">
                    <div class="form-row">
                          <div class="form-group col-md-4">
                            <label for="Date">Date</label>
                            <input type="date" name="Date"  class="form-control" id="Date" placeholder="MM/DD/YY">
                          </div>
                          <div class="form-group col-md-4">
                            <label for="To Do">To Do</label>
                            <input class="form-control" name="ToDo" id="To Do" placeholder="To Do">
                          </div>
                          <div class="form-group col-md-4">
                                <label for="Due On">Due On</label>
                                <input type="date"  class="form-control" name="DueOn" id="Due On" placeholder="MM/DD/YY">
                              </div>
                        <button type="submit" class="btn btn-primary text-right">Submit</button>
                    </div>
            </form>

下面的PHP代码

$toDo = $_POST["ToDo"];
$date = $_POST["Date"];
$dueOn = $_POST["DueOn"];

$newDate = date("m-d-Y", strtotime($date));
$newDate2 = date("m-d-Y", strtotime($dueOn));




        echo "<table  id='table' class='table table-bordered table-dark'>";
        echo "<thead>";
        echo "<tr>";
        echo "<th scope='col'>#</th>";
        echo "<th scope='col'>Date</th>";
        echo "<th scope='col'>To Do</th>";
        echo "<th scope='col'>Due On</th>";
        echo "<th scope='col'>Completed</th>";
        echo "</tr>";
        echo "</thead>";
        echo "<tbody>";
        echo "<tr>";
        echo "<th scope='row'>1</th>";
        echo "<td>";
        echo $newDate;
        echo "</td>";
        echo "<td> $toDo </td>";
        echo "<td> $newDate2  </td>";
        echo "<td>";
        echo "<div class='form-check'>";
        echo "<input class='form-check-input' type='radio' name='Completed' id='exampleRadios1' value='option0'>";
        echo "<label id='labelYes' class='form-check-label' for='exampleRadios1'>Yes</label>";
        echo "</div>";
        echo "</td>";
        echo "</tr>";

标签: phphtml

解决方案


如果没有数据库,仅 PHP 的解决方案将缺乏持久性。因此,第一个解决方案只有在浏览器不导航到另一个页面或关闭时才有效。

javascript 解决方案可以利用浏览器的本地存储功能。因此,javascript 解决方案从不将数据提交回服务器,而是与本地存储通信。

PHP 示例

使这项工作有效的是在输入中使用数组。例如,如果你有

Date      To Do   Due On
10/1/2019 Task 1  10/2/2019
10/1/2019 Task 2  10/3/2019

然后$_POST['row']看起来像这样:

$_POST = array (
  'row' => array(
    [0] => array(
      'date' => '10/1/2019',
      'todo' => 'Task 1',
      'duedate' => '10/2/2019'
      ),
    [1] => array(
      'date' => '10/1/2019',
      'todo' => 'Task 2',
      'duedate' => '10/3/2019'
      ),
    )
  )

示例脚本如下所示:

<?php
// always start with php, don't output any html until php stuff is all done.

// initialize variables
$tableRows = array();


// work with user input
if(isset($_POST['row'])) {

  // normally would save things to database, but
  // since there's no database, we'll just take the data and stuff it back into the page

  $row = $_POST['row'];    // for ease of typing
  settype($row, 'array');  // just to be sure it's an array

  foreach($row as $r) {

    // if the checkbox is not checked, add the submitted row to the new list
    if(!isset($r['completed'])) {

      $tableRows[] = $row;
    }
  }

  // normally would redirect to self or another page
  // header('Location: /');
}

// normally would do any other logic here


// now that PHP processing is finished, present the view (HTML)
?>
<html>
  <head>
    <title>ToDo List</title>
  </head>
  <body>
    <form method="post">
      <table  id="table" class="table table-bordered table-dark">
        <thead>
          <tr>
            <th scope="col">#</th>
            <th scope="col">Date</th>
            <th scope="col">To Do</th>
            <th scope="col">Due On</th>
            <th scope="col">Completed</th>
          </tr>
        </thead>
        <tbody>
          <?php foreach($tableRows as $index=>$row): ?>
          <tr>
            <th scope="row"><?= $index ?></th>
            <td><input type="text" name="row[<?=$index?>][date]"    value="<?= $row[$index]['date']  ?>"></td>
            <td><input type="text" name="row[<?=$index?>][todo]"    value="<?= $row[$index]['todo']     ?>"></td>
            <td><input type="text" name="row[<?=$index?>][duedate]" value="<?= $row[$index]['due date'] ?>"></td>
            <td>
              <div class="form-check">
                <input class="form-check-input" type="checkbox" name="row[<?=$index?>][completed]" id="completed-<?=$index?>" value="task_completed">
                <label id="labelYes" class="form-check-label" for="completed-<?=$index?>">Yes</label>
              </div>
            </td>
          </tr>
          <?php endforeach; ?>
        </tbody>
      </table>

      <div class="form-row">
      <div class="form-group col-md-4">
        <label for="Date">Date</label>
        <input type="date" name="row[][date]"  class="form-control" id="Date" placeholder="MM/DD/YY">
      </div>
      <div class="form-group col-md-4">
        <label for="To Do">To Do</label>
        <input class="form-control" name="row[][todo]" id="To Do" placeholder="To Do">
      </div>
      <div class="form-group col-md-4">
        <label for="Due On">Due On</label>
        <input type="date"  class="form-control" name="row[][duedate]" id="Due On" placeholder="MM/DD/YY">
      </div>
      <button type="submit" class="btn btn-primary text-right">Submit</button>
      </div>
    </form>
  </body>
</html>

Javascript 示例

我把它当作使用本地存储的挑战,因为我以前没有使用过它。我必须强调,SO 不是代码编写服务。然而,这个问题对我来说是一个挑战,所以我把它作为一个学习的机会。

<html>
  <head>
    <title>ToDo List</title>
    <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
  </head>
  <body>
    <div class="row"><div class="col-sm-12">
    <form method="post">
      <div>&nbsp;</div>
      <div class="form-row">
        <div class="form-group col-md-4">
          <label for="Date">Date</label>
          <input type="date" id="date-enter"  class="form-control" placeholder="MM/DD/YY" value="" required>
        </div>
        <div class="form-group col-md-4">
          <label for="To Do">To Do</label>
          <input class="form-control" id="todo-enter" placeholder="To Do" value="" required>
        </div>
        <div class="form-group col-md-4">
          <label for="Due On">Due On</label>
          <input type="date"  class="form-control" id="due-enter" placeholder="MM/DD/YY" value="" required>
        </div>
        <button type="submit" class="btn btn-primary text-right" id="add-row">Submit</button>
      </div>
      <div>&nbsp;</div>

      <table  id="table" class="table table-bordered table-dark">
        <thead>
          <tr>
            <th scope="col">#</th>
            <th scope="col">Date</th>
            <th scope="col">To Do</th>
            <th scope="col">Due On</th>
            <th scope="col">Completed</th>
          </tr>
        </thead>
        <tbody id="table-tbody">
        <script type="text/template" data-template="table-template">
          <tr>
            <th scope="row">${index}</th>
            <td>${date}</td>
            <td>${todo}</td>
            <td>${due}</td>
            <td>
              <!-- 
                <input type="date" id="date-row-${index}" value="${date}"> 
                <input type="text" id="todo-row-${index}" value="${todo}">
                <input type="date" id="due-row-${index}" value="${due}">
              -->
              <div class="form-check">
                <input class="form-check-input" type="checkbox" id="row-completed-${index}" data-index="${index}">
                <label class="form-check-label" for="row-completed-${index}">Yes</label>
              </div>
            </td>
          </tr>
        </script>
        </tbody>
      </table>

    </form>
  </div></div>
  <script
  src="https://code.jquery.com/jquery-3.4.1.min.js"
  integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
  crossorigin="anonymous"></script>


  <script>
  // ensures DOM is loaded first
  $(document).ready(function() {

    // initialize "global" variables.  These are available at all child levels. (i.e., in functions)
    var todoData = [];  // this is all your data as a javascript array
    var template = $('script[data-template="table-template"]').text().split(/\$\{(.+?)\}/g);

    // first, get anything previously stored and write table rows
    todoData = getFromStorage();
    writeTable(todoData);


    // begin "listeners" which wait for events like form submission and click on the "completed" checkbox
    $('form').on('submit', function(e) {
      e.preventDefault();  // html5 validation requires the form be submitted, but this prevents it from following through on the submission.
      addRow();
    });

    // note, this listener must be anchored to document, since it is monitoring DOM elements that are dynamic
    $(document).on('click', '.form-check-input', function() {
      var i = $(this).data("index");
      console.log(i);
      if(confirm("Delete this row?")) {
        // delete this row
        todoData.splice(i-1, 1); // array starts at 0, we start at 1...

        saveToLocalStorage(todoData);
        writeTable(todoData);
      }
    });


    // begin functions that do all the work
    function addRow() {

      var data = {
        // index: index,
        date: $('#date-enter').val(),
        todo: $('#todo-enter').val(),
        due: $('#due-enter').val()
      };

      clearForm();

      todoData.push(data);

      saveToLocalStorage(todoData);

      var fromStorage = getFromStorage();
      writeTable(fromStorage);
    }

    function clearForm() {

      $('#date-enter').val('');
      $('#todo-enter').val('');
      $('#due-enter').val('');
    }

    // store the entire array, not just a single row
    function saveToLocalStorage(data) {

      localStorage.clear();
      console.log('storing data in local storage:');
      console.log(data);
      localStorage.setItem('todoList', JSON.stringify(data));
    }

    function getFromStorage() {

      // addRow is intended to take json values from ajax.  It will support multiple rows.
      // this is test data:
      // var data = [
      //   {date: '2019-01-01',todo: 'Start the year', due: '2019-12-31'},
      //   {date: '2019-12-25',todo: 'Celebrate Christmas',due: '2019-12-25'}
      // ];

      // get data from local storage
      data = JSON.parse(localStorage.getItem('todoList')); 

      // todoData = data; // using a "global" variable is probably not good practice.
      return data;
    }

    function addIndexToData(data) {

       var index=1;  
       // takes each row of data, and adds "index" property to it, giving it the value of index and then incrementing index
      data.map(function(row) {
        row.index = index++;
        return row;
      });

      return data;
   }

    // html template rendering function. see https://stackoverflow.com/a/39065147/2129574
    function render(props) {
      return function(tok, i) { return (i % 2) ? props[tok] : tok; };
    }

    // html template rendering function. see https://stackoverflow.com/a/39065147/2129574
    function writeTable(data) {

      // if not an array, stop before things puke.
      if(!Array.isArray(data)) { 
        console.log("data was not an array.  That just won't work.");
        console.log(data);
        return; 
      }

      data = addIndexToData(data);

      var trow = data.map(function(rows) {
        return template.map(render(rows)).join('');
      });

      // $('#table-tbody').append(trow);
      $('#table-tbody').html(trow);

    }
  }); 



  </script>
  </body>
</html>

推荐阅读