How to sort a pages field by date?

Hi there,

on my site I have a bunch of projects. For each project I would like my user to be able to choose to let it appear in the gallery or/and to appear in the calendar section.

So I thought I go with two pages fields, one for each purpose. That works kind of, but in the calendar pages field I would like to sort the projects automatically by a date field on the project page? Is there any way to do this?

Thanks!

At first, you should use a date field like that:

fields:
  published:
    label: Published on
    type: date
    default: today

After that, you can get projects by sorted date like that:

foreach(page('projects')->children()->sortBy('published', 'desc') as $project) {
    // todo
}

No, I am not talking about sorting in the frontend, rather I need to sort a pages field in the panel.

query: page.children.sortBy('date', 'desc')

That will sort the pages by date. Additionally, you can add the date as info in the select field:

query: page.children.sortBy('date', 'desc')
info: "{{ page.date.toDate('Ymd') }}"
1 Like

That only sorts them in the selection dialog. I actually need to have them sorted in the resulting list (and therefore need to disable manual sorting, but I could do that via some custom panel CSS, if necessary).

There doesn’t seem to be a setting to set sortable to false. CSS would be an option, yes.

Disabling the sorting is not really my main issue. My main issue is how to sort the resulting list (not the selection dialog) by a (date) field.

If you sort them in the dialog, they should come out sorted in the resulting list, don’t they? At least they do in my test.

Ok, I only tested this with a title field now (but I guess it should work the same), here’s the issue:

  1. I click select and select “Project B” and hit OK, “Project B” gets listed.
  2. I click select again and now select “Project A” and hit OK. “Project A” now gets listed below “Project B” because it was added last, although according to my sorting idea it should automatically placed above “Project B”.

So unless I am misunderstanding you, I don’t think the list entries come out sorted exactly like in the list.

Ok, true, that only works if you select them all at once.

Which is not how I intend the panel field to be used. I wonder what else I can do?
I guess I need to sort them via a hook and then rewrite the pages field somehow, maybe?

The problem is probably that the field stores stuff in the content file. You could use a hook that sorts them after saving. Don’t know if it would work with a before hook as well. But the best solution would probably be a custom field.

Is there any documentation on how to create a custom field? That sounds like it might be above my skill level.

But you need some Vue.js to create a custom field (or any Panel extension because the Panel is based on Vue.js)

Maybe it would be enough to make a copy of the field and change the way it displays the list.

That looks like it’s out of my comfort zone.

What would be the problem with hooks, though?

I didn’t say it was a problem, but they only work when the user interacts with the page, i.e. stores the stuff, before that, nothing will happen.

Edit: I see you have already created an ideas issue:

So you mean there is no hook that gets fired when they fill the pages field, but only one when they save the page. Did I get this right?

That’s exactly what I meant.

Ok, thanks. I will look into these options and will see what would be my best bet in this scenario. I don’t feel comfortable using Vue, but if I find time I will look at the video tutorials. I think it would make for a good new feature though, that’s why I created the idea issue. If anyone comes accross this, feel free to upvote the issue, if you also think the feature would make sense. :slight_smile:

Done.

1 Like