Updating individual entries in structure via AJAX

I’m trying to create a simple check-in application where the user clicks a button and it updates a structure field entry with checkedin = “Yes” or empty.

  staffers:
    label: Staffers
    type: structure
    style: table
    entry: >
      {{name}}<br />{{email}}
    fields:
      name:
        label: Full Name
        type: text
      email:
        label: Email
        type: email
      checkedIn:
        label: Checked In
        type: hidden

Here’s the code from the AJAX call:

<?php
if(kirby()->request()->ajax()) {

	$userAnswer = kirby()->request()->query()->name();

	// Get Staff Page
	$staffPage = $pages->findBy('uid', 'staff');

	foreach($staffPage->staffers()->yaml() as $staff) {

		if($staff['name'] = $userAnswer and $staff['checkedin'] == '') {

			$this[] = ['name' => $staff['name'], 'email' => $staff['email'], 'checkedin' => 'Yes'];
			$fieldData = yaml::encode($this);
			$staffPage->update(['staffers' => $fieldData]);

		};

		if($staff['name'] = $userAnswer and $staff['checkedin'] == 'Yes') {

			$this[] = ['name' => $staff['name'], 'email' => $staff['email'], 'checkedin' => ''];
			$fieldData = yaml::encode($this);
			$staffPage->update(['staffers' => $fieldData ]);
		};
	}
}
else {
	header::status('404');
}

Using this method, it updates all of the entries in the structure, which makes sense. I’m wanting to just update the single entry (which I’m sure is pretty easy) but I’m not sure how to go about it.

Any ideas?

Not tested, but I think something like this should work:

if(kirby()->request()->ajax()) {

    $userAnswer = kirby()->request()->query()->name();

    // Get Staff Page
    $staffPage = $pages->findBy('uid', 'staff');
    $staffList = $staffPage->staffers()->yaml();

    foreach($staffList as &$staff) {

        if($staff['name'] = $userAnswer and $staff['checkedin'] == '') {
            $staff['checkedin'] = 'Yes';
        } else if($staff['name'] = $userAnswer and $staff['checkedin'] == 'Yes') {
            $staff['checkedin'] = '';
        };
    }

    $staffPage->update(['staffers' => yaml::encode($staffList)]);
}
else {
    header::status('404');
}

The ‘&’ (reference) in the foreach loop allows you to modify the loop $staff item (it updates the actual element in $staffList). Then you just update the staffers field with the complete updated staff list.

Edit: What context exactly is this executed in? The $this[] does not make much sense to me; what is $this in this particular context?

2 Likes

i like the way that works for updating entries. how would i adjust the code, so an entry will be deleted if the value reaches zero (no, 0, empty) or whatever?

You can do it like this (pseudo code in the if statement):

<?php
$items = $page->items()->yaml();

foreach ($items as $key => &$item){
     if(condition) {
       unset($items[$key]);
     };
}
dump($items);

thanks that works,

i’ve attempted to use unset before, however not in combination with $items as $key => $value

that resulted into my failure …