Question

Making a simple component. If I save a new record with the box checked, it saves fine. If I go back and uncheck a previously checked item it reverts back to checked. I thought it had something to do with a hidden field, played with putting one of those in manually but that didn't fix it either so took it out.

Here's where I'm at: An xml snippet:

<fieldset name="checks">
  <field name="checkbox1"
    type="checkbox"
    label="First Checkbox"
    value="1"
    filter="intval"         
  /> 

   <field name="checkbox2"
    type="checkbox"
    label="Second Checkbox"
    value="1"
    filter="intval"         
  /> 

 ...

</fieldset>

The edit.php file:

<div class="width-45 fltlft">
  <fieldset class="adminform">
    <legend>Checkboxes</legend>
    <ul class="adminformlist">
      <?php foreach ($this->form->getFieldset('checks') as $field): ?>
        <li>
          <?php echo $field->label; ?>
          <?php echo $field->input; ?>
        </li>
      <?php endforeach ?>
    </ul>
  </fieldset>
</div>

Also added this towards the end before the form.token:

<input type="hidden" name="task" id="task" value="completion.edit" />

I tried deleting the value="1" in the xml but then I had the opposite problem where the check wouldn't save at all.

Any ideas?

Thanks!

=============================

Edit:

Model:

<?php
defined( '_JEXEC' ) or die;

jimport('joomla.application.component.modeladmin');

class AssessModelCompletion extends JModelAdmin
{
//tells it what kind of record and the prefix

    public function getTable($type = 'Completion', $prefix = 'AssessTable', $config = array())
    {
        return JTable::getInstance($type, $prefix, $config);
    }

    //Load the data into the edit form
    protected function loadFormData()
    {
        $data = JFactory::getApplication()->getUserState('com_assess.edit.completion.data', array()); //first try to get the data from the session, not db

        if (empty($data)) {
            $data = $this->getItem(); //this gets the data
        }

        return $data;

    }

    //Stores data in a session in case a field is missed
    public function getForm($data = array(), $loadData = true)
    {
        $form = $this->loadForm('com_assess.completion', 'completion', array('control' => 'jform', 'load_data' => $loadData));

        return $form;
    }
}

And table:

<?php 
defined ( '_JEXEC' ) or die;

class AssessTableCompletion extends JTable
{
    public function __construct(&$db)
    {
        parent::__construct('#__tablename_completions', 'completion_id', $db);
    }
}

======================================

References: https://stackoverflow.com/questions/6964333/joomla-1-6-admin-form-processing-grouped-checkboxes-in-form

Tutorial code is not working any more in Joomla 2.5

http://docs.joomla.org/Developing_a_Model-View-Controller_%28MVC%29_Component_for_Joomla!1.7_-_Part_09#Adding_a_toolbar

Was it helpful?

Solution 4

So I had a lot of fields and wanted to simply loop through them in my edit.php field to keep it clean. While all the answers offered were right they weren't easy to implement - got really messy really quickly, had trouble getting it to work, or couldn't figure out a cleaner way around it. I chewed on this for awhile and then today came across what is basically a field override.

The key:

The standard form field types are located in joomla/libraries/joomla/form/fields/. You should not store custom fields there, nor should you have to use this path in your own code, but the standard types are usually good examples.

The custom field types that belong to your component are usually located in administrator/components//models/fields. You can specify this or another path in your code

So, I copied checkbox.php to models/fields. Then, towards the end of the file I added the empty field before the checkbox tag:

<input type="hidden" name="'.$this->name.'" id="'.$this->id.'" value="0" /><input type="checkbox" .....

Now, whenever I need a checkbox the empty field is also written. May not be the most efficient solution but simple to implement and can hopefully help someone else.

[Edit]

As a note, with every Joomla update you would probably need to compare the versions in the core in case there was a change.

OTHER TIPS

So this is a kind of odd situation in that the documentation you list makes it seem that you would have to write no code to handle the checkbox (because as you point out a checkbox is different then checkboxes). But this does not seem to be the case because of the way that html checkboxes are submitted.

A quick overview of this issue and one solution can be found here: http://planetozh.com/blog/2008/09/posting-unchecked-checkboxes-in-html-forms/.

To use this, you would need to get the field's name out of the $field variable (which I'm not sure if it will be easy to access) and then place the <input type=hidden name='name' value=0> before <?php echo $field->input; ?>.

The other method to fix this would be to process the form data during save and override elements. Joomla has a prepareTable function that you could add to your model to edit data as necessary during save. The following example assumes that your form elements are wrapped in a jform array. (Confirm this by looking at the name fields in the html generated and they should be 'jform[checkbox1]')

protected function prepareTable(&$table)
{
    $jform = JRequest::getVar('jform'); // load all submitted data
    if (!isset($jform['checkbox1'])) { // see if the checkbox has been submitted
        $table->checkbox1 = 0; // if it has not been submitted, mark the field unchecked
    }
    if (!isset($jform['checkbox2'])) { // likewise for other checkboxes
        $table->checkbox2 = 0;
    }
}

In this case, you would want to keep "value=1" in your xml fields file.

The problem ultimately is that Joomla loads the current data from the database during saving and then binds the posted data over the top of it. Because an unchecked box is not submitted in the post data, it does not overwrite the databases information and is thus not saved.

As you don't have any model/table code showing, I think you may be mistaking JForm's purpose - it is purely for rendering of the form. You still have to have in your model/table something to handle the array that is returned for multivalued fields.

As Sam Moffat put it:

there is no coupling between the form definitions used to render the data and the models and table structures used to persist them

Although the documentation states that you do not have to do any manual handeling of the checkbox this is not true.

As no value is sent in the $_POST array when a checkbox is not checked the value is not overwritten and thus not saved which makes it impossible to uncheck the checkbox. To fix this you have to write special handling for your checkboxes in your table bind() function like this:

class YourcomponentTableYourview extends JTable 
{ 
    /** 
     * Constructor 
     * 
     * @param JDatabase A database connector object 
     */ 
    public function __construct(&$db) 
    { 
        parent::__construct('#__your_table_name', 'id', $db); 
    } 

    public function bind($array, $ignore = '') 
    { 
        if (!isset($array['name_of_field'])) 
                    $array['name_of_field'] = 0 ; 

        return parent::bind($array, $ignore); 
    } 
} 

I know this is an old question, but the official answer is long winded and I think I have a better solution.

Try setting the default value for the checkbox to 0 rather than 1 in your xml like so:

<fieldset name="checks">
  <field name="checkbox1"
    type="checkbox"
    label="First Checkbox"
    value="0"
    filter="intval"         
  /> 

   <field name="checkbox2"
    type="checkbox"
    label="Second Checkbox"
    value="0"
    filter="intval"         
  /> 

 ...

</fieldset>

I just came across your question and tried setting it to 0 as I didn't want to tamper with the core and hey presto it works.

My guess is that Joomla sees no value and thus sets the default instead.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top