<p>The <code>BaseRelationField</code> is able to relate all elements - even Matrix Blocks but it's a little bit tricky because in order to display everything properly you need to define <code>sources</code> but Matrix Blocks have no sources.</p>

<p>At first we need to make sure our Matrix Blocks have a valid source, otherwise this Javascript check messes all up</p>

<pre><code>var $sources = this._getSourcesInList(this.getSourceContainer());

// No source, no party.
if ($sources.length === 0) {
    return false;
}
</code></pre>

<p>And nothing works So we need the following</p>

<pre><code>Event::on(
    MatrixBlock::class,
    MatrixBlock::EVENT_REGISTER_SOURCES,
    function(RegisterElementSourcesEvent $event) {
        if (empty($event-&gt;sources)) {
            $event-&gt;sources[] = [
                'key'         =&gt; 'MySource',
                'label'       =&gt; 'All Matrixes',
                'defaultSort' =&gt; 'elements.id',
                'data'        =&gt; [
                    'handle' =&gt; 'matrix'
                ],
                'criteria'    =&gt; [
                    'typeId' =&gt; 21,
                    'fieldId' =&gt; 70 // &lt;-- this is the matrix field of Entry A otherwise the values won't be populated
                ]
            ];
        }
    }
);
</code></pre>

<p>In order to display an identifier we need to set the <code>title</code> attribute to the block, otherwise all we see is an id.</p>

<pre><code>Event::on(
    MatrixBlockQuery::class,
    MatrixBlockQuery::EVENT_AFTER_POPULATE_ELEMENT,
    function(PopulateElementEvent $event){
        $element = $event-&gt;element;
        if($element-&gt;getType()-&gt;handle === 'person'){ //&lt;-- make it is the correct matrix block
            try{
                $element-&gt;title = $element-&gt;getFieldValue('firstName') . ' ' . $element-&gt;getFieldValue('lastName');
            }catch(Exception $exception){
                // whatever you need
            }
        }
    }
);
</code></pre>

<p>Since Matrix Blocks usually have no table attributes we need to define them as well</p>

<pre><code>Event::on(
    MatrixBlock::class,
    MatrixBlock::EVENT_REGISTER_TABLE_ATTRIBUTES,
    function($event) {
        $event-&gt;tableAttributes['id'] = ['label' =&gt; 'ID'];
        $event-&gt;tableAttributes['email'] = ['label' =&gt; 'Email'];
    }
);
</code></pre>

<p>After that you can use the normal <code>BaseRelationField</code> and extend it like you are used to for custom element types</p>

CC BY-SA 4.0
2018-05-17T08:35:44.863Z
2018-05-17T08:35:44.863Z
Robin Schambach
<p>I would like to create a field / a way to relate a certain Matrix Block to another Element. Is this possible?</p>

<p>For example:</p>

<p>Entry A contains a Matrix Field <code>matrix</code> and has several blocks. I want to relate one of those blocks to Entry B</p>

<plugin-development><field>
How to create a Matrix Relation field / relate Matrix Blocks to other Elements
# How to create a Matrix Relation field / relate Matrix Blocks to other Elements

(Asked by: username_0 on 2018-05-17)

I would like to create a field / a way to relate a certain Matrix Block to another Element. Is this possible?

For example:

Entry A contains a Matrix Field `matrix` and has several blocks. I want to relate one of those blocks to Entry B

**Tags:** plugin-development, field


---

## 1 answers

### Answer by username_0 on 2018-05-17. Score: 2 | Accepted answer

The BaseRelationField is able to relate all elements - even Matrix Blocks but it's a little bit tricky because in order to display everything properly you need to define sources but Matrix Blocks have no sources.
At first we need to make sure our Matrix Blocks have a valid source, otherwise this Javascript check messes all up
var $sources = this._getSourcesInList(this.getSourceContainer());

// No source, no party.
if ($sources.length === 0) {
    return false;
}

And nothing works So we need the following
Event::on(
    MatrixBlock::class,
    MatrixBlock::EVENT_REGISTER_SOURCES,
    function(RegisterElementSourcesEvent $event) {
        if (empty($event->sources)) {
            $event->sources[] = [
                'key'         => 'MySource',
                'label'       => 'All Matrixes',
                'defaultSort' => 'elements.id',
                'data'        => [
                    'handle' => 'matrix'
                ],
                'criteria'    => [
                    'typeId' => 21,
                    'fieldId' => 70 // <-- this is the matrix field of Entry A otherwise the values won't be populated
                ]
            ];
        }
    }
);

In order to display an identifier we need to set the title attribute to the block, otherwise all we see is an id.
Event::on(
    MatrixBlockQuery::class,
    MatrixBlockQuery::EVENT_AFTER_POPULATE_ELEMENT,
    function(PopulateElementEvent $event){
        $element = $event->element;
        if($element->getType()->handle === 'person'){ //<-- make it is the correct matrix block
            try{
                $element->title = $element->getFieldValue('firstName') . ' ' . $element->getFieldValue('lastName');
            }catch(Exception $exception){
                // whatever you need
            }
        }
    }
);

Since Matrix Blocks usually have no table attributes we need to define them as well
Event::on(
    MatrixBlock::class,
    MatrixBlock::EVENT_REGISTER_TABLE_ATTRIBUTES,
    function($event) {
        $event->tableAttributes['id'] = ['label' => 'ID'];
        $event->tableAttributes['email'] = ['label' => 'Email'];
    }
);

After that you can use the normal BaseRelationField and extend it like you are used to for custom element types


---

