AJAX响应应该更新while循环结果中的所有记录

时间:2017-11-24 15:17:28

标签: javascript php jquery ajax

我摸不着头脑但是我无法得到理想的结果 在while循环中,所有注释都被提取。每个评论都有一个带有字体真棒星座的按钮,使这个评论最受欢迎。 我想在任何评论的星形按钮上显示登录用户在鼠标悬停时最喜欢的评论总数。 (因此,用户可能知道我最喜欢的评论数量。

我正在使用jQuery AJAX方法更新收藏评论的记录 一切都完美正常,最喜欢的评论正在mysql记录中更新,并且AJAX响应运行良好。

我的实际问题是:
AJAX响应仅适用于单击的按钮。 但我想要两件事

  1. 当点击任何评论的收藏按钮时,该按钮应切换为最喜欢的按钮(空星将变成完整的星形),仅适用于此评论,其中一个被点击为最喜欢的

    < / LI>
  2. 此用户最喜欢的评论总数应显示在鼠标悬停时每个评论的收藏按钮的标题文本中。因此,用户可以轻松查看我最喜欢的评论数量。 (刷新页面后,它很好地显示了结果。但是在没有重新加载页面的情况下,应该在AJAX响应的帮助下工作)

  3. 我想在按钮标题中显示登录用户的最喜欢评论总数,并在点击事件中更新它们。我给出了下面的代码,这样你就可以很容易地理解我想做什么了

    输出区号

    <?php
    $query = mysqli_query($conn, "select * from `comments`");
    while ($row = mysqli_fetch_array($query)) {
        ?>
        Comments: <?php echo $row['usercom']; ?><br>
        <?php
        $query1 = mysqli_query($conn, "select * from `favcoms` where fcom_id='" . $row['cid'] . "' and sessionid='" . $_SESSION['id'] . "'");
        $query2 = mysqli_query($conn, "select * from `favcoms` where sessionid='" . $_SESSION['id'] . "'");
        ?>
        <span class="show_like<?php echo $row['cid']; ?>">
            <?php if (mysqli_num_rows($query1) > 0) { ?>
                <button value="<?php echo $row['cid']; ?>" class="unfavcom"><i title="Remove from Favorite? - (<?php echo mysqli_num_rows($query2); ?>/20)" class="fa fa-star" aria-hidden="true"></i></button>
            <?php } else { ?>
                <button value="<?php echo $row['cid']; ?>" class="favcom"><i title="Favorite Comment - (<?php echo mysqli_num_rows($query2); ?>/20)" class="fa fa-star-o" aria-hidden="true"></i></button>
             <?php } ?>
         </span>
         <?php
    }
    ?>
    

    AJAX部分在这里

    $(document).ready(function() {
    
        $(document).on('click', '.favcom', function() {
            var id=$(this).val();
            $.ajax({
                type: "POST",
                url: "like.php",
                data: {
                    id: id,
                    like: 1,
                },
                success: function() {
                    showLike(id);
                }
            });
        });
    
        $(document).on('click', '.unfavcom', function() {
            var id=$(this).val();
            $.ajax({
                type: "POST",
                url: "like.php",
                data: {
                    id: id,
                    like: 1,
                },
                success: function() {
                    showLike(id);
                }
            });
        });
    
    });
    
    function showLike(id) {
            $.ajax({
                url: 'show_like.php',
                type: 'POST',
                async: false,
                data:{
                    id: id,
                    showlike: 1
                },
                success: function(response){
                    $('.show_like'+id).html(response);
    
                }
            });
        }
    

    和show_like.php这里

    <?php
    session_start();
    include('conn.php');
    
    if (isset($_POST['showlike'])) {
        $id = $_POST['id'];
        $query3=mysqli_query($conn, "select * from `favcoms` where fcom_id='".$id."' and sessionid='".$_SESSION['id']."'");
        $query4 = mysqli_query($conn,"select * from `favcoms` where sessionid='".$_SESSION['id']."'");
        $numFavs = mysqli_num_rows($query4);
        if (mysqli_num_rows($query3) > 0) {
            echo '<button class="mycomoptions unfavcom" value="'.$id.'"><font color="#00CC00"><i title="Remove from Favorite? - ('.$numFavs.'/20)" class="fa fa-star" aria-hidden="true"></i></font></button>';
        } else {
            echo '<button class="mycomoptions favcom" value="'.$id.'"><font color="#00CC00"><i title="Remove from Favorite? - ('.$numFavs.'/20)" class="fa fa-star-o" aria-hidden="true"></i></font></button>' ;
        }   
    }   
    ?>
    

    like.php here

    <?php
    include ('conn.php');
    session_start();
    
    if (isset($_POST['like'])) {        
    
        $id = $_POST['id'];
        $query = mysqli_query($conn,"select * from `favcoms` where fcom_id='$id' and sessionid='".$_SESSION['id']."'") or die(mysqli_error());
    
        if (mysqli_num_rows($query) > 0) {
            mysqli_query($conn,"delete from `favcoms` where sessionid='".$_SESSION['id']."' and fcom_id='$id'");
        } else {
            mysqli_query($conn,"insert into `favcoms` (sessionid,fcom_id) values ('".$_SESSION['id']."', '$id')");
        }
    }       
    ?>
    

    当用户喜欢任何评论时,每个评论都应该增加喜欢评论的总数,但是只更新那个用户最喜欢的评论(在AJAX响应中)。刷新页面后,每条评论的最喜欢评论总数显示正常。

    点击的按钮类将被更改,或者应该在空星和彩色星之间的每次点击时切换。因此,只有点击按钮才会更改字体真棒星级,但应更新所有评论的用户最喜欢的评论。

    希望我已经解释得很好。如果您需要进一步解释,请在评论中询问我。

    P.S =我在配置连接文件中使用PDO方法

2 个答案:

答案 0 :(得分:1)

这比你要求的要多,但这似乎是分享一些我希望有用的知识的好机会。

我无法找到您的“评论总数”代码,因为您应该尽可能多地分离逻辑和演示文稿。所以我尽量不要切换进出PHP,除非我放弃了值。这导致了一种AJAX方法,它使服务器返回JSON而不是HTML。你要求服务器做一些业务逻辑,然后告诉你结果;不是如何格式化你的页面。

  警告一:我不使用mysqli;我使用自己的数据抽象类,所以我不必处理PDO与mysqli和ODBC等的怪癖。因此,我的代码可能无法充分利用mysqli。

     

警告二:这不是在浏览器中测试的,因此可能会出错。这是为了显示概念,而不是复制和粘贴代码。

连接

<?php
/**
 * conn.php
 */

// Create connection
$db = new mysqli($servername, $username, $password, $dbname);

// Check connection
if ($db->connect_error) {
    die("Connection failed: " . $db->connect_error);
}

初始页面

<?php
require ('conn.php');

// get user's total number of likes
$query = "SELECT COUNT(sessionid) AS total_faves FROM favcoms WHERE sessionid=?";
$result = $db->prepare($query);
$result->bind_param("s", $_SESSION['id']);
$result->execute();

$total = '';
if($row=$result->fetch_object()) {
    $total = $row->total_faves;
} else {
    // do something on failure
}

// now get all comments with optional sessionid if it has been favorited. coalesce turns null into '' 
$query = 
    "SELECT DISTINCT c.cid, c.usercom, coalesce(f.sessionid, '') " . 
    "FROM comments AS c " . 
    "LEFT JOIN favcoms AS f ON c.cid=f.fcom_id AND sessionid=? ";

$comment = $db->prepare($query);
$comment->bind_param("s", $_SESSION['id']);
$comment->execute();

?>

- 剪辑 -

HTML部分:

<input type="hidden" id="total-faves" value="<?= $total ?>" />

<?php while($row = $comment->fetch_object()): ?>

    <div id="comment-row-<?= $row->cid ?>" class="commentRow">
        Comments: <?= $row->usercom ?>
        <button id="button-<?= $row->cid ?>" 
                val="<?= $row->cid ?>" 
                class="comment-button <?php $row->sessionid ? 'favcom' : 'unfavcom' ?>">
            <i title="Favorite Comment - (<?= $total ?>/20)"
               class="fa fa-star<?php $row->sessionid ? '' : '-o' ?>" 
               aria-hidden="true">
            </i>
        </button> 
    </div>

<?php endwhile; ?>

如果评论是收藏夹,则图标类将为fa fa-star,否则为fa fa-star-o。 Javascript稍后会做一些魔术......

现在,由于您对like.php的调用有效地切换了收藏夹(在数据库中添加或删除),只需使用它来返回结果:

like.php

<?php
/**
 * like.php
 */

header('Content-Type: application/json');  // <--- Don't miss this!

require ('conn.php');

if (isset($_POST['id'])) {        

    $id = $_POST['id'];
    $query = "select * from `favcoms` where fcom_id=? and sessionid=?";

    $stmt = $db->prepare($query);
    $stmt->bind_param("s", $id,$_SESSION['id']);
    $stmt->execute(); // should check if this succeeds.

    // if there is a result, delete it.  if not, add it.
    if ($stmt->fetch_object()) {
        $query = "delete from `favcoms` where fcom_id=? and sessionid=?";
        $status = 'not liked';
    } else {
        $query = "insert into `favcoms` (fcom_id,sessionid) values (?,?)";
        $status = 'liked';
    }

    $stmt = $db->prepare($query);
    $stmt->bind_param("s", $id, $_SESSION['id']);
    $stmt->execute();

    // now find total number of faves and return value
    $query = "SELECT COUNT(sessionid) AS total_faves FROM favcoms";
    $result = $db->query($query);

    $total = '';
    if($row = $result->fetch_object()) {
        $total = $row->total_faves;
    }

    echo json_encode(array(
        'result' => 'success',
        'total' => $total,
        'status' => $status
        ));
} else {

echo json_encode(array(
    'result' => 'fail'
    ));    
}

的Javascript

$(document).ready(function() {

    // dynamically generated buttons must reference a parent element
    $(document).on('click', '.comment-button', function() {
        var id=$(this).val();
        $.ajax({
            type: "POST",
            url: "like.php",
            data: {
                id: id,
            },
            success: function(data) {

                var total = data.total;
                $('#total-faves').val(total);
                toggleButton(id,data);
                updateTitles();
            }
        });
    });

    // initialize titles here. It could be done in PHP output, but javascript needs to do it later anyway...
    updateTitles();


});


function toggleButton(id,data) {

    var status = data.status;
    var button = $('#button-'+id);
    var icon = button.children('i').eq(0);

    if(status=='liked') {
        button.removeClass('unfavcom').addClass('favcom');
        icon.removeClass('fa fa-star-o').addClass('fa fa-star');
    } else {
        button.removeClass('favcom').addClass('unfavcom');
        icon.removeClass('fa fa-star').addClass('fa fa-star-o');
    }
}

function updateTitles() {

    var total = $('#total-faves').val();
    $('.fa fa-star').prop('title',"Favorite Comment - ("+ data.total +"/20)");
    $('.fa fa-star-o').prop('title',"Remove from Favorite? - ("+ data.total +"/20)");
}

你的问题的答案就在上面的函数中 - 但为了实现这一目标,我需要将AJAX更改为使用JSON而不是HTML。然后,你可以通过jquery看到所有可用的魔法。您需要知道的是哪些行被收藏,您可以使用jquery设置标题,类等。

- 编辑 - 我只是注意到我没有检查AJAX数据的成功或失败。您可以随时检查以向用户提供信息。我只是忘了。

答案 1 :(得分:1)

我不认为您每次用户进行更改时都必须转到服务器并带回计数,当您实际上只需添加或减去每个人时,如果评论被喜欢或不喜欢,分别。所以你可以做的是给按钮提供一些其他类(对于它们favcomunfavcom,所以你可以用一种简单的方式访问它们中的第一个),如下所示:

<button value="<?php echo $row['cid']; ?>" class="unfavcom favbutton"><!-- --></button>
<!-- -->
<button value="<?php echo $row['cid']; ?>" class="favcom favbutton"><!-- --></button>

然后,您可以创建一个功能,在用户喜欢/不喜欢评论后更改标题:

function updateCounts(delta){
    var newCount = (
        Number(
            $('.favbutton i:first') // Grabs the first button
            .attr('title') // Grabs its title (i.e. Favorite Comment - 10/20)
            .split('- ')[1] // Splits the string by the dash and takes the second part (i.e. 10/20)
            .split('/')[0] // Splits the string by the slash and takes the first part (i.e. 10)
        ) +
        delta // Adds the delta (which could be 1 or -1)
    );
    $('.unfavcom i').each(function(){
        $(this).attr('title', 'Remove from Favorite? - '+newCount+'/20');
    });
    $('.favcom i').each(function(){
        $(this).attr('title', 'Favorite Comment - '+newCount+'/20');
    });
}

最后,更新代码的success回调,以便他们调用新函数:

$(document).on('click', '.favcom', function() {
    // ...
    $.ajax({
        // ...
        success: function() {
            updateCounts(1);
        }
    });
});

$(document).on('click', '.unfavcom', function() {
    // ...
    $.ajax({
        // ...
        success: function() {
            updateCounts(-1);
        }
    });
});

如果这样就足够了,您可以保存showlike的函数和PHP脚本。如果你真的想去服务器,那么你可以重用我刚给你的代码,但让服务器返回数字而不是我做的所有计算,更改实际计数的delta只是全部更新

<强>更新

对于你的第二个问题(将标志限制为20),当不可能进行更多投票时更容易提醒,这只需要你检查数据库,如下所示:

<?php
// like.php
//...
if (isset($_POST['like'])) {
    // ...
    if (mysqli_num_rows($query) > 0) {
        // ...
    } else {
        $query = mysqli_query($conn,"select count(*) from `favcoms` where sessionid='".$_SESSION['id']."'") or die(mysqli_error());
        $row = $query->fetch_row();
        if($row[0] === 20){
            exit('Maximum upvotes reached');
        }
        mysqli_query($conn,"insert into `favcoms` (sessionid,fcom_id) values ('".$_SESSION['id']."', '$id')");
    }
}

然后您就可以使用Javascript让用户知道,如下所示:

$(document).on('click', '.favcom', function() {
    // ...
    $.ajax({
        // ...
        success: function(response) {
            if(response.length){
                //There's an error
                alert(response);
                return;
            }
            updateCounts(1);
        }
    });
});

现在,如果您还想禁用该操作,可以使用以下内容切换按钮:

function updateCounts(delta){
    //...
    if(newCount === 20){
      // Limit reached, hide favcoms
      $('.favcom').hide();
    }else{
      // Not there yet, show favcoms
      $('.favcom').show();
    }
    //...
}