Sorting Structured field by multiple fields in panel

Dear forum,

I may miss something fundamental here.

I want to sort a structured field by multiple fields.

I thought, if this is possible

$books = page('books')->children()->listed()->sortBy('lastname', 'asc', 'firstname', 'asc');

then I can do the same in a blueprint for a structured field with
sortBy: date_field desc time_field desc

But it only works with one of the fields.

So I guess, sortBy can only accept one field?

Sidenote:
What I actually want to achieve:
New entries in a structured field are added programmatically.
The display of these entries should be sorted by descending order (the newest entry on top).
But when updating entries to a structured field, they are always added at the end of the yaml list. Sorting the yaml array before adding them back to the structured field leads to strange behavior.

Thanks for the help.

According to the docs you can only sort by one field, not multiple in the blueprint

1 Like

Why not use a datetime field instead of separate fields for date and time?

In what way? Maybe you have an issue in your code?

Thanks for your help!

Updating a datetime field in a structured field programmatically or updating a time field in a structured field programmatically always let to a time which is not accurate (rounded up to the nearest 5 minutes).
And I need exact minutes in the date field.

This is why I added 2 fields:
One for the date with the type “date”, and one for the time with the type “text” (not ideal, I know).
I found a few forum issues concerning similar problems, I will look them up again if you like.

This is why I do not have a datetime field I can use for “sortBy”

Thanks for asking.

This is my code now

 try {
          $logs = $newUser->logs_data()->yaml();
          $message = 'Email changed to: ' . $newUser->email();
          // attach the log entry to the user's logs
          $logs[] = createUserLogEntry($message);
          // todo: sort here, or before line above => array_unshift first with existing $logs
          $newUser->update(['logs_data' => Data::encode($logs, 'yaml')]);
        } catch (Exception $error) {
          throw new ErrorException($error->getMessage());
        }

I tried here to sort the logs, unshift the array, reverse etc before updating the structured field.
But it did not work in the way I wanted (the yaml in the the user.de.txt was never correctly updated in the correct order).

You can set the unit and size for time, example:

      date:
        label: Date
        type: date
        time:
          step:
            unit: second
            size: 1
          display: HH:mm:ss

The date is then stored like this:

Date: 2025-01-01 18:00:13

Unfortunately, you left out the important part of sorting your array, unshifting or reversing won’t help if the order is not sorted the way you want. Use usort() instead.

Thank you again for your great help !

Changing the date field to

date:
        label: Date
        type: date
        time:
          step:
            unit: second
            size: 1
          display: HH:mm:ss

and storing the value with $dateNow->format('Y-m-d H:i:s') works now perfectly with the sorting of the structured field.

PS: I also used usort in between at some point and may have missed there something, for sure. But the solution above is way better. No need to make the programmatic update of the structured field more complicated.