使用AJAX更新记录而不刷新表单


Update record with AJAX without refreshing form

我试图在没有刷新表单的情况下更新DB中的记录。我有grid.php页的形式显示和更新记录。然后,我有文件update.phpUPDATE查询。第三个文件是带有AJAX代码的js1.js。如果我通过action=update.phpgrid.php映射到update.php,则更新查询工作得很好。但是,只要我尝试包括js1.js文件,以防止表单刷新,它停止工作。

代码如下:

grid.php

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="j1.js"></script>
<?php //query.php
    require_once 'header.php';
    if (!$loggedin) die();
    $query = "SELECT SpringMgmt.SpringMgmtID, 
                     SpringMgmt.SpringMgmtActiveYear, 
                     SpringMgmt.PoolID, 
                     SpringMgmt.Notes, 
                     SpringMgmt.SOIEstSubmitted,
                     SpringMgmt.EstAdditional, 
                     SpringMgmt.SOIMeetingScheduled, 
                     Pool.Pool, 
                     Pool.AreaManager, 
                     Employees.EmployeeID, 
                     Employees.FirstName
              FROM SpringMgmt
                   INNER JOIN Pool ON SpringMgmt.PoolID = Pool.PoolID
                   INNER JOIN Employees ON Employees.EmployeeID = Pool.AreaManager ";
    $result = mysql_query($query);
    echo "OK</div>";
    if (!$result) die ("Database access failed0: " . mysql_error());
    //TABLE AND ITS HEADING
    echo '<table id="header" cellpadding="0" cellspacing="0" border="0" >';
    echo "
    <tr> 
    <th>Pool</th>
    <th>Notes</th>
    <th>SO Sent</th>
    <th>Est</th>
    <th>Meet Date</th>
    </tr> 
    ";
    while($record = mysql_fetch_array($result)){
        echo "<form id='myForm' name='myForm'  method=post>";
        echo "<tr>";
        echo "<td >$record[Pool]</td>";
        echo "<td ><textarea size=4 name=Notes rows=3 cols=22>$record[Notes]</textarea> </td>";
        echo "<td style=background-color:><input type=text size=3 name=SOIEstSubmitted value='$record[SOIEstSubmitted]' /></td>";
        echo "<td ><textarea size=4 name=EstAdditional rows=3 cols=12>$record[EstAdditional]</textarea></td>";
        echo "<td style=background-color:><input type=text size=3 name=SOIMeetingScheduled value='$record[SOIMeetingScheduled]' /></td>";
        echo "<td>
              <input type=hidden name='SpringMgmtID' value=$record[SpringMgmtID] />
              <input type=submit name='submit' id='submit' value='Submit' />
              </div></td>";
        echo "</tr>";
        echo "</form>";
    }
    echo "</table>";
?>   

update4.php:

<?php 
    require_once 'header.php';
    if (!$loggedin) die();
    if(isset($_POST['submit'])){
        $UpdateQuery = "UPDATE SpringMgmt 
                        SET    Notes='$_POST[Notes]',
                               SOIEstSubmitted='$_POST[SOIEstSubmitted]',
                               EstAdditional='$_POST[EstAdditional]',
                               SOIMeetingScheduled='$_POST[SOIMeetingScheduled]'
                        WHERE SpringMgmtID='$_POST[SpringMgmtID]'";
        mysql_query($UpdateQuery);
    };
?>

js1.js

$(function () {
    $('form').on('submit', function (e) {
        e.preventDefault();
        $.ajax({
            type: 'post',
            url: 'update4.php',
            data: $('form').serialize(),
            success: function () {
                alert('form was submitted');
            }
        });
    });
});

披露:我的回答可能听起来令人难以置信的傲慢甚至刻薄,请注意这不是我的本意。我将向您展示如何解决这个问题,但是让我先添加一些关于上面代码的注释和一些建议:

  1. 你的HTML的结构是不好的:一个form不应该包装每个tr,你应该考虑使用div代替表格,或"表格内的表格内的单元格"(代码看起来像它听起来一样丑陋)。创建一个HTML表,其中每个TR都是一个FORM

  2. 您的SQL语句受制于SQL注入。这很糟糕。非常非常糟糕。正如我在评论中提到的,可以考虑改用mysql或PDO,并使用参数化查询。您可以在这里阅读更多内容:如何在PHP中防止SQL注入?

  3. 你的HTML代码不干净。一般来说,您的页面会正常工作,因为浏览器会提供帮助,但请相信我,这是糟糕的编程:您最终会更改代码,忘记它,它将变得一团糟。From what I see:

    • 有多个具有相同ID的元素(循环创建的所有表单)。
    • 有不完整的内联CSS (background-color:)。
    • 很多地方缺少引号。
    • 有几个关闭</div>没有打开<div>(这可能是OK的,如果开始的div来自header.php;但即使是这样,代码也很难维护)

最后,解。我希望你没有跳过上面所有的文字直接跳到这里,因为它不仅现在而且将来都会对你有帮助。

改变这两件事,你的代码就可以工作了(都在js1.js中):

  1. 将函数封装在$(document).ready中,当页面加载完成时执行。
  2. 将数据从$("form").serialize()更改为$(this).serialize(),这样您将只发送带有您点击的按钮的表单信息(而不是所有表单)。
