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:
- The page loads, and shows edit forms in the correct places
- When I fill in a form to update a field, and click submit, the field is updated in the content file
- When the page reloads following the form submission, the content shown in the field is not updated
- 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!