• 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Possible bug in set_checkbox() function in form_helper library

#1
[eluser]krif[/eluser]
It might be me using the function wrong but when I call the set_checkbox of the Form Helper library without having post variables yet, it always returns a 'checked="checked"'

As far as I see it, the problem is that the function checks if set_checkbox() has not yet been defined by the Form Validation library yet, then looks for the validation object and post field data but if all those return FALSE or 0 resp. then returns checked even if the third parameter was set to FALSE or not defined.

This is the original code:

Code:
if ( ! function_exists('set_checkbox'))
{
    function set_checkbox($field = '', $value = '', $default = FALSE)
    {
        $OBJ =& _get_validation_object();

        if ($OBJ === FALSE)
        {
            if ( ! isset($_POST[$field]))
            {
                if (count($_POST) === 0)
                {
                    return ' checked="checked"';
                }
                return '';
            }

but I guess it should be more something like see the added "$default === TRUE AND " in line 11, or line 687 of the Form Helper library in CI 1.7.0:

Code:
if ( ! function_exists('set_checkbox'))
{
    function set_checkbox($field = '', $value = '', $default = FALSE)
    {
        $OBJ =& _get_validation_object();

        if ($OBJ === FALSE)
        {
            if ( ! isset($_POST[$field]))
            {
                if ($default === TRUE AND count($_POST) === 0)
                {
                    return ' checked="checked"';
                }
                return '';
            }

#2
[eluser]nardberg[/eluser]
I agree that this appears to be a bug. I want to load a form pre-populated from my database record, and then retain the state of a checkbox as submitted if the validation fails.

On the first load of the form, using set_checkbox will always result in checked='checked', maybe as the above poster concludes because the POST array is empty. The proposed code fix works perfectly and I wonder why such an apparently basic flaw in this functionality has received no comments or replies?

Thanks.

#3
[eluser]gustavofarias[/eluser]
[quote author="nardberg" date="1235085467"]...I wonder why such an apparently basic flaw in this functionality has received no comments or replies?
[/quote]

I think it's strange too. So I decided to comment.

A friend of mine solved the problem this way:
Code:
if ( ! isset($_POST[$field]))
{
if (count($_POST) === 0 && $default)
{
  return ' checked="checked"';
}
return '';
}

The same friend discovered that a similar problem happens in another function:
system/helpers/form_helper.php set_select()

Original code:

Code:
function set_select($field = '', $value = '', $default = FALSE)
    {
        $OBJ =& _get_validation_object();

        if ($OBJ === FALSE)
        {
            if ( ! isset($_POST[$field]))
            {
                if (count($_POST) === 0)
                {
                    return ' selected="selected"';
                }
                return '';
            }

            $field = $_POST[$field];

            if (is_array($field))
            {
                if ( ! in_array($value, $field))
                {
                    return '';
                }
            }
            else
            {
                if (($field == '' OR $value == '') OR ($field != $value))
                {
                    return '';
                }
            }

            return ' selected="selected"';
        }

        return $OBJ->set_select($field, $value, $default);
    }

Proposed solution:

Code:
function set_select($field = '', $value = '', $default = FALSE)
    {
        $OBJ =& _get_validation_object();

        if ($OBJ === FALSE)
        {
            if ( ! isset($_POST[$field]))
            {
                if (count($_POST) === 0)
                {
                    if ($default)
                        return ' selected="selected"';
                    else
                        return '';
                }
                return ' selected="selected"';
            }

            $field = $_POST[$field];

            if (is_array($field))
            {
                if ( ! in_array($value, $field))
                {
                    return '';
                }
            }
            else
            {
                if (($field == '' OR $value == '') OR ($field != $value))
                {
                    return '';
                }
            }

            return ' selected="selected"';
        }

        return $OBJ->set_select($field, $value, $default);
    }

#4
[eluser]Cambo[/eluser]
I also had the same problem.
I was using a 2 radio buttons in a form for the first time ever in Codeigniter and both radio buttons were being marked as checked on first load.

It wasn't until I found this post and used gustavofarias's friends resolution that the issue was resolved.
I also believe this is a bug and should be submitted.

Unfortunately, I have 8 websites running Codeigniter so now I have to go and edit them all. Sad

#5
[eluser]gustavofarias[/eluser]
[quote author="Cambo" date="1235711133"]I was using a 2 radio buttons in a form for the first time ever in Codeigniter and both radio buttons were being marked as checked on first load.
[/quote]

Does it mean that set_radio() function is buggy too? If it's the case it must be reported.
Code:
function set_radio($field = '', $value = '', $default = FALSE)
    {
        $OBJ =& _get_validation_object();

        if ($OBJ === FALSE)
        {
            if ( ! isset($_POST[$field]))
            {
                if (count($_POST) === 0 /* =========== HERE AGAIN ============ */)
                {
                    return ' checked="checked"';
                }
                return '';
            }

#6
[eluser]Cambo[/eluser]
Yep.
I changed both set_checkbox() and set_radio() in /system/helpers/form_helper.php to the following:
Code:
if ( ! isset($_POST[$field]))
{
if (count($_POST) === 0 && $default)
{
  return ' checked="checked"';
}
return '';
}

as both returned "checked" on true OR false originally.

#7
[eluser]opel[/eluser]
could you please give an example of how you set up your form view and controllers please

#8
[eluser]Cambo[/eluser]
Here I am using radio buttons.

This is my function to add a contact in my controller.
"leads" and "marques" are the radio button fields.
Code:
/**
* Add a new contact
*/    
    function add()
    {

        $data = $this->site_config->get_odms_config();
        
        $this->load->library('validation');
        $rules['first_name'] = "required";
        $rules['last_name'] = "required";
        $rules['email'] = "required|valid_email";

        $this->validation->set_rules($rules);

        $fields['first_name'] = 'First Name';
        $fields['last_name'] = 'Last Name';
        $fields['phone'] = 'Phone';
        $fields['mobile'] = 'Mobile';
        $fields['email'] = 'Email';
        $fields['info'] = 'Info';
        $fields['leads'] = 'Leads';
        $fields['marques'] = 'Marques';
        $fields['custom_marques'] = 'Custom_Marques';

        $this->validation->set_fields($fields);

        $this->validation->set_error_delimiters('<p class="status-error">', '</p>');
                
        if ($this->validation->run() == FALSE)
        {
            $this->load->view('odms/header',$data);
            $this->load->view('odms/nav_bar');
            $this->load->view('odms/contacts_add');
            $this->load->view('footer');
        } else {

        // Post Data
        $post_array['first_name'] = trim($this->input->post('first_name', TRUE));
        $post_array['last_name'] = trim($this->input->post('last_name', TRUE));
        $post_array['phone'] = trim($this->input->post('phone', TRUE));
        $post_array['mobile'] = trim($this->input->post('mobile', TRUE));
        $post_array['email'] = trim($this->input->post('email', TRUE));
        $post_array['info'] = trim($this->input->post('info', TRUE));
        $post_array['leads'] = trim($this->input->post('leads'));
        
        $tmp_marque = trim($this->input->post('marques', TRUE));
        if($tmp_marque == 'custom')
        {
            $post_array['marques'] = trim($this->input->post('custom_marques', TRUE));
        } else {
            $post_array['marques'] = $tmp_marque;
        }
        
        //add dealerID
        $post_array['dealerID'] = $this->session->userdata('dealerID');
        
        $result = $this->objContacts->add_contact($post_array);
        if($result)
        {
                $systemMsg = 'Contact has been added!';
        } else {
                $systemMsg = 'Error! Unable to add New Contact. Please inform Site Administrator.';
        }
        
        $this->session->set_flashdata('systemMsg', $systemMsg);
        redirect('odms_contacts');
        }

and this is the view:

Code:
<h3>Add a New Contact</h3>
<div id="nav-button">&lt;?php echo anchor('odms_contacts','Cancel',array('class' => ' action-button')); ?&gt;</div>

&lt;?php
    echo form_open('odms_contacts/add', array('name' => 'add_contact'));
?&gt;
<table>
<tr>
<td class="label" width="40%">*First Name :</td>
<td>
    &lt;input type="text" name="first_name" value="&lt;?php echo $this-&gt;validation->first_name;?&gt;"> &lt;?php echo $this->validation->first_name_error; ?&gt;
</td>
</tr>
<tr>
<td class="label">*Last Name :</td>
<td>
    &lt;input type="text" name="last_name" value="&lt;?php echo $this-&gt;validation->last_name;?&gt;"> &lt;?php echo $this->validation->last_name_error; ?&gt;
</td>
</tr>
<tr>
<td class="label">Phone :</td>
<td>
    &lt;input type="text" name="phone" value="&lt;?php echo $this-&gt;validation->phone;?&gt;">
</td>
</tr>


<tr>
<td class="label">Mobile :</td>
<td>
    &lt;input type="text" name="mobile" value="&lt;?php echo $this-&gt;validation->mobile;?&gt;">
</td>
</tr>


<tr>
<td class="label">*Email :</td>
<td>
    &lt;input type="text" name="email" value="&lt;?php echo $this-&gt;validation->email;?&gt;"> &lt;?php echo $this->validation->email_error; ?&gt;
</td>
</tr>


<tr>
<td class="label">Comments :</td>
<td>
    &lt;input type="text" name="info" maxlength="250" size="100" value="&lt;?php echo $this-&gt;validation->info;?&gt;">
</td>
</tr>

<tr>
<td class="label">Receive Leads? :</td>
<td>
<label>&lt;input type="radio" name="leads" value="Y" &lt;?php echo set_radio('leads', 'Y', TRUE); ?&gt; /&gt; YES </label>
<br />
<label>&lt;input type="radio" name="leads" value="N" &lt;?php echo set_radio('leads', 'N'); ?&gt; /&gt; NO</label>

</td>
</tr>

<tr>
<td class="label">Marques :</td>
<td>
    <label>&lt;input type="radio" name="marques" value="ALL"&gt; ALL</label>
    <br />
    <label>&lt;input type="radio" name="marques" value="custom" id="custom_value"&gt; Enter Marques separated by a comma. eg. Ford, Holden </label> <br />
    &lt;input type="text" name="custom_marques" maxlength="250" size="100" value="&lt;?php echo $this-&gt;validation->custom_marques;?&gt;" disabled="true" />

&lt;!-- manage Marques radio buttons  --&gt;
[removed]
function radio_checker() {
        if (document.add_contact.custom_value.checked) {
            document.add_contact.custom_marques.disabled = false;
            document.add_contact.custom_marques.focus();
        } else {
            document.add_contact.custom_marques.disabled = true;
        }
}
[removed]

</td>
</tr>
</table>
<div id="nav-button">
&lt;input class="submit" type="submit" name="submit" value="Add Contact"&gt;
&lt;input class="submit" type="reset" name="reset" value="Reset"&gt;
</div>
&lt;/form&gt;

You might notice a couple of [removed] tags in the view.
They were just the script declaration tags.

Hope that helps you out.

#9
[eluser]opel[/eluser]
Thanks I'll read through it and see if it works with my code. I put a rough hack in the mean time

#10
[eluser]CI Roma[/eluser]
Maybe this is the solution for this bug...
Code:
if ( ! function_exists('set_checkbox'))
{
    function set_checkbox($field = '', $value = '', $default = FALSE)
    {
    if(!isset($_POST[$field])) return '';
        if(is_array($_POST[$field])):
            if(count($_POST[$field]) > 0):
                if(in_array($value,$_POST[$field])) return ' checked="checked"';
            endif;
        else:
            if($_POST[$field] != "" && $_POST[$field] == $value):
                 return ' checked="checked"';
            endif;
        endif;
        return '';
    }
}

bye ...


Digg   Delicious   Reddit   Facebook   Twitter   StumbleUpon  


  Theme © 2014 iAndrew  
Powered By MyBB, © 2002-2019 MyBB Group.