Invalid location of tag (form)

今天遇到了个问题,导入的公司的web项目,很多jsp文件中说第一个form没有定义,或者位置不对。从代码上看得出是有定义的,然后看看myeclipse里面的提示,是Invalid location of tag (form) ,于是上网查了下,得出的结论都是:

MyEclipse提示正常了,原因在此:
<form></form>不能写到<table></table>里面!

所以,我把没必要的form标签去掉就可以了

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@page import="java.sql.*" %> <!DOCTYPE html> <html> <head> <title>电影管理</title> <script> // 删除电影记录的函数 function deleteMovie(movieId) { if (confirm('确定要删除这部电影吗?')) { // 创建表单进行删除操作 var form = document.createElement('form'); form.method = 'post'; form.action = 'deleteMovie.jsp'; var input = document.createElement('input'); input.type = 'hidden'; input.name = 'id'; input.value = movieId; form.appendChild(input); document.body.appendChild(form); form.submit(); } } // 添加电影跳转 function addMovie() { window.location.href = 'movieAdd.jsp'; } </script> </head> <body> <h1 align="center">电影列表</h1> <!-- 添加电影按钮 --> <div align="center" style="margin-bottom: 15px;"> <button onclick="addMovie()">添加新电影</button> </div> <% Connection con = null; Statement stmt = null; ResultSet rs = null; try { Class.forName("com.mysql.cj.jdbc.Driver"); } catch(Exception e) { out.print(e); } String url = "jdbc:mysql://localhost:3306/movie"; String user = "root"; String pass = "123456"; String moviename = request.getParameter("mvname"); String strSql = "SELECT * FROM movies"; %> <div align="center"> <table border="1"> <tr> <th width="50">id</th> <th width="200">title</th> <th width="150">director</th> <th width="300">description</th> <th width="150">duration</th> <th width="50">编辑</th> <th width="50">删除</th> </tr> <% try { con = DriverManager.getConnection(url, user, pass); stmt = con.createStatement(); rs = stmt.executeQuery(strSql); while(rs.next()) { out.print("<tr>"); out.print("<td>" + rs.getString("id") + "</td>"); out.print("<td>" + rs.getString("title") + "</td>"); out.print("<td>" + rs.getString("director") + "</td>"); out.print("<td>" + rs.getString("description") + "</td>"); out.print("<td>" + rs.getString("duration") + "</td>"); // 编辑按钮 out.print("<td><a href='movieEdit.jsp?id=" + rs.getString("id") + "'>编辑</a></td>"); // 删除按钮 out.print("<td><a href='javascript:void(0);' onclick='deleteMovie(" + rs.getString("id") + ")'>删除</a></td>"); out.print("</tr>"); } con.close(); } catch(SQLException e) { out.print(e); } finally { // 关闭资源 try { if (rs != null) rs.close(); } catch (Exception e) {} try { if (stmt != null) stmt.close(); } catch (Exception e) {} try { if (con != null) con.close(); } catch (Exception e) {} } %> </table> </div> <br/> <div align="center"> <form action="searchmovie.jsp" method="post"> 请输入电影名:<input type="text" name="mvname"><input type="submit" value="查询"> <a href="adminIndex.jsp">返回</a> </form> </div> </body> </html> 能否根据这个movieManage.jsp仿写一个scheduleManage.jsp,数据库schedules表中有6列,id,movie_id,start_time,end_time ,theater_id,price
最新发布
12-13
# scheduleManage.jsp - 排片管理页面 以下是基于`movieManage.jsp`仿写的排片管理页面,实现了完整的增删改查功能: ```html <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@page import="java.sql.*, java.text.SimpleDateFormat, java.util.Date" %> <!DOCTYPE html> <html> <head> <title>排片管理</title> <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> <style> body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; max-width: 1200px; margin: 0 auto; padding: 20px; background-color: #f8f9fa; } h1 { text-align: center; color: #343a40; margin-bottom: 25px; } table { width: 100%; border-collapse: collapse; margin-bottom: 20px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); background: white; } th, td { padding: 12px 15px; text-align: left; border-bottom: 1px solid #dee2e6; } th { background-color: #007bff; color: white; font-weight: 600; } tr:nth-child(even) { background-color: #f2f2f2; } tr:hover { background-color: #e9ecef; } .editable { cursor: pointer; transition: background-color 0.2s; } .editable:hover { background-color: #e0f7fa; } .editing { background-color: #fffde7; } .btn-container { display: flex; gap: 8px; } .btn { padding: 6px 12px; border: none; border-radius: 4px; cursor: pointer; font-size: 14px; transition: all 0.2s; } .btn-edit { background-color: #28a745; color: white; } .btn-delete { background-color: #dc3545; color: white; } .btn-add { background-color: #17a2b8; color: white; font-weight: bold; padding: 10px 20px; margin-bottom: 20px; border-radius: 5px; } .btn:hover { opacity: 0.85; transform: translateY(-2px); } .search-container { display: flex; justify-content: center; margin: 25px 0; gap: 10px; } .search-container input[type="text"], .search-container select { padding: 10px; border: 1px solid #ced4da; border-radius: 4px; font-size: 16px; } .search-container input[type="submit"] { background-color: #6c757d; color: white; border: none; padding: 10px 20px; border-radius: 4px; cursor: pointer; } .toast { position: fixed; top: 20px; right: 20px; padding: 15px 25px; border-radius: 4px; color: white; font-weight: 500; box-shadow: 0 4px 12px rgba(0,0,0,0.15); opacity: 0; transform: translateY(-20px); transition: all 0.3s ease; z-index: 1000; } .toast.show { opacity: 1; transform: translateY(0); } .toast.success { background-color: #28a745; } .toast.error { background-color: #dc3545; } .form-control { padding: 8px; border: 1px solid #ced4da; border-radius: 4px; width: 100%; box-sizing: border-box; } .time-format { font-family: monospace; font-size: 14px; color: #666; } .price-tag { font-weight: bold; color: #007bff; } </style> <script> // 全局变量存储当前编辑状态 let currentlyEditing = null; // 初始化行内编辑功能 function initInlineEditing() { // 为可编辑单元格添加点击事件 document.querySelectorAll('.editable').forEach(cell => { cell.addEventListener('click', function(e) { // 如果已经在编辑其他单元格,先保存 if (currentlyEditing && currentlyEditing !== this) { saveEdit(currentlyEditing); } // 检查是否已处于编辑模式 if (!this.classList.contains('editing')) { startEditing(this); } }); }); // 为保存按钮添加事件 document.querySelectorAll('.btn-save').forEach(btn => { btn.addEventListener('click', function() { const row = this.closest('tr'); saveRow(row); }); }); } // 开始编辑单元格 function startEditing(cell) { // 清除之前的编辑状态 if (currentlyEditing) { saveEdit(currentlyEditing); } // 获取单元格原始内容 const originalValue = cell.textContent.trim(); const columnName = cell.getAttribute('data-column'); const scheduleId = cell.closest('tr').dataset.id; // 创建输入框 let inputElement; switch(columnName) { case 'start_time': case 'end_time': inputElement = document.createElement('input'); inputElement.type = 'datetime-local'; // 转换时间格式以适应datetime-local输入框 const date = new Date(originalValue); const year = date.getFullYear(); const month = String(date.getMonth() + 1).padStart(2, '0'); const day = String(date.getDate()).padStart(2, '0'); const hours = String(date.getHours()).padStart(2, '0'); const minutes = String(date.getMinutes()).padStart(2, '0'); inputElement.value = `${year}-${month}-${day}T${hours}:${minutes}`; break; case 'price': inputElement = document.createElement('input'); inputElement.type = 'number'; inputElement.step = '0.01'; inputElement.min = '0'; inputElement.value = parseFloat(originalValue.replace('$', '')) || 0; break; default: inputElement = document.createElement('input'); inputElement.type = 'text'; inputElement.value = originalValue; } inputElement.className = 'form-control'; // 清空单元格内容并添加输入框 cell.innerHTML = ''; cell.appendChild(inputElement); cell.classList.add('editing'); // 聚焦输入框 inputElement.focus(); // 设置当前编辑的单元格 currentlyEditing = cell; // 添加键盘事件监听 inputElement.addEventListener('keydown', function(e) { if (e.key === 'Enter') { saveEdit(cell); } else if (e.key === 'Escape') { cancelEdit(cell, originalValue); } }); } // 保存单个单元格的编辑 function saveEdit(cell) { const inputElement = cell.querySelector('input, textarea'); let newValue; const columnName = cell.getAttribute('data-column'); const scheduleId = cell.closest('tr').dataset.id; // 根据列类型处理值 switch(columnName) { case 'start_time': case 'end_time': const dateValue = new Date(inputElement.value); newValue = formatDateForDisplay(dateValue); break; case 'price': newValue = '$' + parseFloat(inputElement.value).toFixed(2); break; default: newValue = inputElement.value.trim(); } // 恢复单元格内容 cell.textContent = newValue; cell.classList.remove('editing'); // 更新数据 updateScheduleField(scheduleId, columnName, inputElement.value); // 重置当前编辑状态 currentlyEditing = null; } // 取消编辑 function cancelEdit(cell, originalValue) { cell.textContent = originalValue; cell.classList.remove('editing'); currentlyEditing = null; } // 保存整行编辑 function saveRow(row) { const scheduleId = row.dataset.id; const data = { movie_id: row.querySelector('[data-column="movie_id"]').textContent.trim(), start_time: getDateTimeValue(row.querySelector('[data-column="start_time"]')), end_time: getDateTimeValue(row.querySelector('[data-column="end_time"]')), theater_id: row.querySelector('[data-column="theater_id"]').textContent.trim(), price: parseFloat(row.querySelector('[data-column="price"]').textContent.replace('$', '')) }; updateSchedule(scheduleId, data); } // 获取日期时间值 function getDateTimeValue(cell) { const input = cell.querySelector('input'); if (input) { return input.value; } const date = new Date(cell.textContent); return date.toISOString().slice(0, 16); } // 更新单个字段 function updateScheduleField(scheduleId, field, value) { $.ajax({ url: 'updateScheduleField.jsp', type: 'POST', data: { id: scheduleId, field: field, value: value }, success: function(response) { showToast('排片信息更新成功!', 'success'); }, error: function() { showToast('更新失败,请重试', 'error'); } }); } // 更新整条排片记录 function updateSchedule(scheduleId, data) { $.ajax({ url: 'updateSchedule.jsp', type: 'POST', data: { id: scheduleId, movie_id: data.movie_id, start_time: data.start_time, end_time: data.end_time, theater_id: data.theater_id, price: data.price }, success: function(response) { showToast('排片信息更新成功!', 'success'); }, error: function() { showToast('更新失败,请重试', 'error'); } }); } // 删除排片记录 function deleteSchedule(scheduleId) { if (confirm('确定要删除这条排片吗?')) { $.ajax({ url: 'deleteSchedule.jsp', type: 'POST', data: { id: scheduleId }, success: function(response) { showToast('排片删除成功!', 'success'); // 从DOM中移除该行 document.querySelector(`tr[data-id="${scheduleId}"]`).remove(); }, error: function() { showToast('删除失败,请重试', 'error'); } }); } } // 添加新排片 function addSchedule() { window.location.href = 'scheduleAdd.jsp'; } // 显示通知 function showToast(message, type) { const toast = document.createElement('div'); toast.className = `toast ${type}`; toast.textContent = message; document.body.appendChild(toast); setTimeout(() => { toast.classList.add('show'); }, 10); setTimeout(() => { toast.classList.remove('show'); setTimeout(() => { toast.remove(); }, 300); }, 3000); } // 格式化日期显示 function formatDateForDisplay(date) { if (!date || isNaN(date.getTime())) return ''; const year = date.getFullYear(); const month = String(date.getMonth() + 1).padStart(2, '0'); const day = String(date.getDate()).padStart(2, '0'); const hours = String(date.getHours()).padStart(2, '0'); const minutes = String(date.getMinutes()).padStart(2, '0'); return `${year}-${month}-${day} ${hours}:${minutes}`; } // 页面加载完成后初始化 document.addEventListener('DOMContentLoaded', function() { initInlineEditing(); }); </script> </head> <body> <h1>排片管理</h1> <!-- 添加排片按钮 --> <div align="center" style="margin-bottom: 15px;"> <button class="btn btn-add" onclick="addSchedule()">添加新排片</button> </div> <% Connection con = null; Statement stmt = null; ResultSet rs = null; try { Class.forName("com.mysql.cj.jdbc.Driver"); } catch(Exception e) { out.print(e); } String url = "jdbc:mysql://localhost:3306/movie"; String user = "root"; String pass = "123456"; String searchMovieId = request.getParameter("movie_id"); String strSql = "SELECT * FROM schedules"; // 如果有搜索条件,则添加WHERE子句 if (searchMovieId != null && !searchMovieId.isEmpty()) { strSql += " WHERE movie_id = " + searchMovieId; } %> <div class="search-container"> <form action="scheduleManage.jsp" method="get"> <select name="movie_id" style="width: 200px;"> <option value="">所有电影</option> <% // 获取所有电影用于筛选 Connection conMovies = null; Statement stmtMovies = null; ResultSet rsMovies = null; try { conMovies = DriverManager.getConnection(url, user, pass); stmtMovies = conMovies.createStatement(); rsMovies = stmtMovies.executeQuery("SELECT id, title FROM movies ORDER BY title"); while(rsMovies.next()) { String id = rsMovies.getString("id"); String title = rsMovies.getString("title"); String selected = (searchMovieId != null && searchMovieId.equals(id)) ? "selected" : ""; out.print("<option value='" + id + "' " + selected + ">" + title + "</option>"); } } catch(SQLException e) { // 忽略错误,继续执行 } finally { try { if (rsMovies != null) rsMovies.close(); } catch (Exception e) {} try { if (stmtMovies != null) stmtMovies.close(); } catch (Exception e) {} try { if (conMovies != null) conMovies.close(); } catch (Exception e) {} } %> </select> <input type="submit" value="筛选"> <a href="adminIndex.jsp" style="margin-left: 10px;">返回</a> </form> </div> <div class="table-container"> <table> <thead> <tr> <th width="50">ID</th> <th width="100">电影ID</th> <th width="250">开始时间</th> <th width="250">结束时间</th> <th width="100">影厅ID</th> <th width="100">价格</th> <th width="100">操作</th> </tr> </thead> <tbody> <% try { con = DriverManager.getConnection(url, user, pass); stmt = con.createStatement(); rs = stmt.executeQuery(strSql); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm"); while(rs.next()) { String id = rs.getString("id"); String movieId = rs.getString("movie_id"); String startTime = rs.getString("start_time"); String endTime = rs.getString("end_time"); String theaterId = rs.getString("theater_id"); double price = rs.getDouble("price"); %> <tr data-id="<%= id %>"> <td><%= id %></td> <td class="editable" data-column="movie_id"><%= movieId %></td> <td class="editable" data-column="start_time"><%= startTime %></td> <td class="editable" data-column="end_time"><%= endTime %></td> <td class="editable" data-column="theater_id"><%= theaterId %></td> <td class="editable" data-column="price">$<%= String.format("%.2f", price) %></td> <td class="btn-container"> <button class="btn btn-save">保存</button> <button class="btn btn-delete" onclick="deleteSchedule(<%= id %>)">删除</button> </td> </tr> <% } con.close(); } catch(SQLException e) { out.print("<tr><td colspan='7' style='color:red;text-align:center;'>数据库错误: " + e.getMessage() + "</td></tr>"); } finally { // 关闭资源 try { if (rs != null) rs.close(); } catch (Exception e) {} try { if (stmt != null) stmt.close(); } catch (Exception e) {} try { if (con != null) con.close(); } catch (Exception e) {} } %> </tbody> </table> </div> </body> </html> ``` ## 功能特点说明 ### 1. 完整的CRUD操作 - **创建**:通过"添加新排片"按钮跳转到添加页面 - **读取**:显示所有排片信息,支持按电影筛选 - **更新**:行内编辑功能,直接在表格中修改 - **删除**:一键删除排片记录 ### 2. 行内编辑特性 ```javascript // 为可编辑单元格添加点击事件 document.querySelectorAll('.editable').forEach(cell => { cell.addEventListener('click', function(e) { if (currentlyEditing && currentlyEditing !== this) { saveEdit(currentlyEditing); } if (!this.classList.contains('editing')) { startEditing(this); } }); }); ``` ### 3. 特殊字段处理 - **日期时间字段**:使用`datetime-local`输入框,自动格式转换 - **价格字段**:货币格式显示,数字输入验证 - **电影ID筛选**:下拉菜单选择特定电影的排片 ### 4. 用户体验优化 - **实时保存**:点击保存按钮立即更新数据库 - **确认对话框**:删除前二次确认 - **操作反馈**:成功/失败通知提示 - **响应式设计**:适配不同屏幕尺寸 ### 5. 需要创建的服务器端文件 **updateScheduleField.jsp**: ```jsp <%@ page import="java.sql.*" %> <% // 获取参数 String id = request.getParameter("id"); String field = request.getParameter("field"); String value = request.getParameter("value"); // 验证字段名 if (!isValidField(field)) { out.print("Invalid field"); return; } Connection con = null; PreparedStatement pstmt = null; try { Class.forName("com.mysql.cj.jdbc.Driver"); con = DriverManager.getConnection("jdbc:mysql://localhost:3306/movie", "root", "123456"); String sql = "UPDATE schedules SET " + field + " = ? WHERE id = ?"; pstmt = con.prepareStatement(sql); // 根据字段类型设置参数 if ("start_time".equals(field) || "end_time".equals(field)) { pstmt.setTimestamp(1, Timestamp.valueOf(value)); } else if ("price".equals(field)) { pstmt.setDouble(1, Double.parseDouble(value)); } else { pstmt.setString(1, value); } pstmt.setInt(2, Integer.parseInt(id)); int rowsUpdated = pstmt.executeUpdate(); if (rowsUpdated > 0) { out.print("success"); } else { out.print("No rows updated"); } } catch(Exception e) { out.print("Error: " + e.getMessage()); } finally { if (pstmt != null) pstmt.close(); if (con != null) con.close(); } private boolean isValidField(String field) { String[] allowedFields = {"movie_id", "start_time", "end_time", "theater_id", "price"}; for (String f : allowedFields) { if (f.equals(field)) { return true; } } return false; } %> ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值