4

I'm looking for a way to keep matrix inputs populated with their original value after submitting a form containing errors. I'm already aware of the method of doing this for general inputs as shown here but I can't find an example of doing the same thing with a matrix field input. Here is my form currently without such functionality.

<form method="post" accept-charset="UTF-8">
    {{ getCsrfInput() }}
    <input type="hidden" name="action" value="entries/saveEntry">
    <input type="hidden" name="redirect" value="/">
    <input type="hidden" name="sectionId" value="5">
    <input type="hidden" name="enabled" value="1">

    // First goal
    <input type="hidden" name="fields[year][new1][type]" value="goal">
    <input type="hidden" name="fields[year][new1][enabled]" value="1">
    <input type="text" id="descriptionMeasurement" rows="4" name="fields[year][new1][fields][descriptionMeasurement]">
    <input class="dueDate" name="fields[year][new1][fields][dueDate][date]" type="text" placeholder="mm/dd/yyyy">
    <input id="weight" type="number" min="1" max="100" name="fields[year][new1][fields][weight]">

    // Second Goal
    <input type="hidden" name="fields[year][new2][type]" value="goal">
    <input type="hidden" name="fields[year][new2][enabled]" value="1">
    <input type="text" id="descriptionMeasurement" rows="4" name="fields[year][new2][fields][descriptionMeasurement]">
    <input class="dueDate" name="fields[year][new2][fields][dueDate][date]" type="text" placeholder="mm/dd/yyyy">
    <input id="weight" type="number" min="1" max="100" name="fields[year][new2][fields][weight]">

    <input type="submit" value="Save Goals">
</form>
1
  • Experiencing the same. Subscribing to this. Hope someone could help. – user3547 Apr 17 '15 at 2:41
4

As you've discovered, your Matrix Field behaves a bit differently than many other basic fields. The Matrix Field, is composed of several Matrix Blocks and, like Entries themselves, Matrix Blocks are Element Types. So, you can access your value on a MatrixBlockModel in the familiar way that you know how to do already on your EntryModel, however, first you need to get to it which requires an extra step from the EntryModel you get back when a form fails validation.

When your Form fails validation, an EntryModel gets returned to the page. This EntryModel can't be accessed directly but its attributes and methods can be accessed. From the example you referenced:

{# Our Title can be found on our EntryModel like so #}
{% if entry is defined %}{{ entry.title }}{% endif -%}

{# And errors can be accessed on our EntryModel too #}
{{ entry.getErrors('title') }}

We can access our Matrix Field like our Title field or any other custom field, but since it's not a simple field, it gives us back an ElementCriteriaModel and we can't output anything without navigating further into the model and accessing each block and the fields within each block directly.

{# This will thrown an error "Object of class Craft\ElementCriteriaModel could not be converted to string" #}
{{ entry.matrixFieldHandle }}

{# But we can access the first block just like we would a single Entry or Asset #}
{{ entry.matrixFieldHandle.first() }}

{# And a field within that block in the same way we would a field on the EntryModel #}
{{ entry.matrixFieldHandle.first().fieldHandle }}

{# And the errors of those fields within a block in the same way we would a field on the EntryModel #}
{{ entry.matrixFieldHandle.first().getError('fieldHandle') }}

To navigate all the retained values and errors for your Matrix Field, you'll need to loop through the MatrixBlockModels of your matrix entry.matrixFieldHandle and output the values and errors within your template.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.