nickspiel
nickspiel

Reputation: 5640

SilverStripe gridfield multi class editor has invalid sort() column

I am having trouble setting the SortOrder of a nested has_many relationship where the child items are drag and drop reorder-able though the Orderable Rows module of Gridfield Extensions. I am also using the Multi Class Editor

I have a Page that has many ComplexStrips. These ComplexStrip objects have many 'LinkedObjects'.

The issue:

When I try to add a ComplexStrip via the GridField I get the following error: Uncaught InvalidArgumentException: Invalid sort() column

My Setup:

Page Class: This class is working fine when I browse to edit it in the CMS.

<?php
class Page extends SiteTree {

    private static $has_many = array(
        'ComplexStrips' => 'ComplexStrip'
    );

    public function getCMSFields() {

        $fields = parent::getCMSFields();

        $dataColumns = new GridFieldDataColumns();
        $dataColumns->setDisplayFields(
            array(
                'Title'     => 'Title',
                'ClassName' => 'Class Name'
            )
        );

        $multiClassConfig = new GridFieldAddNewMultiClass();
        $multiClassConfig->setClasses(
            array(
                'ComplexStrip'
            )
        );

        $stripsGridField = GridField::create('ComplexStrips', 'Complex strips', $this->Strips(),
            GridFieldConfig::create()->addComponents(
                new GridFieldToolbarHeader(),
                new GridFieldDetailForm(),
                new GridFieldEditButton(),
                new GridFieldDeleteAction('unlinkrelation'),
                new GridFieldDeleteAction(),
                new GridFieldOrderableRows('SortOrder'), // This line causes the issue
                new GridFieldTitleHeader(),
                $multiClassConfig,
                $dataColumns
            )
        );

        $fields->addFieldsToTab(
            'Root.Strips',
            array(
                $stripsGridField
            )
        );

        return $fields;
    }
}

TextBlocksStrip Class: As soon as I try to add one of these via the gridfield on Page I get the error: Uncaught InvalidArgumentException: Invalid sort() column

<?php
class ComplexStrip extends DataObject {

    private static $db = array(
        'SortOrder' => 'Int'
    );

    private static $has_many = array(
        'TextBlocks' => 'TextBlock'
    );

//-------------------------------------------- CMS Fields

    public function getCMSFields() {

        $fields = parent::getCMSFields();

//---------------------- Main Tab

        $textBlocks = GridField::create('TextBlocks', 'Text blocks', $this->TextBlocks(), 
            GridFieldConfig::create()->addComponents(
                new GridFieldToolbarHeader(),
                new GridFieldAddNewButton('toolbar-header-right'),
                new GridFieldDetailForm(),
                new GridFieldDataColumns(),
                new GridFieldEditButton(),
                new GridFieldDeleteAction('unlinkrelation'),
                new GridFieldDeleteAction(),
                new GridFieldOrderableRows('SortOrder'),
                new GridFieldTitleHeader(),
                new GridFieldAddExistingAutocompleter('before', array('Title'))
            )
        );

        $fields->addFieldsToTab('Root.Main',
            array(
                $textBlocks
            )
        );

        return $fields;
    }
}

TextBlock Class:

<?php
class TextBlock extends DataObject {

    private static $db = array(
        'SortOrder' => 'Int'
    );

    private static $default_sort = 'Sort';

    private static $has_one = array(
        'TextBlocksStrip' => 'TextBlocksStrip'
    );
}

If I remove the line new GridFieldOrderableRows('SortOrder') all works but is obviously not reorder-able.

I am pulling my hair out over this one. Makes no sense to me why this isn't working.

Upvotes: 1

Views: 652

Answers (2)

pinkp
pinkp

Reputation: 455

I had the same error as I was using $many_many instead of $has_many. I can see you used $has_many so wouldn't solve your issue but might help others encountering the same error message like I was.

Upvotes: 1

nickspiel
nickspiel

Reputation: 5640

I have made a fairly elegant workaround.

The SortOrder could not be queried as the parent Object ComplexStrip doesn't exist at the time it is attempting to join the sorted table. So wrapping the GridFieldOrderableRows in an if to check if the parent object has been assigned an ID yet.

// Need to wait until parent object is created before trying to set sort order
if($this->ID) {
    $textBlocks->addComponents(
        new GridFieldOrderableRows('Sort')
    );
}

After that everything works the same as before in the CMS. I will open an issue on the module now to see if there is a more permanent solution.

Upvotes: 3

Related Questions