Skip to content

Sort order is not respected for Formkit ElementSelectInputs #2746

@superextinct

Description

@superextinct

Describe the bug

In the current implementation, domToModel() is only called after elements have been added or removed, but not when elements are re-ordered.

Steps to reproduce

Render an elementSelect Input:

public function defineGeneralSchema(): array
{
    return [
        SchemaHelper::elementSelectField([
            'label'=> 'Schritte',
            'help' => 'Einträge auswählen, die als Schritte angezeigt werden sollen.',
            'name' => 'sourceElements',
            'validation' => 'required',
            'required' => true,
            'config' => [
                'jsClass' => $this->cpInputJsClass,
                'elementType' => static::elementType(),
                'limit' => null,
            ],
            'selectionLabel' => Craft::t('app', 'Choose'),
        ]),
    ];
}

Add and re-order elements, apply the field settings and observe the sort order has been reset to the insertion order.

Form settings

Not applicable

Craft CMS version

5.9.14

Plugin version

dev-craft-5

Multi-site?

No response

Additional context

For "Entries" fields, this would also require more changes. In my custom field, I'm doing this:

public function getElementsQuery(): ElementQueryInterface
{
    $query = parent::getElementsQuery();

    // When elements are manually curated, the parent applies orderBy('title ASC') which
    // destroys the user-defined sort order. Use fixedOrder() to preserve it.
    if (!empty($this->sourceElements)) {
        $query->orderBy(null)->fixedOrder();
    }

    return $query;
}

public function modifyFieldSettings(array $settings): array
{
    $settings = parent::modifyFieldSettings($settings);

    // The parent re-queries sourceElements without fixedOrder(), returning elements in DB
    // order instead of the user-defined order. Re-run with fixedOrder() to fix that.
    if ($ids = ArrayHelper::getColumn($this->sourceElements, 'id')) {
        $elements = static::elementType()::find()->id($ids)->fixedOrder()->status(null)->all();

        $settings['sourceElementsOptions'] = array_map(fn($el) => [
            'label' => $this->getElementLabel($el),
            'value' => $el->id,
        ], $elements);

        $settings['sourceElementsHtml'] = Craft::$app->getView()->renderTemplate(
            'formie/_includes/element-select-input-elements',
            ['elements' => $elements]
        );
    }

    return $settings;
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions