Add or edit a collection item

Add or edit a collection item on form submission. This is a Runway only feature.

<perch:form 
    id="collection_item"
    app="pipit_members"
    collection="Tickets"
    method="POST"
    r="/tickest/success"
    fail="/tickets/fail"
> 
    <perch:input type="submit" value="Save">

    <!--* logged-in member's CSRF token *-->
    <perch:input type="hidden" id="token">

    <!--* collection item's ID. If empty, a new item is created *-->
    <perch:input type="hidden" id="_id">
</perch:form>

Creating a new item

When creating a new item, you only need the member’s token (and ID if you’re linking the member to the collection item). So you would either output the form with perch_members_form() or perch_template() if:

perch_members_form() automatically passes the required data to the template engine:

perch_members_form('my_form.html');

On the other hand, you need to pass the data yourself when using perch_template():

perch_template('content/my_collection/_form', [
    'token'  => perch_member_get('token'),
    'member' => perch_member_get('id'),
]);

Editing an item

There are more than one way to do this. The goal is to have the following available to you in the template:

  1. The collection item’s data
  2. The member’s data (at minimum the CSRF token)

Output the form with perch_member_form()

// get the collection item
$ticket = perch_collection('Tickets', [
    '_id'           => perch_get('id'),
    'skip-template' => true,
]);

// make the item's data available to the templating enging
// Note we are using set_vars() not set_var()
PerchSystem::set_vars($ticket[0]);

// output the form with perch_member_form()
perch_member_form('my_form.html');

Output the form with perch_collection()

// example url /tickets/?id=88
$ticket = perch_collection('Tickets', [
    '_id'       => perch_get('id'),
    'template'  => 'tickets/_edit.html',
    'data'      => [
        'token' => perch_member_get('token'),
    ]
]);

Linking a member to a collection item

While the above example works, in most cases you wouldn’t want any member to edit any collection item. You want to link them. Technically a text field to store the member’s ID would do the trick, but that wouldn’t be user-friendly. You can use the members field type instead.

In your collection edit template:

<perch:content id="member" type="members" label="Member" max="1" required>

Pass the logged-in member ID to the template:

// when editing an existing item
$ticket = perch_collection('Tickets', [
    'template'  => 'tickets/_edit.html',
    'filter'    => [
        [
            'filter' => '_id',
            'value' => perch_get('id'),
        ],
        [
            'filter' => 'member',
            'value' => perch_member_get('id'),
        ],
    ]
    'data'      => [
        'token'  => perch_member_get('token'),
        'member' => perch_member_get('id'),
    ]
]);
<perch:form 
    id="collection_item"
    app="pipit_members"
    collection="Tickets"
    method="POST"
    r="/tickest/success"
    fail="/tickets/fail"
>     
    <perch:input type="submit" value="Save">

    <!--* logged-in member's CSRF token *-->
    <perch:input type="hidden" id="token">

    <!--* collection item's ID. If empty, a new item is created *-->
    <perch:input type="hidden" id="_id">

    <!--* Member ID *-->
    <perch:input type="hidden" id="member[]" value="<perch:content id="member">">
</perch:form>

Note that you need to use the relevant namespace. If you output the form with perch_collection(), you use perch:content. If you output the form with perch_members_form(), you use the perch:forms namespace. You can always use perch:showall to check the namespace.

Also note that the members field type expects the value to be an array. So the input ID should reflect that as demonstrated above.

link