js1.js的最终代码如下所示:
$(document).ready(function () {
    $('form').on('submit', function (e) {
        e.preventDefault();
        $.ajax({
            type: 'post',
            url: 'update4.php',
            data: $(this).serialize(),
            success: function () {
                alert('form was submitted');
            }
        });
    });
});

好了,下面我将试着帮助大家快速解决一些问题。

查询

你的问题很复杂,但我觉得没有必要。我已经用MySQL做了很长一段时间了,我不记得我在你的方法中使用过INNER JOIN的情况。因此,更短的查询语法应该是:SQL alias

$query = "SELECT s.*, p.Pool, p.AreaManager, e.EmployeeID, e.FirstName
              FROM SpringMgmt as s, Pool as P, Employees as E
              WHERE s.PoolID = p.PoolID AND e.EmployeeID = p.AreaManager ";

HTML

假设脚本中的HTML是您希望的显示方式,这里有几件事:您可以转义双引号,这样它们就不会破坏您的代码。我会将循环中的代码更改为:点击这里了解我在代码中放入的".$variable."语句

echo "<form id='"myForm'" name='"myForm'"  method='"post'">";
        echo "<tr>";
        echo "<td data-field-id='"pool'">".$record['Pool']."</td>";
        echo "<td ><textarea data-field-id='"notes'" size='"4'" name='"Notes'" rows='"3'" cols='"22'">".$record['Notes']."</textarea> </td>";
        echo "<td style='"background-color:'"><input data-field-id='"submitted'" type='"text'" size='"3'" name='"SOIEstSubmitted'" value='"".$record['SOIEstSubmitted']."'" /></td>";
        echo "<td ><textarea size='"4'" data-field-id='"additional'" name='"EstAdditional'" rows=3 cols='"12'">".$record['EstAdditional']."</textarea></td>";
        echo "<td style='"background-color:'"><input data-field-id='"meetingScheduled'" type='"text'" size='"3'" name='"SOIMeetingScheduled'" value='"".$record['SOIMeetingScheduled']."'" /></td>";
        echo "<td>
              <input type='"hidden'" name='"SpringMgmtID'" value='"$record[SpringMgmtID]'" />
              <input type='"submit'" name='"submit'" id='"submit'" value='"Submit'" />
              </div></td>";
        echo "</tr>";
        echo "</form>";
AJAX/Javascript调用

这个解释起来有点复杂。jQuery ajax对象success函数可以接受一些参数来帮助您完成请求。更多解释请看这个链接。跳过有关.done()函数的部分。其中之一是从请求返回的数据。这意味着在您的update4.php文件中,如果您将数据作为JSON对象输出到浏览器,那么您可以在原始页面上使用该数据。

$(document).ready(function(){
$('form').on('submit', function (e) {
    e.preventDefault();
    $.ajax({
        type: 'post',
        url: 'update4.php',
        data: $(this).serialize(),
        success: function (data,successText) {
           for(var x in data){
              //Use tree traversing to find the input/text elements that have the data-field-id option equal to the x variable; I can't test it right now so I don't want to have this here.
           }
        }
    });
});

});

Update4.php

正如另一位用户在评论部分指出的那样,你在这里的查询很容易被SQL注入。请点击他们提供的链接阅读更多内容。

现在,假设您希望返回所有数据,update4.php文件中的最后一组行应该接近于:
<?php 
  require_once 'header.php';
    if (!$loggedin) die();
    if(isset($_POST['submit'])){
        $UpdateQuery = /*"UPDATE SpringMgmt 
                        SET    Notes='$_POST[Notes]',
                               SOIEstSubmitted='$_POST[SOIEstSubmitted]',
                               EstAdditional='$_POST[EstAdditional]',
                               SOIMeetingScheduled='$_POST[SOIMeetingScheduled]'
                        WHERE SpringMgmtID='$_POST[SpringMgmtID]'"; 
               Don't do this, please use a prepared statement or mysql(i)_real_escape_string() on the data.*/
        $result = mysql_query($UpdateQuery);
        if($result!==false){
              echo json_encode(array(
                     'notes'=> $_POST['Notes'],
                     'submitted'=> $_POST['SOIEstSubmitted'],
                     'additional'=>$_POST['EstAdditional'],
                     'meetingScheduled'=>$_POST['SOIMeetingScheduled']
                  ));
        }
    };

注意 I do NOT建议这么做。您应该将这些$_POST变量移动到您已经正确清理过的其他变量中。永远不要假设你的用户不了解web技术。总是,总是假设用户是有恶意意图从您的数据库窃取数据的人。因此,总是检查用户输入的数据。我设置这个的唯一原因是你看起来对web开发的这些方面相当陌生,并且我所展示的所有其他信息我不想让你负担过重,使你对web开发/设计失去兴趣。

边注

我建议查找一些类型的模板引擎。通常更好的做法是将显示(HTML)和数据(PHP)尽可能分开。我以前使用过的唯一模板引擎是PhpBB 3模板引擎的修改版本和Smarty (PhpBB团队的模板引擎是基于Smarty)。

自从开始输入这个,我看到了另一个答案张贴和快速阅读它。我认为我们两个人对你的整体问题的回答都略有不同,所以我将把这篇文章作为参考,尽管我认为另一个用户的答案比我的好一点。我重复他的观点,如果我听起来居高临下或刻薄,我不是有意的。

而且,我相信有人会或已经向你指出,养成使用mysql_ *函数的习惯,因为mysql_将在未来的PHP版本中被弃用(不再可用)。