Trongate PHP Framework Docs
Introduction
Quick Start
Basic Concepts
Understanding Routing
Intercepting Requests
Module Fundamentals
Database Operations
Templates
Helpers
Form Handling
Form Validation
Working With Files
Image Manipulation
Working With Dates & Times
Language Control
Security
Tips And Best Practices

Checkboxes and Radio Buttons

Checkboxes and radio buttons use a similar helper pattern as other form elements, with special handling for checked states.

Always do this:

  1. In your view: Use value="1" for checkboxes
  2. In your controller: Convert POST data to boolean for views, integer for database
  3. In your database: Store as 0 or 1

Checkboxes

Use :

PHP
form_checkbox($name, $value = '1', $checked = false, $attributes = []);

Parameters

  • $name (string, required) - The name attribute for the checkbox
  • $value (string|bool|int, optional) - The value attribute. Defaults to '1'
  • $checked (mixed, optional) - Whether the checkbox should be checked. Defaults to false
  • $attributes (array, optional) - Additional HTML attributes. Defaults to []

Recommended Pattern (Best Practice)

For accessibility and improved usability, always wrap the checkbox input directly within the HTML <label> element. This allows users to click the text to toggle the checkbox, increasing the target area.

Note on Validity: Placing the input inside the label (implicit association) is perfectly valid HTML5 and the industry-standard best practice for these elements.

View File
<?php
echo '<label>'; // Start the label wrapper
echo form_checkbox('subscribe', 1, $subscribe_checked);
echo ' Newsletter Subscription'; // Place the text after the input
echo '</label>'; // Close the label wrapper
?>

The Checkbox Reality

Unchecked checkboxes don't submit any data. This is HTML behavior, not Trongate.

When a form submits:

  • Checked checkbox → POST contains subscribe='1'
  • Unchecked checkbox → POST contains no subscribe field
PHP
// After form submission:
$raw_value = post('subscribe', true); 
// If checked: returns '1'
// If unchecked: returns '' (empty string)

Here's something crucial: unchecked checkboxes don't submit anything.

If a checkbox is checked, the form submits its value. If unchecked, the field doesn't appear in the POST data at all.

PHP
// Checkbox was checked
post('subscribe', true); // Returns '1' (or whatever value you set)

// Checkbox was unchecked
post('subscribe', true); // Returns '' (empty string)

This is why you often see this pattern:

PHP
// In controller (submit method)
$data['subscribe'] = (int) (bool) post('subscribe', true);
// Converts to 1 if checked, 0 if unchecked

The Complete Pattern

Step 1: View File (Use Wrapping Pattern)

View File
<?php
echo '<label>';
echo form_checkbox('newsletter', 1, $newsletter_checked);
echo ' Newsletter Subscription';
echo '</label>';
?>

Important: The third parameter ($newsletter_checked) must be true or false.

Step 2: Controller (Two different conversions)

Your controller needs to handle data differently depending on whether it's going to the view or to the database.

PHP
class Members extends Trongate {
    
    // Display form (data goes TO view)
    public function create(): void {
        $update_id = segment(3, 'int');
        
        if ($update_id > 0 && REQUEST_TYPE === 'GET') {
            // Editing existing record
            $user = $this->db->get_where($update_id, 'users');
            $data['newsletter_checked'] = (bool) $user->newsletter;
        } else {
            // New form OR redisplay after validation error
            $data['newsletter_checked'] = (bool) post('newsletter', true);
        }
        
        $this->view('user_form', $data);
    }
    
    // Process submission (data goes TO database)
    public function submit(): void {
        $this->validation->set_rules('email', 'email address', 'required|valid_email');
        
        $result = $this->validation->run();

        if ($result === true) {
            $data['email'] = post('email', true);
            
            // Convert for database: 1 (checked) or 0 (unchecked)
            $data['newsletter'] = (int) (bool) post('newsletter', true);
            
            $update_id = segment(3, 'int');
            if ($update_id > 0) {
                $this->db->update($update_id, $data, 'users');
                set_flashdata('User updated');
            } else {
                $this->db->insert($data, 'users');
                set_flashdata('User created');
            }
            
            redirect('users/manage');
        } else {
            $this->create(); // Redisplay form with errors
            // Note: create() method fetches posted data for $newsletter_checked
        }
    }
}

