Jump to content

Handling unchecked checkboxes with processwire form API


Stefanowitsch
 Share

Recommended Posts

I am stuck with a problem: How to handle unchecked checkboxes via api.

I have a form with a single checkbox. The value of the checked box would be "yes". When the form is submitted I want the value of the checkbox to be displayed within an email, together with a label text. That works.

But we all know that when you don't check the checkbox the value of the checkbox will be missing in the post data.

So in that case you can use the "hidden field trick": Create a hidden field that contains the value "no" and name it exactly like the the checkbox. This works perfectly fine with the processwire API like this:

// create a hidden input for checkbox
$field = $modules->get("InputfieldHidden");
$field->attr('name',$item->form_name);
$field->attr('value', 'No');
$field->skipLabel = 8;
$form->append($field);

// create a checkbox
$field = $this->modules->get('InputfieldCheckbox');
$field->attr('name',$item->form_name);
$field->attr('value', 'Yes');
$form->append($field); 

My problem is: When you submit the form and some required fields weren't filled out, the form gets validated and the error messages are shown according to the required fields. So far so good.
But in that case the previously unchecked checkbox is suddenly "checked". 
The reason for this must be the fact that the hidden field is submitted which has the same name as the checkbox that is visible in the frontend. So I guess that the processwire form handler then checks the checkbox automatically. This is not a behaviour that occurs in "normal" PHP post data handling.

Link to comment
Share on other sites

Have you studied this thread?

You can use the PW API to process your form submission and then you won't need to do any hacks like that for checkbox fields. The "truthiness" of the checkbox field value once the form has been processed will tell you if it was checked or not.

Example:

/** @var InputfieldForm $form */
$form = $modules->get('InputfieldForm');

/** @var InputfieldText $f */
$f = $modules->get('InputfieldText');
$f->name = 'greeting';
$f->label = 'Greeting';
$form->add($f);

/** @var InputfieldCheckbox $f */
$f = $modules->get('InputfieldCheckbox');
$f->name = 'new_zealander';
$f->label = 'I am a New Zealander';
$f->skipLabel = Inputfield::skipLabelMarkup;
$form->add($f);

/** @var InputfieldSubmit $f */
$f = $modules->get('InputfieldSubmit');
$form->add($f);

if($input->post('submit')) {
	$form->processInput($input->post);
	$greeting = $form->getChildByName('greeting')->value;
	$new_zealander = $form->getChildByName('new_zealander')->value ? 'checked' : 'not checked';
	bd("The greeting was '$greeting' and the 'I am a New Zealander' checkbox was $new_zealander");
}

echo $form->render();

2021-09-21_095956.png.751c6660e62d0073ce020b15f829206a.png

2021-09-21_100033.png.11354978c28091cc48902aacd079a558.png

  • Like 1
Link to comment
Share on other sites

Hi Robin!

Thanks but that solution won't work for my case. Let me explain:

For my forms I am using a "custom formbuilder" solution made from repeater fields. In the backend I can build my own forms with different elements in any order. 

After the submit I am iterating through the input values like this and build my email body content from that. 

foreach($input->post as $field => $val) { 
	// get the $val and use it in e-mail body
}

Your code example does not work for me, because I am going through the fields one after one and the unchecked box will just be missing in the array. In case of unchecked I want to submit a value with "No" instead of nothing. 

$greeting = $form->getChildByName('greeting')->value;

 

Link to comment
Share on other sites

2 hours ago, Stefanowitsch said:

Thanks but that solution won't work for my case. Let me explain:

For my forms I am using a "custom formbuilder" solution made from repeater fields. In the backend I can build my own forms with different elements in any order. 

If you are adding inputfields to a InputfieldForm object (as it looks like you are according the code you posted) then it will work. 

2 hours ago, Stefanowitsch said:

After the submit I am iterating through the input values like this and build my email body content from that. 

foreach($input->post as $field => $val) { 
	// get the $val and use it in e-mail body
}

Yeah, my suggestion is that you don't do that and you instead take advantage of all the useful stuff PW provides for you in the InputfieldForm::processInput() method. This method calls the various processInput() methods of all the inputfields that you have in your form. That does a lot of the input validation work for you and has useful features like inputfield-specific error messages, required fields, required-if logic, etc.

  • Like 2
Link to comment
Share on other sites

2 hours ago, Stefanowitsch said:

unchecked box will just be missing in the array

// after your loop

if( array_key_exists( 'fieldname', $input->post ) ) {
	// add yes stuff to email
} else {
	// add no stuff to email
}

or 

if( is_null( $form->getChildByName( 'fieldname' ) ) {
	// add no stuff to email
} else {
	// add yes stuff to email
}

 

  • Like 1
Link to comment
Share on other sites

Yes you could do the yes/no questionnaire with two radio buttons. In my case I just want a simple fallback value for a non-checked checkbox to be visible inside the e-mail body. This is no problem with the API, my only issue is that the checkbox always will be set to "checked" after submitting - when there are validation errors inside the form.
I find this to be solved much easer in "classic" PHP style and I will stick to that instead of the API form solution.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...