Прежде чем я начну, я немного коснусь параноика и подчеркиваю, что используемый на стороне сервера PHP-код небезопасен.Во-первых, магические кавычки PHP устарели и их следует избегать и два, подготовка данных на стороне клиента и последующее сохранение их на сервере без вопросов - очень плохая идея .
Никогда не доверяйте клиенту для форматирования данных, в противном случае я могу прийти и сделать следующее:
var myOwnJson = [{ "data": [{
"index":"<script>alert('You');<\/script>",
"part":"<script>alert('Are');<\/script>",
"pieces":"<script>alert('Not');<\/script>",
"weight":"<script>alert('Safe');<\/script>"
}] }];
var URL = "save.php?data=" + encodeURI(JSON.stringify(myOwnJson));
Я бы порекомендовалчтение о санации и проверке ввода. Вы все еще можете создать файл JSON на клиенте и отправить его на сервер, но сервер должен убедиться, что он проверяет входные данные в соответствии с ожиданиями.
В качестве примера:
<?php
// Try to parse read the json file as an associative array.
$unsafe_json = json_decode( $_GET["data"], true );
if( ! is_array( $unsafe_json ) ) {
// Otherwise die, and tell the user.
die('Failed to save');
}
// Start building a trusted json array.
$safe_json = [ 'data' => [] ];
// These are the only keys we'll accept for each todo item.
$values = [ 'index', 'part', 'pieces', 'weight' ];
foreach( $unsafe_json as $unsafe_todo ) {
$safe_todo = [];
foreach( $values as $value ) {
if( isset( $unsafe_todo[$value] ) && is_string( $unsafe_todo[$value] ) ) {
// Sanitize the value from the submitted json array.
$safe_todo[$value] = filter_var( $unsafe_todo[$value], FILTER_SANITIZE_STRING );
} else {
// This value wasn't found in the array, we'll mark it as false.
$safe_todo[$value] = false;
}
}
// Add our validated todo item to the list.
$safe_json['data'][] = $safe_todo;
}
// Save the file
$file = fopen( "todo.json", "w" );
fwrite( $file, '[' . json_encode( $safe_json ) . ']' );
fclose( $file );
Я очищаю отправленные данные и удаляю нежелательный код, пока проверяет , что отправленные данные отформатированытак, как я ожидаю.
Если пойти еще дальше, я могу проверить, что index
и weight
являются числовыми значениями, используя FILTER_VALIDATE_INT
или is_numeric
, которые я затем мог бы выбратьпользователь о. Или я мог бы очистить эти значения с помощью FILTER_SANITIZE_INT
или intval
, чтобы убедиться, что эти значения находятся в формате, который я ожидаю.
Но достаточно безопасностиnaggage ... Я на самом деле сейчас отвечу на ваш вопрос.
Не внося слишком много изменений в свой текущий код, одним из способов добавить кнопку удаления или несколько кнопок удаления будет использование столбца флажка,Я пометил эти изменения в приведенном ниже коде, но подведу итог:
- Дайте каждой строке индекс и идентификатор, чтобы их можно было быстро идентифицировать.Например.
<tr id="row-1"></tr>
- Я сделал это, создав глобальный счетчик количества элементов todo.
- В каждой строке добавьте флажок, дайте емузначение индекса строки.
- Создать функцию, которая удаляет строку на основе параметра индекса.Например.
removeTodo(1);
- Создайте функцию, которая перебирает выбранные флажки, и используйте функцию
removeTodo()
, используя их значение. - Свяжите эти функции с кнопками.
// 1 ) Add a global variable to count the todo items we have.
var todo_index = 0;
function checkInputText(value, msg) {
if (value == null || value == "") {
alert(msg);
return true;
}
return false;
}
function Todo(index, part, pieces, weight) {
this.index = index;
this.part = part;
this.pieces = pieces;
this.weight = weight;
}
var todos = new Array();
window.onload = init;
function init() {
var submitButton = document.getElementById("submit");
//submitButton.onclick = getTodoData;
//getTodoData();
}
function getTodoData() {
var request = new XMLHttpRequest();
request.open("GET", "todo.json");
request.onreadystatechange = function() {
if (this.readyState == this.DONE && this.status == 200) {
if (this.responseText) {
parseTodoItems(this.responseText);
addTodosToPage();
} else {
console.log("error");
}
}
};
request.send();
}
function parseTodoItems(todoJSON) {
if (todoJSON == null || todoJSON.trim() == "") {
return;
}
var todoArray = JSON.parse(todoJSON);
if (todoArray.length == 0) {
console.log("Error: the to-do list array is empty!");
return;
}
for (var i = 0; i < todoArray.length; i++) {
var todoItem = todoArray[i];
todos.push(todoItem);
addTodosToPage(todoItem);
}
}
function addTodosToPage() {
var table = document.getElementById("todoList");
var tr = document.createElement("tr");
// 2 ) Increment the number of todos we have by 1.
todo_index++;
// 3 ) Set the row ID to an index.
tr.id = "todo-" + todo_index;
var index = document.getElementById('index').value;
var part = document.getElementById('part').value;
var pieces = document.getElementById('pieces').value;
var weight = document.getElementById('weight').value;
// 4 ) Add a checkbox for selecting the row and a remove button for removing the row.
tr.innerHTML = "\
<td><input name='select-row' type='checkbox' value='" + todo_index + "'></td>\
<td>" + index + "</td>\
<td>" + part + "</td>\
<td>" + pieces + "</td>\
<td>" + weight + "</td>\
<td><button onclick='removeTodo(" + todo_index + ");'>x</button><td>";
table.appendChild(tr);
}
function checkInputText(value, msg) {
if (value == null || value == "") {
alert(msg);
return true;
}
return false;
}
function saveTodoData() {
var todoJSON = JSON.stringify(todos);
var request = new XMLHttpRequest();
var URL = "save.php?data=" + encodeURI(todoJSON);
request.open("GET", URL);
request.setRequestHeader("Content-Type",
"text/plain;charset=UTF-8");
request.send();
}
// 5 ) Add a function which will remove a todo item based on it's index.
function removeTodo(index) {
// Get the element.
var row = document.getElementById('todo-' + index);
// If we were able to find a row matching that id.
if (row) {
// Access row's parent node (tbody) and remove the row.
row.parentNode.removeChild(row);
}
// Decrement the todo count by 1.
todo_index--;
}
// 6 ) Add a function so we can click 'select all' to either select all rows or deselect all rows.
function toggleSelection(checkbox) {
// Get our rows.
var rowsToSelect = document.querySelectorAll('input[name=select-row]');
for (var i = 0; i < rowsToSelect.length; i++) {
// Check or uncheck boxes if the 'master' checkbox is checked.
rowsToSelect[i].checked = checkbox.checked;
}
}
// 7 ) Add a function to remove all rows that are selected.
function removeSelectedTodos() {
// Get our rows.
var rowsToRemove = document.querySelectorAll('input[name=select-row]:checked');
for (var i = 0; i < rowsToRemove.length; i++) {
// Delete the row.
removeTodo(rowsToRemove[i].value);
}
}
<table>
<thead>
<tr>
<!-- 8 ) Add a 'select all' checkbox. -->
<th><input onchange="toggleSelection(this);" type='checkbox'></th>
<th>Index</th>
<th>Part</th>
<th>Pieces</th>
<th>Weight</th>
<!-- 9 ) Add a 'delete selected' button -->
<th><button onclick='removeSelectedTodos();'>x</button></th>
</tr>
</thead>
<tbody id="todoList">
</tbody>
</table>
<form>
<fieldset>
<div class="tableContainer">
<label for="index">
<select id="index" name="index">
<option hidden="" >Index</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="5">5</option>
<option value="6">6</option>
<option value="7">7</option>
<option value="8">8</option>
<option value="9">9</option>
<option value="10">10</option>
</select>
</label>
<input placeholder="part" id="part" />
<input placeholder="pieces" id="pieces" />
<input placeholder="weight" id="weight" />
<input type="button" id="submit" value="ADD" onclick="addTodosToPage()">
</div>
</fieldset>
</form>
Что касается обновления списка задач на сервере: ваш текущий код уже на пути к этому.Если вы отправляете значения на сервер и сохраняете их в файл json, который перезаписывает старый, вы обновили версию списка задач на сервере.
Надеюсь, это поможет!