Grouping attributes with addFieldSet

From Achievo/ATK Wiki

Jump to: navigation, search

ATK Howto: Grouping attributes with addFieldSet

Complexity: intermediate
Author: Jorge Garifuna <http://www.garidigital.com>

List of other Howto's

By default, ATK positions each attribute on a separate row. The addFieldSet() function can be used to position multiple attributes on the same row. It allows the programmer complete control over the placement of the attribute labels and values on the row. The programmer may also embed HTML tags to further control the positioning of the labels and values on the form.

The addFieldSet() function was introduced to ATK on June 11, 2008. Prior to this the addGroup() function was used, but subsequently dropped from the core of ATK due to compatibility issues.

To make use of the addFieldSet() function, you need to have an ATK build created after June 11, 2008.

Assumming we had the following node:

    function employee()
    {
      $this->atkNode("employee", NF_ADD_LINK);
 
      $this->add(new atkAttribute("id", AF_AUTOKEY));
      $this->add(new atkAttribute("name", AF_OBLIGATORY|AF_UNIQUE|AF_SEARCHABLE));
      $this->add(new atkManyToOneRelation("department_id","lesson3.department", AF_SEARCHABLE));
      $this->add(new atkManyToOneRelation("manager_id","lesson3.employee", AF_SEARCHABLE|AF_RELATION_AUTOCOMPLETE));
 
      $this->add(new atkDateAttribute("hiredate"));
      $this->add(new atkNumberAttribute("salary", AF_TOTAL));
      $this->add(new atkTextAttribute("notes", 0, AF_HIDE_LIST));
      
      $this->setOrder("name");
      $this->setIndex("name");
      $this->setTable("lesson3_employee");
    }

Now let's group the following attributes so they appear on the same row:

Group0 will contain: department and manager Group1 will contain: name salary and the notes will have the label displayed on top of the attribute as opposed to the left

Below is the revised version of our node to accommodate for these enhancements using the addFieldSet() function:

    function employee()
    {
      $this->atkNode("employee", NF_ADD_LINK);
 
      $this->add(new atkAttribute("id", AF_AUTOKEY));
      $this->add(new atkAttribute("name", AF_OBLIGATORY|AF_UNIQUE|AF_SEARCHABLE));
      $this->add(new atkManyToOneRelation("department_id","lesson3.department", AF_SEARCHABLE));
      $this->add(new atkManyToOneRelation("manager_id","lesson3.employee", AF_SEARCHABLE|AF_RELATION_AUTOCOMPLETE));
 
      $this->add(new atkDateAttribute("hiredate"));
      $this->add(new atkNumberAttribute("salary", AF_TOTAL));
      $this->add(new atkTextAttribute("notes", 0, AF_HIDE_LIST));
 
      $this->addFieldSet("group0","[department_id.label] [department_id.field] [manager_id.label] [manager_id.field] ",AF_SEARCHABLE|AF_BLANK_LABEL,NULL,300 );
      $this->addFieldSet("group1","[name.field] [salary.field] <hr>[notes.label]:<br>[notes.field]",AF_SEARCHABLE|AF_BLANK_LABEL,NULL,600 );
      
      $this->setOrder("name");
      $this->setIndex("name");
      $this->setTable("lesson3_employee");
    }

The addFieldSet() function is defined as follows on class.atknode.inc:

addFieldSet($name, $template, $flags=0, $sections=NULL, $order=0)


Moving the concatenated labels to the attribute label

Addition by René Bakx(http://renebakx.nl)

If you want to move the concatenated you defined in your fieldset to the label part of the attribute, create an extended fieldset with the following code :

define("AF_FIELDSET_LABEL",                   AF_SPECIFIC_5);
 
class myFieldSet extends atkFieldSet {
 
    var $fieldSetLabel = "";
 
    protected function renderFieldSet($type, $record, $mode, $fieldprefix='') {
        $replacements = array();
        (hasflag($this->m_flags,AF_FIELDSET_LABEL))?$flagToLabel = true:$flagToLabel = false;
        $fields = array_unique($this->getParser()->getFields());
        foreach ($fields as $field) {
            @list($attrName, $part) = explode('.', $field);
            $attr = $this->getOwnerInstance()->getAttribute($attrName);
            switch ($part) {
                case 'label':
                    if ($flagToLabel) {
                        $this->fieldSetLabel[] = $attr->getLabel($record, $mode);
                    } else {
                        $replacements[$attrName][$part] = $attr->getLabel($record, $mode);
                    }
                    break;
                case 'field':
                    if ($type == 'edit')
                        $replacements[$attrName][$part] = $attr->getEdit($mode, $record, $fieldprefix);
                    else if ($type == 'display')
                        $replacements[$attrName][$part] = $attr->display($record, $mode);
                    break;
            }
        }
 
        return $this->getParser()->parse($replacements);
    }
 
    function label($record = array()) {
        if  (hasflag($this->m_flags,AF_FIELDSET_LABEL)) {
            //edit mode is okay, we just need the label part anyway.
            $this->renderFieldSet('edit', $record,'edit');
            return implode(" ",$this->fieldSetLabel);
        } else {
            return parent::label($record);
        }
 
    }
}

As you can see i mapped the last AF_SPECIFIC_FLAG to a new more readable flag so you can use both the default method and the moved label method with one fieldset call

// Render the old way:
   $this->addFieldSet("group0","[department_id.label] [department_id.field] [department_id.label] [manager_id.field] ",AF_SEARCHABLE|AF_BLANK_LABEL,NULL,300 );
// Or render it with the department_id.label and department_id.label as attribute label
   $this->addFieldSet("group0","[department_id.label] [department_id.field] [department_id.label] [manager_id.field] ",AF_SEARCHABLE|AF_FIELDSET_LABEL,NULL,300 );
Personal tools
Navigation