Why is that Laravel is not working with JavaScript and AJAX request?

73 Views Asked by At

I am working on a Laravel Project! The project is based on a Social Network, where user can create account, have access to post, follow each other and reply to each other posts. Also they will be notified if anybody or who they follow post any updates in realtime. I have been using pure php for this work with js and its working fine, but I encountered some errors when it comes to the realtime post notification that all clients will receive, during my research I came accross websocket and I learnt that it is only web socket that can do that. So I tried switching to Laravel since they said there is a package there which is pusher that can work for the websocket and not all hosting providers have websocket.

Now the main problem is that my javascript is not working with the laravel at all when it comes to posts successful or error notification that I have designed perfectly which was working on the pure PHP before. No signs of working, even the word limit notification, nothing is even working. I got fraustrated.. Even when post is successful instead of returning the JS successful message, it is only returning JSON which I have been battling with. Also I want the ajax to jus make request to the server without refreshing the page when the post is submitted or having any error. I will provide the code now Thanks so much for the solutions that will be provided from this community.

>! HTML CODE (home.blade.php)
<!-- Add this at the top of your file to include Laravel Mix -->
<script src="{{ mix('js/app.js') }}" defer></script>
@extends('layouts.app')

@section('content')


<!-- ======= Header ======= -->
@include('partials.navbar')

<!-- ======= Sidebar ======= -->
@include('partials.sidebar')

<!-- <main id="main" class="main"> -->

<div class="main-content">
    <button id="notificationButton" onclick="refreshContent()" class="notificationButton">New Updates (<span id="newPostsCount">0</span>)</button>

    <!-- <div class="post-container" id="postContainer">
        <div class="user-info">
            <img src="{{ asset('img/user8.jpeg')}}" alt="User">
            <textarea id="postContent" oninput="updateWordCount()" placeholder="Wetin dey your mind?" required></textarea>
            <div id="suggestions"></div>
        </div>
        <div class="post-actions">
            <div class="word-count" id="wordCount">0/50</div>
            <button id="postButton" onclick="postContent()" class="post-button disabled">Post</button>
        </div>
    </div> -->
    <div class="post-container" id="postContainer">
        <!-- Add the CSRF token within the form -->
        <form id="postForm" method="POST" action="{{ route('post.store') }}">
            @csrf
            <div class="user-info">
                <img src="{{ asset('img/user8.jpeg') }}" alt="User">
                <!-- <textarea id="postContent" name="postContent" oninput="updateWordCount()" placeholder="Wetin dey your mind?" required></textarea> -->
                <textarea id="postContent" name="postContent" oninput="updateWordCount()" placeholder="Wetin dey your mind?"></textarea>
                <div id="suggestions"></div>
            </div>
            <!-- ... your existing form code ... -->
            <div class="post-actions">
            <div class="word-count" id="wordCount">0/50</div>
            <button id="postButton" onclick="postContent()" class="post-button disabled">Post</button>
        </div>
        </form>
    </div>

    <div id="notification" class="notification"></div>

    <hr>


    <div class="post-feed" id="contentContainer">



    </div>

    <!-- Loading spinner placeholder -->
    <div id="loadingSpinner">
        <!-- Add your loading spinner content here -->
        Loading...
    </div>

    <div class="the-post-container" id="popPostContainer">
        <div class="modal-content">
            <!-- Close button -->
            <span class="close-btn" onclick="closePostContainer()">&times;</span>
            <div class="user-info">
                <img src="{{ asset('img/user8.jpeg')}}" alt="User">

                <textarea id="postContent" oninput="updateWordCount()" placeholder="Wetin dey your mind? "></textarea>
                <div id="suggestions"></div>
            </div>
            <div class="post-actions">
                <div class="word-count" id="wordCount">0/50</div>
                <!-- <emoji-picker for="postContent"></emoji-picker> -->
                <button id="postButton" onclick="postContent()" class="post-button disabled">Post</button>
            </div>
        </div>
    </div>

    <!-- <a href="#" onclick="togglePostContainer()"> -->
    <a href="#" onclick="openPostContainer()">
        <div class="edit-post">
            <i class="bi bi-pencil-square post-icon"></i>
            <span class="editpost-text">Post Update</span>
        </div>
    </a>


    @include('partials.bottom-navbar')
</div>

<div class="side-content">
    <div class="trending-section">
        <h2>Trends on FpiUpdates <i class="fa-solid fa-arrow-trend-up"></i></h2>
        <!-- <ul id="trendingList"></ul> -->
        <?php
        //include "posts.php"
        ?>
        <div id="trendsContainer">
            <!-- Trends will be displayed here -->
        </div>

    </div>

    <hr>

    <?php
    // include "include/userList.php";
    ?>


    <hr>

    <h2>Latest Job Posts</h2>
    <ul class="job-posts">
        <li>
            <h3>Sales Representative</h3>
            <p>Jusrite Ota</p>
            <button class="apply-button">Apply</button>
        </li>
        <li>
            <h3>Senior Software Developer</h3>
            <p>Dangote Cement, Lagos</p>
            <button class="apply-button">Apply</button>
        </li>
        <!-- Add more job posts as needed -->
    </ul>

    <hr>

    <!-- Footer -->
    <footer>
        <ul class="footer-links">
            <li><a href="#">Terms of Service</a></li>
            <li><a href="#">Privacy Policy</a></li>
            <li><a href="#">Cookie Policy</a></li>
            <li><a href="#">Accessibility</a></li>
            <li><a href="#">Ads info</a></li>
            <li><a href="#">More</a></li>
        </ul>
        <p>© 2023 FpiUpdates.</p>
    </footer>
