有没有办法我可以做到这一点而不刷新页面?

时间:2018-02-28 12:18:32

标签: php ajax

我正在尝试为我的论坛创建和编辑按钮,就像Reddit一样。我已经开始工作,但我想知道我是否能够在不刷新页面的情况下完成它。

例如,当我单击编辑按钮时,它会重新加载页面并显示要编辑的表单,然后当我单击“保存”时,它将再次重新加载以显示新编辑的帖子。

代码(来自IncredibleHat答案的编辑):

<?php

session_start();

$host = "host"; // Host name 
$user = "username"; // Mysql username 
$password = "password"; // Mysql password 
$db_name = "database"; // Database name 
$tbl_name = "fquestions"; // Table name 

// Connect to server and select databse.
$conn = mysqli_connect($host, $user, $password)or die("cannot connect"); 
mysqli_select_db($conn, $db_name)or die("cannot select DB");

// get value of id that sent from address bar 
$id = $_GET['id'];
$sql = "SELECT * FROM $tbl_name WHERE id='$id'";
$result = mysqli_query($conn, $sql);
$rows = mysqli_fetch_array($result);

/*Check if topic is locked or not */
$locked = $rows['locked'];

if ($_SESSION['username'] == $rows['username']) {
    $editPost = true;
}
?>

<head>

    <!-- ****** faviconit.com favicons ****** -->
    <link rel="shortcut icon" href="../images/favicon.ico">
    <!-- ****** faviconit.com favicons ****** -->

    <link id ="pageStyle" rel="stylesheet" href='../css/defaultStyle.css' type='text/css'> <!-- Loads Default Stylesheet -->
    <script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script>
    <link rel='stylesheet' href='https://fonts.googleapis.com/css?family=Roboto' type='text/css'>
    <script src='https://www.google.com/recaptcha/api.js'></script>

</head>

<body>     
    <div id="mainContent">
        <div id="question">
            <p id="date"><?php echo $rows['datetime']; ?></p>
            <h2><?php echo $rows['topic']; ?></h2>
            <b><p><?php echo $rows['username']; ?></p></b>
            <?php
            // The Regular Expression filter
            $reg_exUrl = "/(http|https|ftp|ftps)\:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(\/\S*)?/";

            // The Text you want to filter for urls
            $text = htmlspecialchars($rows['detail']);

            // Check if there is a url in the text
            if(preg_match($reg_exUrl, $text, $url)) {
                $url = preg_replace("/^http:/i", "https:", $url);

                // make the urls hyper links
                echo preg_replace($reg_exUrl, '<a title="Opening this link will take you to a new page" alt="External Link Deleted" target="_blank" href="'.$url[0].'" rel="nofollow">'.$url[0].'</a><br>', '<p id="post">'.$text.'</p>');

            } else {
                ?>
            <p id="post"><?php echo htmlspecialchars($rows['detail']); ?></p>
            <?php
            }

            if ($editPost == true) {
                $_SESSION['detail'] = $rows['detail'];
                $_SESSION['id'] = $rows['id'];
                ?>
                <style>
                    #editPostButton {
                        border: none; outline: 0; background-color: #D8D8D8; margin-left: -5px;
                    }

                    #editPostButton.dark {
                        color: white;
                        background-color: #1C1C1C;
                    }
                </style>
                <input type="submit" value="Edit" name="editPostButton" id="editPostButton" data-postId="<?php echo $rows['id']; ?>">
                <div id="editFormBlock"></div>

                <script>
                   $(document).ready(function() {
                       // for clicking on the edit button, to grab the edit form
                       $("#editPostButton").on('click',function(e) {
                           e.preventDefault();
                           $.post(
                               'ajaxhandler.php',
                               { action: 'editform', postid: $(this).data('postId') },
                               function(htmlReturn) {
                                   $("#editFormBlock").html( htmlReturn ); // replace editForm content
                                },
                                'HTML'
                                );
                       });

                       // for clicking the save button for a edit form
                       // using .on so it catches dynamically added content
                       $("#editFormBlock").on('click',"#saveButton",function(e) {
                           e.preventDefault();
                           var data = $("#editForm").serializeArray();
                           data.push({name: 'action', value: 'saveform'});
                           $.post(
                               'ajaxhandler.php',
                               data,
                               function(htmlReturn) {
                                   $("#editFormBlock").html( '' ); // clear edit form out
                                },
                                'HTML'
                                );
                       });
                   });
                </script>
                <?php
            }
            ?>
        </div>

