Checkbox Fix

Permalink 1 user found helpful
For the LIFE of me, I could get checkboxes to default to unchecked. So much so, that I only use select boxes half the time. And I've seen plenty of other people pulling their hair out over this one.

However, with the single page I am creating now, ONLY checkboxes will work.

Sample usage (to prove I know the basics):
echo $form->checkbox('user_votes_' . $fid,$selected ,false,array('class'=>'user_select'));


I have narrowed down the issue to the 2nd validator (line 119 of form.php):
if ($this->getRequestValue($key) == $value) {
         $checked = true;
}

That is what is returning the checked value. Here's the fun part - $_REQUEST is empty. Therefore, there is no way the key is being found in the request.

I think the issue here is a "double negative == positive". Since the key is not in the request (there is no request), and the value is negative to start with (no one has selected it yet), false of course is == false.

A simple additional if statement seems to fix this:
if ($this->getRequestValue($key) == $value) {
            if($value!=false){
              $checked = true;  
            }
}


I'd like others to ensure this doesn't cause other issues, and this is a preliminary fix, but I would think this would resolve a LOT of the issues people have with the $isChecked variable.

 
jordanlev replied on at Permalink Reply
jordanlev
Checkboxes are tricky because (as you discovered), an unchecked box doesn't POST any values. This is an issue with HTML in general (not specific to C5).

I'm not sure what your context is here (is it a block? a theme template? a custom template for another block? etc.), but in general I've found the following to work for me:

1) use the number "1" as the value for the checkbox:
echo $form->checkbox('my_field', 1, $my_field); ?>


2) when processing the form, use php's "empty" function to check for true/false/null/not-set-ness all in one fell swoop:
$my_field = !empty($_POST['my_field']);
cryophallion replied on at Permalink Reply
Frankly, it doesn't matter what this is for.

If you search the forums, there are problems ALL OVER about default unchecked boxes being checked even though both the variable AND the $isChecked value are false.

(
http://www.concrete5.org/community/forums/customizing_c5/bizarre-be...

http://www.concrete5.org/developers/bugs/5-5-2/problem-with-formhel...

http://www.concrete5.org/community/forums/customizing_c5/how-does-f...

http://www.concrete5.org/community/forums/customizing_c5/checkbox-i...

note: doing this with a modal window is rather annoying, so I'll stop there
)

This problem is NOT an issue with html. This is an issue with the way C5 sets the variables. The 2nd filter is seeing that the value is unset or false, and that the default is false. It then compares these two, and if they are the same, checks the box. That is improper behavior, and a simple line of code can fix it.

In fact, the code can be further simplified with:

} else if ($this->getRequestValue($key) == $value && $value!=false) {
         $checked = true;
      }


This is a simple fix to remedy a longstanding bug. I'd just like it if a dev said that this was going to be fixed in the next release, as I can't use checkboxes in half my code because of this (and I can't trust my fixes will be saved in updates).

Once the one line is changed, checkboxes can again be defaulted to false properly.
Phallanx replied on at Permalink Reply
Phallanx
@cryophallion
[quote]
(and I can't trust my fixes will be saved in updates)
[/quote]

If you override the core rather than modifying it, then your fix will persist regardless of updates. If/when they do get around to addressing it, you can just remove the override.

http://www.concrete5.org/documentation/how-tos/developers/overridin...
cryophallion replied on at Permalink Reply
And I should have also added (but for some stupid reason deleted after writing it) " and to ensure bug fixes or other features in the updates will be available".

You are right, I can. I would just prefer that it worked, and am naturally nervous that it will happen on a site that I hand off to a client, they update for 2 years, then something breaks because of my overrides or another bug doesn't get fixed. I know, I'm paranoid, but I've been burned in the past.
Phallanx replied on at Permalink Reply
Phallanx
@cryophallion

Well. That is more to do with managing clients expectations. I know of no developer that provides unlimited, unchargeable, support for life and most clients I deal with understand that after acceptance and a warrantee/support period we are back to the quotation phase.

If they change something, then that is a risk they have chosen which you can help with but ultimately not your responsibility. The only risk free approach has always been, and always will be, not to change anything. Once you have proved it working and that it meets all requirements, your design task is finished. You are not responsible for bugs introduced by the core team after them upgrading and, similarly, you are not responsible for something breaking after an upgrade. You are commissioned to create a website and your responsibility is that you achieve the requirements that they then sign off as completed satisfactorily. Once signed off, your responsibility ends unless a support contract is in place.
jordanlev replied on at Permalink Reply
jordanlev
Sounds like you've found a bug in the core system and also provided a fix -- that's great! The procedure from here is to submit a pull request on github --https://github.com/concrete5/concrete5/pulls...

If you're unfamiliar with how to do pull requests in github, there are a lot of resources out there to learn (it's a very useful skill -- knowing git in general will serve you well in all sorts of programming projects, even outside of the Concrete5 world). Here's a decent guide:https://help.github.com/articles/using-pull-requests...

If you run into trouble or don't understand how to make this work (after trying for yourself), let me know and I'd be happy to help out (as time permits -- might take me a day or three to respond).

-Jordan