Step 3: Database Schema

SQL
CREATE TABLE users (
    id INT PRIMARY KEY AUTO_INCREMENT,
    email VARCHAR(255),
    newsletter TINYINT(1) DEFAULT 0 -- 0 = no, 1 = yes
);

Two Different Conversions

When working with checkboxes the type of conversion that happens differs, depending on whether the goal is to render a view file or enter a checkbox value into a database.

Destination Needs Conversion Result
View (form_checkbox) Boolean (bool) post('field', true) true or false
Database Integer 0/1 (int) (bool) post('field', true) 1 or 0

Common Pitfalls

Never use string values for checkboxes.

View File
// ❌ CONFUSING
echo form_checkbox('newsletter', 'yes');
PHP
// Then you need messy checks:
$value = post('newsletter', true); // 'yes' or ''
$is_checked = ($value === 'yes'); // Have to check string
$for_db = (int) ($value === 'yes'); // Even more complex

Do this: Always use 1 as the value

View File
// ✅ CLEAR
echo form_checkbox('newsletter', 1, $newsletter_checked);
PHP
// Simple conversions:
$for_view = (bool) post('newsletter', true);    // true/false
$for_db = (int) (bool) post('newsletter', true); // 1/0

Radio Buttons

Radio buttons are simpler - they always submit a value. You should also wrap the radio input within the <label> element for accessibility.

PHP
form_radio($name, $value = '', $checked = false, $attributes = []);

Parameters

  • $name (string, required) - The name attribute for the radio button
  • $value (string|bool|int, optional) - The value attribute. Defaults to ''
  • $checked (mixed, optional) - Whether the radio button should be checked. Defaults to false
  • $attributes (array, optional) - Additional HTML attributes. Defaults to []

Radio Group Example (Recommended Pattern)

View File
<?php
$status_options = [
    'active' => 'Active',
    'inactive' => 'Inactive', 
    'pending' => 'Pending'
];

foreach ($status_options as $value => $label) {
    $is_checked = ($current_status === $value);
    echo '<label>';
    echo form_radio('status', $value, $is_checked);
    echo ' ' . $label;
    echo '</label>';
}
?>
PHP
// Controller - both view and database use the same value
public function create(): void {
    $update_id = segment(3, 'int');
    
    if ($update_id > 0 && REQUEST_TYPE === 'GET') {
        $record = $this->db->get_where($update_id, 'items');
        $data['current_status'] = $record->status;
    } else {
        $data['current_status'] = post('status', true);
    }
    
    $this->view('form', $data);
}

public function submit(): void {
    // Same value works for both view and database
    $data['status'] = post('status', true);
    $this->db->insert($data, 'items');
}

Multiple Checkboxes

For multiple selections, store as JSON array:

View File
<?php
$categories = ['web', 'mobile', 'design', 'marketing'];
$selected_cats = $selected_categories ?? [];

foreach ($categories as $category) {
    $is_checked = in_array($category, $selected_cats, true);
    echo '<label>';
    echo form_checkbox('categories[]', $category, $is_checked);
    echo ' ' . ucfirst($category);
    echo '</label>';
}
?>
PHP
// Controller
public function submit(): void {
    $selected = post('categories', true) ?: []; // Array or empty array
    $data['categories'] = json_encode($selected);
    $this->db->insert($data, 'projects');
}

Quick Reference

Element View Code To View (boolean) To Database
Checkbox <label>...form_checkbox('field', 1, $checked)...</label> (bool) post('field', true) (int) (bool) post('field', true)
Radio <label>...form_radio('field', 'value', $checked)...</label> post('field', true) post('field', true)
Text Input form_input('field', $value) post('field', true) post('field', true)

Remember: Checkboxes are the only form element that needs different handling for views vs. databases. Everything else uses the same value for both.

We're continually improving the Trongate documentation. If anything is incorrect, unclear, incomplete, or could be better, we'd genuinely appreciate your input.

Share your thoughts in the Documentation Feedback.

Leave Feedback About This Page