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_member_form() or perch_template() if:

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

perch_member_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_member_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.

File Uploads

The app’s form handler can import uploaded files into Perch as Perch Assets. Firstly, you need to configure the app to use a temporary directory during the upload process:

define('PIPIT_MEMBERS_TMP_PATH', dirname(PERCH_PATH, 2) . '/private_html');

Then you can use a file Perch input tag as you would in any Perch-templated form:

<perch:input id="profile_image" type="file" accept="webimage">

You can also specify the maximum file size with the perch-max-file-size attribute:

<perch:form 
    id="collection_item"
    app="pipit_members"
    collection="Profiles"
    method="POST"
    r="/profile"
    fail="/profile/fail"

    perch-max-file-size="1000000" 
> 
    <perch:input id="profile_image" type="file" accept="webimage">
    <perch:error for="profile_image" type="upload_max_size">
        <p>Error: file must not exceed 1MB</p>
    </perch:error>

    <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>
link