I have an application in CakePHP 4 where I'm doing the equivalent of what's described in Make array from checkbox form
The markup I have is simple:
<input type="checkbox" name="services[]" value="Service 1" id="service1">
<input type="checkbox" name="services[]" value="Service 2" id="service2">
<input type="checkbox" name="services[]" value="Service 3" id="service3">
So somebody could for example check "Service 1" and "Service 3" and omit "Service 2", e.g.
I've used the Form Helper in CakePHP to generate the HTML above. The code looks like this and is in my template file for that page:
<?= $this->Form->checkbox('services[]', ['value' => 'Service 1', 'id' => 'service1', 'hiddenField' => false]); ?>
<?= $this->Form->checkbox('services[]', ['value' => 'Service 2', 'id' => 'service2', 'hiddenField' => false]); ?>
<?= $this->Form->checkbox('services[]', ['value' => 'Service 3', 'id' => 'service3', 'hiddenField' => false]); ?>
When I submit the form and debug the output:
// in my Controller
if ($this->request->is('post')) {
debug($this->request->getData());
}
I get:
'services' => [
(int) 0 => 'Service 1',
(int) 1 => 'Service 3',
],
This is fine, because it has the selected services which is all I need in terms of data submitted from the user on this part of the form.
But when the form is rendered following submit it errors with:
Notice (8): Array to string conversion [CORE/src/View/Widget/CheckboxWidget.php, line 93]
None of the checkboxes are checked (whereas the remainder of fields on the form are populated with the request data, albeit they are all text inputs as opposed to checkboxes). It looks like this:
Why does this happen? The markup which is being generated uses the array syntax for checkbox names (e.g.services[]
) which from what I can see is perfectly valid HTML and also something which was used on the linked post without anyone saying it's a problem.
Is this a CakePHP specific problem (e.g. wrong syntax used somewhere in the Form Helper) or a general issue with the way the HTML or PHP is being interpreted?
Your field name is the same as the data name, egservices
, and thus the form helper will pick up an array for the current value of each individual control, and that will fail, as the "should be checked" logic needs to compare two flat values.
If you want to create individual checkboxes like this, then you either need to take care of passing the possible POST data for the individual controls too, which is what mark's example does, or you need to test the data manually and mark the boxes checked accordingly, here's one example:
$values = (array)$this->Form->getSourceValue('services');
echo $this->Form->checkbox('services[]', [
'value' => 'first',
'checked' => in_array('first', $values),
// ...
]);
echo $this->Form->checkbox('services[]', [
'value' => 'second',
'checked' => in_array('second', $values),
'hiddenField' => false,
// ...
]);
echo $this->Form->checkbox('services[]', [
'value' => 'third',
'checked' => in_array('third', $values),
'hiddenField' => false,
// ...
]);
That being said, for your specific case you should be able to simply use a multi-checkbox control, which will handle looking up data and marking the boxes checked automatically:
echo $this->Form->select(
'services',
$options,
['multiple' => 'checkbox', /* ... */]
);
If you want to use names as the option values,$options
would need to be an array like:
[
'Service 1' => 'Service 1',
'Service 2' => 'Service 2',
// ...
]
as the array index is used for the checkbox value, and the array value is used for the checkbox label.
See also
I remember that I wrote a helper for that once for my project(s) Something along the lines of
namespace App\View\Helper;
use Cake\View\Helper\FormHelper;
/**
* Allows forms with fieldname[] syntax.
*
* @author Mark Scherer
* @license MIT
* @property \Cake\View\Helper\UrlHelper $Url
* @property \App\View\Helper\HtmlHelper $Html
*/
class ArrayFormHelper extends FormHelper
{
/**
* @var int
*/
protected $counter = 0;
/**
* @var array
*/
protected $data = [];
/**
* @param array $config
*
* @return void
*/
public function initialize(array $config): void
{
$this->data = $this->getView()->getRequest()->getData();
}
/**
* @return void
*/
public function endRow(): void
{
$this->counter++;
}
/**
* @return void
*/
public function reset(): void
{
$this->counter = 0;
}
/**
* @param string $field
* @param array $options
*
* @return string
*/
public function arrayControl(string $field, array $options = []): string
{
if (array_key_exists($this->counter, $this->data[$field])) {
$options['default'] = $this->data[$field][$this->counter];
$this->getView()->setRequest($this->getView()->getRequest()->withoutData($field));
}
return $this->control($field . '[]', $options);
}
}
to be used as e.g.
echo $this->ArrayForm->arrayControl('module', ['label' => 'Module', 'placeholder' => 'CamelCase']);
echo $this->ArrayForm->arrayControl('type', ['label' => 'Type', 'options' => ['patch' => 'patch', 'minor' => 'minor', 'major' => 'major'], 'empty' => true]);
$this->ArrayForm->endRow();
The counter and endRow stuff isn't needed if this is not inside a loop (as in my case it was).
Our community is visited by hundreds of web development professionals every day. Ask your question and get a quick answer for free.
Find the answer in similar questions on our website.
Do you know the answer to this question? Write a quick response to it. With your help, we will make our community stronger.
PHP (from the English Hypertext Preprocessor - hypertext preprocessor) is a scripting programming language for developing web applications. Supported by most hosting providers, it is one of the most popular tools for creating dynamic websites.
The PHP scripting language has gained wide popularity due to its processing speed, simplicity, cross-platform, functionality and distribution of source codes under its own license.
https://www.php.net/
CakePHP is a framework that has been around since 2005 and is known for the convenience it gives web developers. It needs very modest settings, does not require the use of XML or YAML files. It has its own ORM, which sets it apart from other similar tools. In terms of security, it is also doing well, in particular, it has a protection system against CSRF attacks.
https://cakephp.org/
HTML (English "hyper text markup language" - hypertext markup language) is a special markup language that is used to create sites on the Internet.
Browsers understand html perfectly and can interpret it in an understandable way. In general, any page on the site is html-code, which the browser translates into a user-friendly form. By the way, the code of any page is available to everyone.
https://www.w3.org/html/
Welcome to the Q&A site for web developers. Here you can ask a question about the problem you are facing and get answers from other experts. We have created a user-friendly interface so that you can quickly and free of charge ask a question about a web programming problem. We also invite other experts to join our community and help other members who ask questions. In addition, you can use our search for questions with a solution.
Ask about the real problem you are facing. Describe in detail what you are doing and what you want to achieve.
Our goal is to create a strong community in which everyone will support each other. If you find a question and know the answer to it, help others with your knowledge.