Ajax setup for post comment

This tutorial is part of this mini project on topic oriented user community. To see all the sections of this project Click Here

Now, it's time to give focus on following methods in controller PostCommentController.php to store post comments using ajax when submitted under a post.

<?php
namespace App\Http\Controllers;

use App\Models\Comment;
use App\Models\Post;
use Illuminate\Http\Request;

class PostCommentController extends Controller
{
    public function store(Request $request, Post $post)
    {
        $request->validate([
            'comment_text' => 'required|string|max:255',
        ]);

        // Store the comment
        $comment = Comment::create([
            'post_id' => $post->id,
            'user_id' => 0,
            'comment_text' => $request->comment_text,
        ]);

        if ($request->ajax()) {
            return response()->json([
                'success' => 'Comment added successfully!',
                'comment_text' => $comment->comment_text,
                'user_name' => "Demo User", // Assuming a User model with a 'name' attribute
            ]);
        }
    }
}

Now, Let's turn our attention to resources/js/app.js file where JS code of ajax form submission for comment under a post needs to be added after previously added codes. 

$(document).ready(function() {
    $('#post-comment-frm').off('submit').on('submit', function(e) {
        e.preventDefault(); // Prevent the default form submission

        // Clear previous error messages
        $('#error-message').text('');

        // Get form data
        let formData = $(this).serialize();

        // Send AJAX request
        $.ajax({
            url: $(this).attr('action'),
            type: 'POST',
            data: formData,
            success: function(response) {
                // Handle success
                let commentHtml = `
                        <strong>${response.user_name}</strong> says:
                        <br>
                        <span style="color:grey;" class="comment-time" data-timestamp="${new Date().getTime()}"><small>just now</small></span>
                        <p>${response.comment_text}</p>
                `;

                // Insert the new comment just before the form
                $('.comments').append(commentHtml);
                $('.no-comments').html('');

                // Reset the form
                $('#post-comment-frm')[0].reset(); // Clear the form
            },
            error: function(xhr) {
                if (xhr.status === 422) { // 422 Unprocessable Entity (validation error)
                    var errors = xhr.responseJSON.errors;
                    $('#error-message').text(errors.comment_text[0]); // Show the first error message
                } else {
                    // Handle other errors (e.g., server errors)
                    $('#error-message').text('An error occurred. Please try again.');
                }
            }
        });

        return false;
    });
});

// Update time ago every 30 seconds
setInterval(updateTimeAgo, 30000);

// Initial call to set the correct time ago for any existing comments
updateTimeAgo();

function updateTimeAgo() {
    $('.comment-time').each(function() {
        let timestamp = $(this).data('timestamp');
        let timeAgo = getTimeAgo(timestamp);
        $(this).text(`${timeAgo}`);
    });
}

function getTimeAgo(timestamp) {
    let now = new Date().getTime();
    let secondsAgo = Math.floor((now - timestamp) / 1000);

    if (secondsAgo < 60) {
        return `${secondsAgo} second${secondsAgo !== 1 ? 's' : ''} ago`;
    } else if (secondsAgo < 3600) {
        let minutesAgo = Math.floor(secondsAgo / 60);
        return `${minutesAgo} minute${minutesAgo !== 1 ? 's' : ''} ago`;
    } else if (secondsAgo < 86400) {
        let hoursAgo = Math.floor(secondsAgo / 3600);
        return `${hoursAgo} hour${hoursAgo !== 1 ? 's' : ''} ago`;
    } else {
        let daysAgo = Math.floor(secondsAgo / 86400);
        return `${daysAgo} day${daysAgo !== 1 ? 's' : ''} ago`;
    }
}

Now, setting up routes for PostCommentController.php

Route::resource('posts.comments', \App\Http\Controllers\PostCommentController::class);

So, PostCommentController.php and corresponding js code have been setup.

Lastly, setting up navigation links to index page of communities and topics inside resources/layouts/app.blade.php

<ul class="navbar-nav">
    <li class="nav-item">
        <a class="nav-link active" href="/">Home</a>
    </li>
    <li class="nav-item">
        <a class="nav-link active" href="{{ route('topics.index') }}">Topics</a>
    </li>
    <li class="nav-item">
        <a class="nav-link active" href="{{ route('communities.index') }}">Communities</a>
    </li>
</ul>

 Now, we can move on to the next post.

Related Posts


Crud setup for communities

Crud setup for topics

Crud setup for posts