<?php

$tbl_name2="fanswer"; // Switch to table "forum_answer"
$sql2 = "SELECT * FROM $tbl_name2 WHERE question_id='$id'";
$result2 = mysqli_query($conn, $sql2);
$row_cnt = mysqli_num_rows($result2);

if ($row_cnt > 0) {
    ?>
    <h3>Replies:</h3>
    <div id="replies">

    <?php
    while($rows = mysqli_fetch_array($result2)) {
    ?>
        <p id="dates"><?php echo $rows['a_datetime']; ?></p>
        <div id="reply">
        <b><p><?php echo $rows['a_username']; ?></p></b>
        <?php
        // The Regular Expression filter
        $reg_exUrl = "/(http|https|ftp|ftps)\:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(\/\S*)?/";

        // The Text you want to filter for urls
        $text = htmlspecialchars($rows['a_answer']);

        // Check if there is a url in the text
        if(preg_match($reg_exUrl, $text, $url)) {
            $url = preg_replace("/^http:/i", "https:", $url);

            // make the urls hyper links
            echo preg_replace($reg_exUrl, '<a title="Opening this link will take you to a new page" alt="External Link Deleted" target="_blank" href="'.$url[0].'" rel="nofollow">'.$url[0].'</a>', $text);

        } else {
            ?>
            <p><?php echo htmlspecialchars($rows['a_answer']); ?></p>
            <?php
        }
        ?>
        </div>
        <?php
    }
} else {
    ?>
    <div id="answers">
        <p style="color: red;">There doesn't seem to be anything here</p>
    <?php
}

$sql3 = "SELECT view FROM $tbl_name WHERE id='$id'";
$result3 = mysqli_query($conn, $sql3);
$rows = mysqli_fetch_array($result3);
$view = $rows['view'];

// if have no counter value set counter = 1
if(empty($view)) {
    $view = 1;
    $sql4 = "INSERT INTO $tbl_name(view) VALUES('$view') WHERE id='$id'";
    $result4 = mysqli_query($conn, $sql4);
}

// count more value
$addview = $view+1;
$sql5 = "update $tbl_name set view='$addview' WHERE id='$id'";
$result5 = mysqli_query($conn, $sql5);
mysqli_close($conn);
?>
    </div>
    <h3>Post A Reply:</h3>
    <form name="form1" method="post" action="add-answer" autocomplete="off">
    <label>Reply: </label>
<?php
if ($locked == 1) {
    echo '<textarea name="a_answer" id="a_answer" style="width: 800px;" readonly> This topic is locked! </textarea><br>';
} else if ($_SESSION['logged_in'] != true) {
    echo '<textarea name="a_answer" id="a_answer" style="width: 800px;" readonly>⛔ You must login to reply! ⛔</textarea><br>';
} else {
    echo '<textarea name="a_answer" id="a_answer" maxlength="300" required style="width: 800px;"></textarea><br>
    <div class="g-recaptcha" data-sitekey="6LdrxD4UAAAAACAaVAR6U9BjOEDC9-j4QaOzBsFh"></div>
    <input type="submit" name="submit" value="Submit">
    <input type="reset" name="reset" value="Reset">';
}
?>
    <input name="id" type="hidden" value="<?php echo $id; ?>">
    </form>
    </div>
</body>

ajaxhandler.php:

<?php

session_start();

$detail = $_SESSION['detail'];
$id = $_SESSION['id'];

