form_checkbox()
function form_checkbox(string $name, string|bool|int $value = '1', mixed $checked = false, array $attributes = []): string
Description
Generates an HTML checkbox input element. Checkboxes allow users to select or deselect a single option.
Unlike other form elements, unchecked checkboxes do not submit any data to the server.
Parameters
| Parameter |
Type |
Description |
| $name |
string |
The name attribute for the checkbox element. |
| $value |
string|bool|int |
(optional) The value submitted when checked. Defaults to '1'. |
| $checked |
mixed |
(optional) Whether the checkbox should be checked. Default is false. Accepts true, false, 'true', 'false', 1, 0, '1', '0', 'yes', 'no', 'on', 'off'. |
| $attributes |
array |
(optional) HTML attributes like class, id, etc. Defaults to an empty array ([]). |
Return Value
| Type |
Description |
| string |
HTML checkbox input element. |
Example Usage
Imagine you're building a task manager where users can mark tasks as complete. Here's how checkboxes work in Trongate:
1. In Your View (create.php)
<?php
echo form_open($form_location);
echo form_label('Task Title');
echo form_input('task_title', $task_title);
echo form_label('Complete');
echo form_checkbox('complete', 1, $complete); // Third parameter accepts boolean or truthy string
echo form_submit('submit', 'Save');
echo form_close();
?>
Trongate Convention: Always use 1 as the checkbox value. This makes data conversion simple and consistent.
2. In Your Controller (Tasks.php)
The controller prepares data for the view and handles form submission:
<?php
class Tasks extends Trongate {
public function create(): void {
$update_id = segment(3, 'int');
if ($update_id > 0 && REQUEST_TYPE === 'GET') {
// Editing existing task
$task = $this->db->get_where($update_id, 'tasks');
$data['complete'] = (bool) $task->complete; // Convert 1/0 to true/false
} else {
// New task or redisplay after validation error
$data['complete'] = (bool) post('complete', true);
}
$data['form_location'] = 'tasks/submit';
$data['task_title'] = post('task_title', true);
$this->view('task_form', $data);
}
public function submit(): void {
$this->validation->set_rules('task_title', 'task title', 'required|min_length[2]|max_length[255]');
$result = $this->validation->run();
if ($result === true) {
$data['task_title'] = post('task_title', true);
// Convert checkbox for database storage
$data['complete'] = (int) (bool) post('complete', true);
// Result: 1 if checked, 0 if unchecked
$update_id = segment(3, 'int');
if ($update_id > 0) {
$this->db->update($update_id, $data, 'tasks');
} else {
$this->db->insert($data, 'tasks');
}
redirect('tasks/manage');
} else {
$this->create();
}
}
}
Understanding Checkbox Behavior
Checkboxes work differently than other form elements:
// After form submission:
$value = post('complete', true);
// If checkbox WAS checked:
// Returns: '1' (the value you set)
// POST data contains: complete='1'
// If checkbox was NOT checked:
// Returns: '' (empty string)
// POST data does NOT contain 'complete' field at all
This is HTML behavior, not Trongate. That's why you need special handling.
Flexible Checked Parameter
The $checked parameter accepts various truthy/falsy values:
// All of these produce a checked checkbox:
echo form_checkbox('option', 1, true);
echo form_checkbox('option', 1, 'true');
echo form_checkbox('option', 1, 'yes');
echo form_checkbox('option', 1, 'on');
echo form_checkbox('option', 1, '1');
echo form_checkbox('option', 1, 1);
// All of these produce an unchecked checkbox:
echo form_checkbox('option', 1, false);
echo form_checkbox('option', 1, 'false');
echo form_checkbox('option', 1, 'no');
echo form_checkbox('option', 1, 'off');
echo form_checkbox('option', 1, '0');
echo form_checkbox('option', 1, 0);
The Complete Pattern
Remember these conversions:
- For views:
(bool) post('field', true) → returns true/false
- For database:
(int) (bool) post('field', true) → returns 1/0
Simple Examples
Basic checkbox with default value (unchecked):
echo form_checkbox('subscribe');
// Output: <input type="checkbox" name="subscribe" value="1">
Explicitly unchecked checkbox:
echo form_checkbox('newsletter', 1, false);
// Same output: <input type="checkbox" name="newsletter" value="1">
Default State: By default, checkboxes are unchecked. The third parameter $checked defaults to false, so form_checkbox('field') and form_checkbox('field', 1, false) produce identical unchecked checkboxes.
Checked checkbox:
echo form_checkbox('newsletter', 1, true);
// Output: <input type="checkbox" name="newsletter" value="1" checked="checked">
With custom attributes:
$attributes = [
'class' => 'form-check-input',
'id' => 'terms-checkbox'
];
echo form_checkbox('terms', 1, $terms_accepted, $attributes);
Common Pitfalls
Avoid string values for checkboxes:
// ❌ CONFUSING
echo form_checkbox('newsletter', 'yes');
// Then you need messy checks:
$value = post('newsletter'); // 'yes' or ''
$is_checked = ($value === 'yes'); // Have to check string
Do this instead:
// ✅ CLEAR
echo form_checkbox('newsletter', 1, $newsletter_checked);
// Simple conversions:
$for_view = (bool) post('newsletter', true); // true/false
$for_db = (int) (bool) post('newsletter', true); // 1/0
Database Schema
Store checkbox values as integers in your database:
CREATE TABLE tasks (
id INT PRIMARY KEY AUTO_INCREMENT,
task_title VARCHAR(255),
complete TINYINT(1) DEFAULT 0, -- 0 = no, 1 = yes
date_created TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
Quick Reference
The table below illustrates how checkboxes are the only form element type that requires special handling when converting between view logic and database storage.
| Element |
View Code |
To View (boolean) |
To Database |
| Checkbox |
form_checkbox('field', 1, $checked) |
(bool) post('field', true) |
(int) (bool) post('field', true) |
| Radio |
form_radio('field', 'value', $checked) |
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.