Overriding a page variable used in a self updating ajax partial, from component ajax handler

I’m struggling with this a bit…

I have a component that sets a $count and an $attendees page variable in the onRun method

public function onRun()
{
    // Note: $attendees is an array of attendee details

    $this->page['count'] = $attendees ? count($attendees) : 1;
    $this->page['attendees'] = $attendees ?? [];
}

I have a partial on my page that contains a self updating ajax partial within it, that displays a form, and loops over the $count value, displaying a set of fields for each iteration. Pre-filling the form fields if the data is available at that index in the $attendees array.

The first item in the array will display a button, that I want to make an ajax request with, to add the logged in users details to the first item of the array.

<form data-request="onSubmit">
    {% for i in 1..count %}
        {% set attendee = attendees[i] %}
        {% if loop.first %}
            <button
                 data-request="onAddUserAsAttendee"
                 data-request-update="{ _self: true }">
                 Use my details
            </button>
        {% endif %}
        <input name="attendee[i][first_name] value="{{ attendee.first_name }}" />
        <input name="attendee[i][last_name] value="{{ attendee.last_name }}" />
    {% endfor %}
    <button type="submit">Submit</button>
</form>

Then in my component 's onAddUserAsAttendee ajax handler I have this…

public function onAddUserAsAttendee()
{
    // I get my logged in user's data stored as an array in a $userData variable

    // Add this user's data to the first item in the array
    // P.S. I know it's not zero indexed here
    $this->page['attendees'][1] = $userData;
}

My understanding is that the form.htm ajax partial should update itself, and be able to use the new attendees page variable… but it only works if I don’t set $this->page['attendees'] in the component’s onRun method.

The problem then, is that I don’t have the data available to me on page load to fill in the form with existing data.

I feel like I’m missing something fundamental here with self updating ajax partials and page variables. If anybody has idea on how I can sort this, I’d be very appreciative. Thanks

I’ve got around this by checking if the request is an ajax request in the onRun method on my component… Seems a bit hacky though, so if there’s a better way please tell me

if (!Request::ajax()) {
    $this->page['attendees'] = $attendees ?? [];
}

Hey @neil-impelling

This could be a result of the capture lifecycle, documented here:

It mentions what you’ve done as a solution:

Since it counts as a complete page render, this may mean the onRun component method is called when an AJAX partial handler is used. ​You can use Request::ajax() helper method to determine if the request is occurring as the result of an AJAX request.

It is possible to determine that you are in an AJAX context though, by way of being inside the onAddUserAsAttendee handler.

1 Like