Saving selected checkbox from view in Codeignitor/php

So for context I currently have an HTML form page where I allow the user to create a new book entry. As part of the form the user needs to choose between 3 different checkboxes (Horror, Fantasy, and Mystery). Will add more options later down the line.

The problem I am having is that when I’m trying to save which option are chosen from the checkboxes into the same SQL entry. But all the examples I’ve found for checkboxes want to create a new SQL entry for each option chosen. It seems to want to create the new entry for each option chosen even if every other variable in the entry stays the same. An example would be the following stack overflow post from a few years ago where (At least to my understanding of the post/code) implies that in the controller script I need to go through each value in the array and create a new SQL entry for it. I would rather not do this as it will mass populate the table.

Saving the selected rows by checkbox to database in php

I am currently using Codeigniter 4, HTML/CSS, and PHP to make the website. I have the code for the HTML form below. The PHP controller is set up to receive all the other information from the form. I am only missing the info from BookType[]

<form method="post" id="add_create" name="add_create" action="<?= '/public/book-submit2' ?>">
  <!-- Other form inputs -->
  <div class="col-md-4">
    <div class="form-group">
      <label class="text-secondary" for="BookType"><em>*Type Of book:</em></label>
      <p>
      <form required>
        <input type="checkbox" id="Horror" name="BookType[]" value="Horror">
        <label for="Horror"> Horror</label><br>
        <input type="checkbox" id="Fantasy" name="BookType[]" value="Fantasy">
        <label for="Fantasy"> Fantasy </label><br>
        <input type="checkbox" id="Mystery" name="BookType[]" value="Mystery">
        <label for="Mystery"> Mystery </label><br>
      </form>
    </div><!-- /.form-group -->
  </div><!-- /.col -->
</form>

Is there something I am not realizing with the PHP code or SQL? I’ve only been using SQL and CodeIgnitor for a few months.

To store multiple checkbox values (e.g., “Horror”, “Fantasy”, “Mystery”) from the BookType[] array in a single SQL entry, you can serialize or join the values into a single string before saving them to the database. Then, you can retrieve and manipulate the data as needed.

Here’s a step-by-step solution:


HTML Form

Your HTML form looks mostly fine, but you have a nested <form> tag, which is unnecessary. Remove the inner <form> tag and keep only one <form>:

<form method="post" id="add_create" name="add_create" action="<?= '/public/book-submit2' ?>">
  <!-- Other form inputs -->
  <div class="col-md-4">
    <div class="form-group">
      <label class="text-secondary" for="BookType"><em>*Type Of book:</em></label>
      <p>
        <input type="checkbox" id="Horror" name="BookType[]" value="Horror">
        <label for="Horror"> Horror</label><br>
        <input type="checkbox" id="Fantasy" name="BookType[]" value="Fantasy">
        <label for="Fantasy"> Fantasy</label><br>
        <input type="checkbox" id="Mystery" name="BookType[]" value="Mystery">
        <label for="Mystery"> Mystery</label><br>
      </p>
    </div><!-- /.form-group -->
  </div><!-- /.col -->
  <button type="submit">Submit</button>
</form>

Controller Logic

In your CodeIgniter 4 controller, process the BookType[] input:

  1. Retrieve the Checkbox Values: Use $this->request->getVar('BookType').
  2. Join the Array into a String: Use implode() to concatenate the selected values into a comma-separated string.
  3. Save the String to the Database: Store the concatenated string in a single column of your database.

Here’s how your controller method might look:

public function bookSubmit()
{
    helper(['form']);
    
    // Retrieve other form data (e.g., title, author, etc.)
    $title = $this->request->getVar('title');
    $author = $this->request->getVar('author');
    
    // Retrieve selected BookType checkboxes
    $bookTypes = $this->request->getVar('BookType'); // This will be an array
    
    // Handle empty selection (optional)
    if (empty($bookTypes)) {
        return redirect()->back()->with('error', 'Please select at least one book type.');
    }
    
    // Convert the array to a comma-separated string
    $bookTypesString = implode(',', $bookTypes);

    // Save to database (example)
    $data = [
        'title' => $title,
        'author' => $author,
        'book_types' => $bookTypesString, // Store as a single string
    ];

    $bookModel = new \App\Models\BookModel();
    $bookModel->insert($data);

    // Redirect or return success response
    return redirect()->to('/success')->with('message', 'Book entry created successfully!');
}

Database Table

Ensure your database table has a column like this to store the joined values:

CREATE TABLE books (
    id INT AUTO_INCREMENT PRIMARY KEY,
    title VARCHAR(255),
    author VARCHAR(255),
    book_types TEXT -- To store the comma-separated values
);

Retrieving and Displaying Data

When retrieving the book_types column from the database, split the string back into an array using explode():

$bookEntry = $bookModel->find($id);
$bookTypesArray = explode(',', $bookEntry['book_types']);

You can then loop through $bookTypesArray to display the selected book types.


Advantages

  • Single SQL Entry: All selected checkboxes are stored in a single row, avoiding unnecessary table bloat.
  • Easier Updates: When more book types are added, no schema changes are required.
  • Localization: If needed, the data can easily be serialized into JSON instead of using a comma-separated string.

Optional Enhancements

  • JSON Storage: Instead of a comma-separated string, you can use JSON encoding to store the data in a database. JSON makes parsing more structured and flexible:
$bookTypesJson = json_encode($bookTypes);
  • Modify your database column to JSON type (if your DB supports it) or keep it as TEXT for backward compatibility.