</div>
<!-- </main> -->
@endsection
@section('script')
<script src="{{ asset('js/main.js') }}"></script>
<script src="{{ asset('js/username.js') }}"></script>
<!-- <script src="{{ asset('js/text-format.js')}}"></script> -->
<script src="{{ asset('js/post.js') }}" defer></script>
<script src="index.js"></script>
@endsection

JS Code in post.js

var wordLimit = 50;

function updateWordCount() {
    var textarea = document.getElementById('postContent');
    var wordCount = document.getElementById('wordCount');
    var postButton = document.getElementById('postButton');

    // Detect hashtags and change their color
    var content = textarea.value.replace(/#(\w+)/g, '<span class="hashtag">#$1</span>');
    textarea.innerHTML = content;

    var words = textarea.value.split(/\s+/).filter(function (word) {
        return word.length > 0;
    });

    wordCount.textContent = words.length + '/' + wordLimit;

    textarea.style.height = "1";
    textarea.style.height = (textarea.scrollHeight) + "px";

    if (words.length === 0) {
        postButton.classList.add('disabled');
        textarea.classList.add('exceeded');
        window.alert('Content cannot be empty!');  // Show an alert for empty content
    } else if (words.length > wordLimit) {
        postButton.classList.add('disabled');
        textarea.classList.add('exceeded');
        window.alert('Word limit exceeded. Please limit your post to ' + wordLimit + ' words.');
    } else {
        postButton.classList.remove('disabled');
        textarea.classList.remove('exceeded');
    }
}


function postContent() {
    window.alert('Button clicked');  // Debugging line

    var textarea = document.getElementById('postContent');
    var words = textarea.value.split(/\s+/).filter(function (word) {
        return word.length > 0;
    });

    if (words.length === 0) {
        window.alert('Please enter some content before posting.');  // Alert for empty content
        return;
    }

    if (words.length > wordLimit) {
        window.alert('Word limit exceeded. Please limit your post to ' + wordLimit + ' words.');  // Alert for word limit exceeded
        return;
    }

    const postContent = textarea.value.trim();

    // Make an AJAX request to the server
    fetch('/post', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content,
        },
        body: 'postContent=' + encodeURIComponent(postContent),
    })
    .then(response => {
        if (!response.ok) {
            throw new Error('Error posting content. Please try again.');
        }
        return response.json();
    })
    .then(data => {
        // Successful response
        showNotification(data.message, true);

        // Update only the new posts count and button visibility
        newPostsCount++; // Assuming you increment the count
        updateNewPostsButton();

        clearPostForm();
    })
    .catch(error => {
        // Error response
        showNotification(error.message);
    });
}


function showNotification(message, success = false) {
    const notification = document.getElementById('notification');
    notification.innerHTML = message;

    if (success) {
        notification.style.backgroundColor = '#4CAF50'; // Green color for success
    } else {
        notification.style.backgroundColor = '#ff3333'; // Red color for error
    }

    notification.style.display = 'block';

    setTimeout(function () {
        notification.style.display = 'none';
    }, 3000);
}

function clearPostForm() {
    document.getElementById('postContent').value = '';
    updateWordCount();
}

app.blade.php

<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
@include('partials.head')
<body>
    <div id="app">
        <main id="main" class="main">
            @yield('content')
        </main>
    </div>
    @yield('scripts')
</body>
</html>

PostController Code

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Post;
use Illuminate\Support\Facades\Auth;
use App\Rules\MaxWords;

class PostController extends Controller
{
    public function __construct()
    {
        $this->middleware('auth');
    }

    public function store(Request $request)
    {
        // Validate the request
        $validatedData = $request->validate([
            'postContent' => ['required', new MaxWords(50)],
        ]);

        // Store the post in the database
        $post = Post::create([
            'content' => $validatedData['postContent'],
            'user_id' => Auth::id(),
        ]);

        // Return a response with a 201 Created status code
        return response()->json(['message' => 'Post created successfully'], 201);
    }
}

Post Model (Post)

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    protected $fillable = ['content', 'user_id'];

    public function user()
    {
        return $this->belongsTo(User::class);
    }
}

The Route (web.php)

<?php

use App\Http\Controllers\Auth\RegisterController;
use App\Http\Controllers\AuthController;
use App\Http\Controllers\HomeController;
use App\Http\Controllers\PostController;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Route;


Route::middleware(['auth'])->group(function () {
    Route::get('/home', [HomeController::class, 'index'])->name('user.home');
    // Add other authenticated routes as needed
    // Route::post('/posts', [PostController::class, 'store'])->name('posts.store');
    Route::post('/post', [PostController::class, 'store'])->name('post.store');
});

// Authentication routes
Route::get('/login', [AuthController::class, 'showLoginForm'])->name('login');
Route::post('/login', [AuthController::class, 'login']);
Route::get('/register', [RegisterController::class, 'showRegistrationForm'])->name('register');
Route::post('/register', [RegisterController::class, 'register']);

// Laravel default authentication routes
Auth::routes();

// Additional routes
Route::get('/profile', function () {
    return view('profile');
})->name('profile');

Route::get('/search', function () {
    return view('search');
})->name('search');

I have used chatGPT and Bard and videos but still same thing

I want the post to be submitted successfully without the webpage been refreshed I want the user to be notified using the js notification written when post is successful, when they tried to click the button without entering anything and also be notified when followed user droped updates

0

There are 0 best solutions below