Apply provisional drafts in a custom controller #15272
-
I have a custom controller that copies the value of one field to another. I have it setup as a button in the sidebar of an entry using
If I make a change to the field, save the entry and then run my controller, the value is copied successfully. However, I would like to do it on click. If make a change then run trigger my controller I get 'Recent changes to the Current revision have been merged into this draft.' but the change isn't saved (and the field is still marked as changed.) I thought of saving the entry once before copying my data:
But that doesn't make any difference. I tried Is there any easy way to run my controller -> apply the provisional draft changes to the entry -> do my data copying -> resave the entry? I hope it makes sense, but let me know if anything is unclear. |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 2 replies
-
How much work is your button/JavaScript doing? Is it copying the value directly in the form? Or just triggering an Ajax request to your controller action? What do you want to happen if the user is already editing a provisional draft with other unsaved changes? Would you want all unsaved changes to be applied to the canonical entry? And what if they press the button without having made any unsaved changes (so no provisional draft)? Is creating a provisional draft important, or just that the field value gets copied? |
Beta Was this translation helpful? Give feedback.
-
I’d just go about this by adding a use craft\base\Element;
use craft\base\Event;
use craft\elements\Entry;
use craft\events\DefineHtmlEvent;
use craft\helpers\Html;
Event::on(Entry::class, Element::EVENT_DEFINE_SIDEBAR_HTML, function(DefineHtmlEvent $event) {
$event->html .= Html::button('Run action', [
'class' => ['btn', 'submit', 'formsubmit'],
'data' => [
'param' => 'copyValue',
'value' => '1',
],
]);
}); With that in place, you could then register an after-save listener that checks if the use craft\base\Element;
use craft\base\Event;
use craft\elements\Entry;
use craft\events\ModelEvent;
use craft\helpers\ElementHelper;
Event::on(Entry::class, Element::EVENT_AFTER_SAVE, function(ModelEvent $event) {
/** @var Entry $entry */
$entry = $event->sender;
static $copyingValue = false;
if (
!$copyingValue &&
!ElementHelper::isDraftOrRevision($entry) &&
Craft::$app->request->getBodyParam('copyValue')
) {
$copyingValue = true;
$entry->targetField = $entry->sourceField;
Craft::$app->elements->saveElement($entry);
$copyingValue = false;
}
}); |
Beta Was this translation helpful? Give feedback.
I’d just go about this by adding a
formsubmit
class to the button, which gives you an opportunity to register a new param value on the form, but otherwise let is submit the form normally.With that in place, you could then register an after-save listener that che…