Jump to content

AtkExtendableShuttleRelation

From NusaATK

Relation: atkExtendableShuttleRelation

API docs | Flags

Overview of other ATK relations
Alphabetical list

File:AtkExtendableShuttleRelation.png
atkExtendableShuttleRelation screenshot

The extendableShuttleRelation is a many-to-many relation which can be extended with so called controls. These controls are AJAX-components which can, for example, be used to show information about the current available/selected items or to filter these items.

The extendableShuttleRelation is based on the atkShuttleRelation: This implies that its core functionality is the same as the shuttleRelation and therefore can be a substitute for the ordinary shuttleRelation, and might, in time, completely replace the current shuttleRelation.

function atkExtendableShuttleRelation ($name, $link, $destination, $flags=0)
 String $name The name of the relation. 
 String $link The full name of the node that is used as intermediairy node. 
 String $destination The full name of the node that is the other end of the relation. 
 int $flags Flags for the relation. 

As said, the relation can be extended with controls, or more specific, filters. The difference between a control and a filter is that a control is readonly (e.g. a counter for selectable records) and a filter influences the entries in the shuttle lists (e.g. a filter which limits selectable records to records ending with '1'). Multiple filters can even depend on each other.

If you want to use a control or filter, you have to extend the atkShuttleControl class or the atkShuttleFilter class and at least implement the following function:

  /**
   * Renders the control. Returns a piece of HTML that is used in the shuttle
   * to represent this control. If this control has input elements then the
   * getFormName method can be used to retrieve the base name for the input
   * elements. The getValue method can be used to retrieve this controls value(s)
   * for the given record.
   *
   * @param array $record full record
   * @param string $mode add/edit mode
   * @param string $prefix field prefix
   *
   * @return string HTML string
   */
  public abstract function render($record, $mode, $prefix);

For the atkShuttleFilter you need to implement one more function:

  /**
   * Returns a filter clause for this filter's current value.
   * The current value can be retrieved from the record using
   * the getValue function.
   *
   * @param array $record full record
   */
  public abstract function getFilter($record);

Optionally, you can implement this function:

  /**
   * Called if a filter or selection event has occured. And allows the control to
   * state if it needs to be refreshed based on the filter or selection changes.
   *
   * @param string $type  type of event ('filter' or 'selection'
   * @param array $record full record (see partial_filter, partial_selection for more information)
   *
   * @return boolean needs refresh?
   */
  public function needsRefresh($type, $record)

Controls can be added to the relation as follows:

atkExtendableShuttleRelation::addControl($name, $section)
 String $name The name of the control
 String $section Either atkShuttleControl::AVAILABLE or atkShuttleControl::SELECTABLE. This tells the relation on which shuttle list you want to add the control.

Example:

	
  userelation("atkextendableshuttlerelation");
  atkimport("controls/class.selectedcountercontrol.inc");
  atkimport("controls/class.searchfilter.inc");

  class exampleNode extends atkNode
  {
    function exampleNode()
    {
      $this->atkNode("exampleNode");

      $this->add(new atkAttribute("id",AF_AUTOKEY));
      $this->add(new atkAttribute("name",AF_OBLIGATORY));

      $relation  = new atkExtendableShuttleRelation("shuttleExample","example.interm","example.node2");

      $relation->addControl(new selectedCounterControl('selected'), atkShuttleControl::SELECTED);

      $relation->addControl(new searchFilter('sfilter'), atkShuttleControl::AVAILABLE);

      $this->add($relation);

      $this->setOrder("name");
      $this->setTable("example_table");
    }
 }
  class searchFilter extends atkShuttleFilter
  {
    public function getFilter($record)
    {
      $filterValue = escapeSQL($this->getValue($record));
      if ($filterValue!="")
      {
        $this->m_shuttle->addDestinationFilter("name LIKE '%{$filterValue}%'");
      }
    }

    public function render($record, $mode, $prefix)
    {
      parent::render($record,$mode,$prefix);

      return '
        <div id="'.$this->getFormName($prefix).'">
          <input type="text" name="'.$this->getFormName($prefix).'" onkeyup="'.$prefix.$this->getName().'_onChange(this)" value="'.$this->getValue($record).'" />
        </div>
      ';
    }
  }
  class selectedCounterControl extends atkShuttleControl
  {
    public function needsRefresh($type, $record)
    {
      if ($this->getValue($record)!==count($record[$this->m_shuttle->fieldName()]['selected']))
      {
        return true;
      }
      else
      {
        return false;
      }
    }

    public function render($record, $mode, $prefix)
    {
      return '
        <div id="'.$this->getFormName($prefix).'">'.$this->m_name.': '.count($record[$this->m_shuttle->fieldName()]['selected']).'</div>
      ';
    }
  }

This will result into: