Carsten
Carsten

Reputation: 31

Multiple rows with same ID in Silverstripe GridField

is there a way to group a GridField (for example, by ID)? The following Query (many_many) returns some dataobjects twice or more, if they havent the same SortOrder. Here is some code. I hope that somebody can help ;-)

private static $many_many = array(
    'Mitarbeiter'         => 'Mitarbeiter',
);

private static $many_many_extraFields = array(
    'Mitarbeiter' => array(
        'SortOrder' => "Int"
    )
)

        // Start Mitarbeiterzuordnung
        $MitarbeiterFieldConfig = GridFieldConfig::create()->addComponents(
          new GridFieldToolbarHeader(),
          //new GridFieldSortableHeader(),
          new GridFieldDataColumns(),
          new GridFieldDeleteAction('unlinkrelation'),
          new GridFieldSortableRows('SortOrder'),
          new GridFieldManyRelationHandler(), 'GridFieldPaginator',
          new GridFieldPaginator(20)
        );
        $MitarbeiterField = new GridField("Mitarbeiter", "Mitarbeiter", $this->Mitarbeiter()->sort('SortOrder'), $MitarbeiterFieldConfig);
        $fields->addFieldToTab('Root.Mitarbeiter', $MitarbeiterField);   

Upvotes: 0

Views: 276

Answers (1)

Ben Dubuisson
Ben Dubuisson

Reputation: 757

There is an issue with GridFieldManyRelationHandler.php and having a private static $many_many_extraFields as sorting field.

The query runs with the SortOrder being different and because it uses distinct, the ones having a different values are seen as extra, this is why the ones that have an order set show up twice.

You need to create a copy of GridFieldManyRelationHandler.php (I called it GridFieldManyManyRelationHandler.php) and edit the following function:

    public function getManipulatedData(GridField $gridField, SS_List $list) {
    if(!$list instanceof RelationList) {
        user_error('GridFieldManyRelationHandler requires the GridField to have a RelationList. Got a ' . get_class($list) . ' instead.', E_USER_WARNING);
    }

    $state = $this->getState($gridField);

    // We don't use setupState() as we need the list
    if($state->FirstTime) {
        $state->RelationVal = array_values($list->getIdList()) ?: array();
    }
    if(!$state->ShowingRelation && $this->useToggle) {
        return $list;
    }

    $baseClass = $list->dataClass();
    return $baseClass::get();


}

Then call that new class from your code, ie

private static $many_many = array(
    'Mitarbeiter'         => 'Mitarbeiter',
);

private static $many_many_extraFields = array(
    'Mitarbeiter' => array(
        'SortOrder' => "Int"
    )
)

        // Start Mitarbeiterzuordnung
        $MitarbeiterFieldConfig = GridFieldConfig::create()->addComponents(
          new GridFieldToolbarHeader(),
          //new GridFieldSortableHeader(),
          new GridFieldDataColumns(),
          new GridFieldDeleteAction('unlinkrelation'),
          new GridFieldSortableRows('SortOrder'),
          new GridFieldManyManyRelationHandler(), 'GridFieldPaginator',
          new GridFieldPaginator(20)
        );
        $MitarbeiterField = new GridField("Mitarbeiter", "Mitarbeiter", $this->Mitarbeiter()->sort('SortOrder'), $MitarbeiterFieldConfig);
        $fields->addFieldToTab('Root.Mitarbeiter', $MitarbeiterField);

This probably should be refactored and the two classes should be separated (one class handling many_many and the other has_many).

Upvotes: 0

Related Questions