php - 当有人仅使用 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>";
解决方案
如果没有数据库,仅 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> </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> </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>
推荐阅读
- django - 如何在 Django Rest Framework 中获取属于特定用户的数据?
- python - 自制软件安装了 pip 中缺少的 python 包
- sql - 如何使用 typeORM 制作复杂的嵌套 where 条件?
- php - 在不重新加载的情况下向 div 添加/删除内容
- java - Selenium WebDriver - 无法处理页面加载时出现的警报
- amazon-web-services - 如何将数据从 s3 存储桶迁移到冰川?
- javascript - 将带有子变量的变量从 JQuery 传递到 Flask 应用程序
- python - 在 Python 中平均 pi 的位数
- r - 字符向量是否有 tidyr::extract 等效项?
- java - xp:fileUpload 的提交按钮需要完整更新吗?