Introduction to Client-Side Interactivity

Welcome to the third lesson in our course on building an image generation web application with PHP Laravel! In the previous lessons, we created the HTML structure for our application and styled it with CSS. We now have a polished interface with tabs, form controls, and containers for displaying generated images and image history.

At this stage, though, the application is still static. Clicking the buttons does not yet switch tabs, submit prompts, or display results. This is where JavaScript comes in. JavaScript adds the behavior that makes the interface interactive and responsive.

In this lesson, we will write the client-side code that allows users to:

  • switch between the Generate Image and View History tabs,
  • read values from the form,
  • send requests to the backend API,
  • and display generated images on the page.

Our script.js file will act as the bridge between the user interface and the Laravel backend.

Organizing the Frontend Files

Before writing the JavaScript, let’s confirm the file structure we are using in this course so it stays consistent with the earlier units.

In our Laravel project:

  • the Blade template lives in resources/views
  • static assets like CSS and JavaScript live in public

Here is the structure we will use:

This matches the structure used throughout the project:

  • resources/views/index.blade.php contains the HTML interface
  • public/css/style.css contains the styling
  • public/js/script.js contains the frontend logic

Now let’s begin by implementing tab navigation.

Implementing Tab Navigation

Our application has two main tabs:

  1. Generate Image
  2. View History

We need a function that hides all tab sections and then shows only the one the user selected.

Add the following to public/js/script.js:

This function works in two steps:

  1. It selects all elements with the class .tab-content and hides them.
  2. It selects the tab whose id matches tabName and displays it.

Our Blade template already connects the buttons to this function:

That means:

  • clicking Generate Image shows the generate section
  • clicking View History shows the history section

Because this function works with all elements using the .tab-content class, it will also support additional tabs later without needing extra logic.

Building the Image Generation Function

Now let’s implement the main feature of the application: generating an image from a text prompt.

In earlier lessons, we added both:

  • a text input with id="prompt"
  • an aspect ratio dropdown with id="aspect-ratio"

That means our JavaScript should read both values and send them to the backend.

Here is the full generateImage() function:

Now let’s break this function down step by step.

Step 1: Capture User Input

First, we retrieve the values entered or selected by the user:

This is important because our form includes both:

  • the prompt text
  • the selected aspect ratio

The aspect ratio dropdown was added in earlier lessons specifically so users can control the image dimensions, so we should make sure that value is included in the request.

Step 2: Get References to UI Elements

Next, we retrieve the elements we need to update while the request is being processed:

These references allow us to:

  • show a loading message,
  • temporarily hide the button,
  • and display the generated image when it arrives.
Step 3: Validate Input

Before making the request, we confirm that the user actually entered a prompt:

If the prompt is empty, we stop the function early and show an alert.

Step 4: Update the UI for the Loading State

Before the API call begins, we update the page so the user gets immediate feedback:

This does three things:

  • shows the loading message,
  • hides the generate button,
  • clears any previously displayed image.
Step 5: Send Data to the Backend

Now we send the request to the Laravel backend:

Notice that we now send both pieces of form data:

  • user_input
  • aspect_ratio

This is important because the backend route is already expecting those fields:

  • user_input for the prompt
  • aspect_ratio for the selected dimensions

This keeps the frontend aligned with the backend API and allows the image generation service to build prompts that reflect the user’s aspect ratio choice.

Step 6: Handle the API Response

Once the backend responds, we parse the JSON and restore the UI:

This code:

  • hides the loading message,
  • shows the generate button again,
  • checks whether an error was returned,
  • and displays the generated image if successful.
Step 7: Catch Unexpected Errors

If the request fails entirely, we handle that in a .catch() block:

This ensures the interface remains usable even if something goes wrong.

Summary and Next Steps

In this lesson, we added the frontend behavior that makes our application interactive.

We:

  1. created the openTab() function for tab navigation,
  2. kept the project structure consistent with Laravel by using:
    • resources/views/index.blade.php
    • public/js/script.js
  3. implemented the generateImage() function,
  4. retrieved both the prompt and the selected aspect ratio from the form,
  5. sent both values to the backend API,
  6. and displayed the returned image on the page.

At this point, users can:

  • type a prompt,
  • choose an aspect ratio,
  • submit the form,
  • and view the generated result.

In the next lesson, we will build the history functionality so users can load and review previously generated images.

Sign up
Join the 1M+ learners on CodeSignal
Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal