Updating structure field using Uniform

Hi,
I have a structure field I am trying to update using a Uniform form on the front end of the site. I have this nearly working, but am seeing a strange issue. Following a form submission update, even through the content file itself is updated I am seeing old content on the page.

This is my code as it stands (simplified here for ease):

Blueprint

spreadsheet:
    type: structure
    empty: Click to start creating your spreadsheet
    label: Spreadsheet
    fields:
      columnOne:
        label: 1
        type: writer
        nodes: false
        inline: true
        marks:
          - italic
          - link
      columnTwo:
        label: 2
        type: writer
        nodes: false
        inline: true
        marks:
          - italic
          - link
      columnThree:
        label: 3
        type: writer
        nodes: false
        inline: true
        marks:
          - italic
          - link
      columnFour:
        label: 4
        type: writer
        nodes: false
        inline: true
        marks:
          - italic
          - link
      columnFive:
        label: 5
        type: writer
        nodes: false
        inline: true
        marks:
          - italic
          - link

Page

<?php $rows = $page->spreadsheet()->toStructure();
  foreach($rows as $row): ?>
    <?php snippet('row-content', ['rowContent' => $row->columnOne()->text(),'row' => $row,'column' => 'columnOne']) ?> 
    <?php snippet('row-content', ['rowContent' => $row->columnTwo()->text(),'row' => $row,'column' => 'columnTwo']) ?>
    <?php snippet('row-content', ['rowContent' => $row->columnThree()->text(),'row' => $row,'column' => 'columnThree']) ?>
    <?php snippet('row-content', ['rowContent' => $row->columnFour()->text(),'row' => $row,'column' => 'columnFour']) ?>
    <?php snippet('row-content', ['rowContent' => $row->columnFive()->text(),'row' => $row,'column' => 'columnFive']) ?>
  <?php endforeach ?>

row-content.php snippet (this includes a check to see if the editor has added (EDIT) to the end of the field, which triggers display of the edit form)

<?php
$editable = false;
if(str_ends_with(Str::unhtml($rowContent), '(EDIT)')):
  $endRemoved = preg_replace('/[(]EDIT[)]$/', '', $rowContent);
  $rowContent = $endRemoved;
  $editable = true;
endif;
?>
<?= $rowContent ?>
<?php if($editable): ?>
<?php snippet('forms/update-cell',['content' => Str::unhtml($rowContent), 'row' => $row, 'column' => $column]) ?>
<?php endif ?>

update-cell.php snippet (this is the uniform form)

<form method="POST" class="mt-3">
<?php if ($form->error()): ?>
<div class="px-4 py-2 mb-6 text-base rounded-md text-red bg-red bg-opacity-10"><?php snippet('uniform/errors', ['form' => $form]); ?></div>
<?php endif; ?>

<div class="mb-2">
<label class="block sr-only" for="content">Content</label>
<textarea class="block w-full px-4 py-2 rounded-lg border-grey-300" id="content" name="content" rows="3">
<?= $content ?>
</textarea>
</div>

<input type='hidden' name='rowId' value='<?= $row->id() ?>'/>
<input type='hidden' name='column' value='<?= $column ?>'/>

  <?php echo csrf_field() ?>

  <div>
     <button class="text-white button bg-blue hover:bg-yellow hover:text-blue" type="submit" name="update" value="update">Update</button>
  </div>
</form>

Controller

<?php

use Uniform\Form;

return function ($kirby, $page)
{

    $form = new Form([
        'content' => [],
        'rowId' => [],
        'column' => []
    ]);

    if ($kirby->request()->is('POST')) {

        $data = $form->data('content') . ' (EDIT)';
        $rowId = $form->data('rowId');
        $column = strtolower($form->data('column'));
        echo $data . '<br>';
        echo $rowId . '<br>';
        echo $column;

        $sheet = $page->spreadsheet()->yaml();
        foreach($sheet as $key => $value):
            if($key == $rowId):
                $value[$column] = $data;
            endif;
            $updatedSheet[] = $value;
        endforeach;

        $page->update([
            'spreadsheet' => Data::encode($updatedSheet, 'yaml'),
        ]);
 
    }

    return compact('form');
};

?>

The current behaviour is:

  1. The page loads, and shows edit forms in the correct places
  2. When I fill in a form to update a field, and click submit, the field is updated in the content file
  3. When the page reloads following the form submission, the content shown in the field is not updated
  4. If I reload the page manually, the updated content is shown.

If anyone has any thoughts on this that would be awesome, I can’t work it out!

Update the $page variable:

$page =  $page->update([
            'spreadsheet' => Data::encode($updatedSheet, 'yaml'),
        ]);

Thanks for the quick reply! Unfortunately that has not resolved the issue, I am still seeing the previous content on the page

I have tried redirecting the user to the same page on successful submission by using $form->success() in case that helped, but I am still having the same issue. I am not sure what to try next with it

Another update - I have moved all the page updating bits into a custom Uniform Action, but unfortunately am still seeing the same result. It is like the page is reloading before the update is applied.

Where is your redirect actually happening?

when I create a very simple testcase like this:

Controller:

<?php

return function ($kirby, $page)
{


    $input = null;
    if ($kirby->request()->is('POST')) {

        $input = get('text');

        $kirby->impersonate('kirby');
        $page = $page->update([
            'spreadsheet' => $input,
        ]);
        go($page->url());
    }

    return compact('input');
};

Template:

<?php echo($page->spreadsheet()); ?>

<form action="" method='POST'>
  <input type="text" name="text">
</form>

The page updates perfectly

Hi,

Ok I have put the go($page->url()); in to the action where you have in the example above, and it now works perfectly. I was relying on the page load following the form success to reflect the changes, but it obviously not doing this.

Anyway, the code above works and is doing exactly what I need. Thanks for your time and patience @texnixe