if (!empty($_POST['action'])) {
    if ($_POST['action'] == 'editform') {
        ?>

        <style>
            #post, #editPostButton {
                display: none;
            }

            #saveButton {
                border: none; outline: 0; background-color: #D8D8D8; margin-left: -5px;
            }
        </style>

        <form id="editForm">
            <textarea name="detail"><?php echo $detail; ?></textarea><br>
            <input type="button" id="saveButton" value="Save">
        </form>
        <?php
    }
    if ($_POST['action'] == 'saveform') {
        // do save process to db
        // echo out a new static post html block

        $host = "host"; // Host name 
        $user = "username"; // Mysql username 
        $password = "password"; // Mysql password 
        $db_name = "database"; // Database name 
        $tbl_name = "fquestions"; // Table name 

        // Connect to server and select databse.
        $conn = mysqli_connect($host, $user, $password)or die("cannot connect"); 
        mysqli_select_db($conn, $db_name)or die("cannot select DB");

        $sql = "UPDATE $tbl_name SET detail = '$detail' WHERE id=$id";
        $result = mysqli_query($conn, $sql);
    }
}
?>

1 个答案:

答案 0 :(得分:1)

您可以通过两种方式切换编辑表单。

  1. 使用ajax调用加载更多html(子部分,而不是整个html文档),并根据操作用新的html块替换现有元素。单击编辑按钮,它调用ajax以“获取表单块”,然后用它替换页面上的一些插槽。提交表单,抛出该表单,并将其替换为新的静态文本块。这通常是一种更清洁的方式来处理它。

  2. 首次加载php脚本时,在html DOM中包含所有相关位。有许多部分 隐藏 。然后单击某些按钮或执行操作会根据这些操作显示/隐藏元素。这样更容易,但不是很干净,因为所有表单提交元素和操作以及原始静态部分都在每个常规页面加载的HTML中。

  3. 在编辑按钮单击上加载编辑表单并交换内容块的示例:

    基本静态HTML框架(从首次加载main.php开始):

    <p id="post">[the original post html here]</p>
    
    <?php if ($editPost == true) { /* dont bother if they have no edit rights */?>
    <input type="button" id="editPostButton" value="Edit" data-postId="<?php echo $postId;?>">
    <div id="editFormBlock"></div>
    <?php }?>
    

    脚本区域(需要jquery):

    <script language="Javascript" type="text/javascript">
    $(document).ready(function() {
    
        // for clicking on the edit button, to grab the edit form
        $("#editPostButton").on('click',function(e){
            e.preventDefault();
            $.post(
                'ajaxhandler.php',
                { action: 'editform', postid: $(this).data('postId') },
                function(htmlReturn){
                    $("#editFormBlock").html( htmlReturn ); // replace editForm content
                },
                'HTML'
            );
        });
    
        // for clicking the save button for a edit form
        // using .on so it catches dynamically added content
        $("#editFormBlock").on('click',"#saveButton",function(e){
            e.preventDefault();
            var data = $("#editForm").serializeArray();
                data.push({name: 'action', value: 'saveform'});
            $.post(
                'ajaxhandler.php',
                data,
                function(htmlReturn){
                    $("#post").html( htmlReturn ); // replace static post content
                    $("#editFormBlock").html( '' ); // clear edit form out
                },
                'HTML'
            );
        });
    
    });
    </script>
    

    ajaxhandler.php

    // Have blocks that pertain to the $_POST['action']
    if (!empty($_POST['action'])) {
        if ($_POST['action'] == 'editform') {
    
            // do a database select on using the postId
            // grab the data you wish to use in the edit form
    
            // build a form and echo it out for the ajax return
            echo '
            <form id="editForm">
                <input type="hidden" name="postId" value="'. $row['id'] .'">
                <textarea name="detail">'. $row['detail'] .'</textarea>
                <input type="button" id="saveButton" value="Save">
            </form>
            ';
        }
        if ($_POST['action'] == 'saveform') {
    
            // put your "save to database" code here
            // that uses $_POST['postId'], $_POST['detail'] etc
    
            // after saving, grab a fresh copy of the post
            // and then echo out a new static html #post content
            echo htmlspecialchars($row['detail']);
        }
    }
    

    我希望这很清楚,以便能够立足于你想做的事情。您可以执行更多操作,使用额外的errorBlock来显示错误和处理结果。你甚至可以推出一些动画。无尽的可能性。

    注意:我应该警告您,这完全基于您的示例,您只显示一个帖子和一个编辑表单。这使用“ID”,它必须在页面上是唯一的。如果您打算在一个页面上倾注多个帖子,则需要调整所有内容以使用类和枚举ID来保持唯一性。

相关问题