<p>I managed to figure this out. Here is my working solution.</p>
<pre><code>Event::on(Entry::class, Element::EVENT_AFTER_PROPAGATE, function(ModelEvent $e) {
    // @var Entry $entry
    $entry = $e-&gt;sender;

    if (ElementHelper::isDraftOrRevision($entry)) {
        return;
    }

    if ($entry-&gt;section-&gt;handle != 'events') {
        return;
    }

    $old = $entry-&gt;getFieldValue('events');

    $new = (clone $old)-&gt;orderBy('startDate ASC');

    if ($old-&gt;ids() == $new-&gt;ids()) {
        return;
    }
    
    $entry-&gt;setFieldValue('events', $new);
    Craft::$app-&gt;elements-&gt;saveElement($entry);

});
</code></pre>
<p>Hopefully this helps somebody :)</p>

CC BY-SA 4.0
2022-07-21T14:40:16.360Z
2022-07-21T14:40:16.360Z
Lewis Jenkins
<p>I'm trying to reorder Matrix Blocks in date order when saving an entry in the control panel. I kind of have it working using the following code.</p>
<p>My Matrix field is 'events'. Each block contains a date field called 'startDate'.</p>
<pre><code>Event::on(Entry::class, Element::EVENT_BEFORE_SAVE, function(ModelEvent $e) {
    // @var Entry $entry
    $entry = $e-&gt;sender;

    if (ElementHelper::isDraftOrRevision($entry)) {
        return;
    }

    $blocks = $entry-&gt;getFieldValue('events')-&gt;orderBy('startDate ASC');
    
    $entry-&gt;setFieldValue('events', $blocks);

});
</code></pre>
<p>My problem is that I have to save the Entry TWICE for the above code to actually work. I've read that I should maybe use EVENT_AFTER_PROPAGATE instead but when I try that I can't get it to work at all.</p>
<p>Does anybody know how I can get this working?</p>

<plugin-development><matrix><modules><order>
Reordering Matrix blocks by date in the control panel when saving an entry
# Reordering Matrix blocks by date in the control panel when saving an entry

(Asked by: username_0 on 2022-07-21)

I'm trying to reorder Matrix Blocks in date order when saving an entry in the control panel. I kind of have it working using the following code.
My Matrix field is 'events'. Each block contains a date field called 'startDate'.
Event::on(Entry::class, Element::EVENT_BEFORE_SAVE, function(ModelEvent $e) {
    // @var Entry $entry
    $entry = $e->sender;

    if (ElementHelper::isDraftOrRevision($entry)) {
        return;
    }

    $blocks = $entry->getFieldValue('events')->orderBy('startDate ASC');
    
    $entry->setFieldValue('events', $blocks);

});

My problem is that I have to save the Entry TWICE for the above code to actually work. I've read that I should maybe use EVENT_AFTER_PROPAGATE instead but when I try that I can't get it to work at all.
Does anybody know how I can get this working?

**Tags:** plugin-development, matrix, modules, order

---

## 1 answers

### Answer by username_0 on 2022-07-21. Score: 1

I managed to figure this out. Here is my working solution.
Event::on(Entry::class, Element::EVENT_AFTER_PROPAGATE, function(ModelEvent $e) {
    // @var Entry $entry
    $entry = $e->sender;

    if (ElementHelper::isDraftOrRevision($entry)) {
        return;
    }

    if ($entry->section->handle != 'events') {
        return;
    }

    $old = $entry->getFieldValue('events');

    $new = (clone $old)->orderBy('startDate ASC');

    if ($old->ids() == $new->ids()) {
        return;
    }
    
    $entry->setFieldValue('events', $new);
    Craft::$app->elements->saveElement($entry);

});

Hopefully this helps somebody :)


---

