求助:用JS+PHP实现餐厅后台菜单JSON文件无刷新编辑功能
问题描述
我正在为餐厅老板开发后台管理面板,需实现菜单板块的编辑功能。目前已通过JSON文件动态生成菜单表格,但无法实现通过表格内的文本输入框修改内容,点击“确认”按钮后无刷新更新JSON文件的功能,附上相关代码寻求解决方案。
HTML文件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src="script.js"></script> <link href="style.css" rel="stylesheet"> <title>Menu</title> </head> <body> <div class="menu-container"> <h1>Menu del Ristorante</h1> <table> <thead> <tr> <th>Tipologia</th> <th class="nome">Nome</th> <th>Modifica</th> <th>Nuovo testo</th> <th>Conferma</th> </tr> </thead> <tbody id="menu-table"> <!-- I dati verranno caricati qui dinamicamente --> </tbody> </table> </div> </body> </html>
JSON文件(menu.json)
[ { "tipologia": "Antipasto", "nome": "Misto di Mare caldo e freddo (min. per 2 persone)" }, { "tipologia": "Antipasto", "nome": "Carpaccio di Gambero rosso, Cetriolo, Panna acida" }, { "tipologia": "Antipasto", "nome": "Tartare di Pescato, Guacamole e Pane Carasau" }, { "tipologia": "Antipasto", "nome": "Bresaola di Tonno e insalata di Pesche Noci" }, { "tipologia": "Antipasto", "nome": "Altra voce del menu senza descrizione" }, { "tipologia": "Antipasto", "nome": "Ancora un'altra voce del menu senza descrizione" } ]
PHP文件(save-menu.php)
<?php // Percorso del file JSON $jsonFile = 'menu.json'; // Controlla se è una richiesta PUT if ($_SERVER['REQUEST_METHOD'] === 'PUT') { // Leggi i dati inviati dalla richiesta PUT $data = file_get_contents('php://input'); // Decodifica i dati JSON $jsonData = json_decode($data, true); // Verifica se la decodifica è riuscita if ($jsonData !== null) { // Codifica nuovamente i dati come JSON $jsonString = json_encode($jsonData, JSON_PRETTY_PRINT); // Sovrascrivi il file JSON con i nuovi dati file_put_contents($jsonFile, $jsonString); // Restituisci una risposta di successo http_response_code(200); echo json_encode(array('message' => 'Modifiche salvate con successo.')); } else { // Errore nella decodifica JSON http_response_code(400); echo json_encode(array('message' => 'Errore nella decodifica JSON.')); } } else { // Tipo di richiesta non supportato http_response_code(405); echo json_encode(array('message' => 'Metodo non consentito.')); } ?>
JavaScript文件(script.js)
let menuData; // Variabile per archiviare i dati del menu // Funzione per inizializzare la tabella del menu async function initMenuTable() { const menuTable = document.getElementById('menu-table'); // Carica i dati del menu dal file JSON try { const response = await fetch('menu.json'); if (!response.ok) { throw new Error('Errore nel caricamento dei dati del menu.'); } menuData = await response.json(); // Popola la tabella con i dati del menu menuData.forEach((item, index) => { const row = menuTable.insertRow(); row.innerHTML = `<td>${item.tipologia}</td><td>${item.nome}</td><td><button onclick="modificaVoceMenu(${index})">Modifica</button></td><td><input type="text" id="nuovo-titolo-${index}" value="${item.nome}" disabled></td><td><button onclick="confermaModifica(${index})">Conferma</button></td>`; }); } catch (error) { console.error(error); } } // Funzione per abilitare la modifica di una voce del menu function modificaVoceMenu(index) { const input = document.getElementById(`nuovo-titolo-${index}`); input.removeAttribute('disabled'); input.focus(); } // Funzione per confermare la modifica e aggiornare i dati function confermaModifica(index) { const nuovoTitolo = document.getElementById(`nuovo-titolo-${index}`).value.trim(); if (!nuovoTitolo) return; // 防止空值提交 // Aggiorna il titolo nel menuData menuData[index].nome = nuovoTitolo; // Aggiorna la cella HTML con il nuovo valore const row = document.getElementById('menu-table').rows[index]; row.cells[1].textContent = nuovoTitolo; // Disabilita l'input document.getElementById(`nuovo-titolo-${index}`).setAttribute('disabled', 'true'); // Salva il menuData aggiornato nel file JSON salvaMenuData(menuData); } // Funzione per salvare il menuData aggiornato nel file JSON function salvaMenuData(data) { fetch('save-menu.php', { // 修改为请求PHP处理文件 method: 'PUT', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(data), }) .then(response => { if (!response.ok) { throw new Error('Errore nel salvataggio delle modifiche.'); } return response.json(); }) .then(result => { console.log(result.message); }) .catch(error => { console.error(error); }); } // Chiama la funzione per inizializzare la tabella del menu quando la pagina si carica window.addEventListener('load', initMenuTable);
解决方案说明
- 请求目标修正:原JS中
salvaMenuData函数请求静态menu.json文件,静态文件无法处理PUT请求,需改为请求PHP处理文件(如save-menu.php),由PHP完成JSON文件的写入操作。 - 输入框初始化优化:生成表格时将当前菜品名称填入输入框,方便用户直接修改,无需重新输入完整内容。
- DOM选择器优化:替换原
getElementsByTagName为更可靠的表格行选择方式,避免页面其他表格干扰导致的选择错误。 - 空值校验:确认修改时添加空值校验,防止提交空的菜品名称。
- 用户体验优化:点击“Modifica”时自动聚焦输入框,提升操作流畅度。
内容的提问来源于stack exchange,提问作者Il_ghiso
相关产品推荐
相关产品推荐

