How do I REQUIRE a delete confirmation for a tiddler with no text field?

First, just to be upfront: I know about the plugin that lets you “trash” deleted tiddlers, and the plugin that saves tiddler revisions. I’m not interested in either of these. I simply want to ALWAYS CONFIRM a tiddler deletion, every time, no matter what.

In view mode (only), if your tiddler has an empty text field, it does not ask for confirmation before deleting the tiddler.

This is by design, so that you can quickly delete empty tiddlers you didn’t mean to create.

But if you’re using fields to store your data + a viewtemplate to show a unified display for that data, and you don’t currently have anything in the text field, then it is FAR too easy to accidentally delete a tiddler full of complicated fields with a single misclick, with no chance to cancel. And if you haven’t saved the wiki since creating that new tiddler, then you have to start all over from scratch.

  • Searching around, this was brought up 4 years ago in the GG, and there’s an open issue from 2016 about this as well. Unfortunately, neither provides solutions/workarounds, other than a suggestion implying a custom button.

I can make my own custom delete button for view mode, but I’d prefer to look first for a better solution that doesn’t duplicate existing functionality. Plus, the code’s constantly evolving, so there may be a solution that wasn’t available earlier.

I believe the code for deletion is part of $:/core/modules/widgets/navigator.js (search for “seek confirmation” to see its section), but I don’t know Javascript, and even if I did I wouldn’t feel safe making changes to that tiddler, because it does…well, everything!

So: other than making a custom delete button, is there a way to override the core’s empty-text-field check so that it ALWAYS pops up the delete confirmation prompt instead?

  • The core delete tiddler button ($:/core/ui/Buttons/delete) uses <$button actions=<<cancel-delete-tiddler-actions "delete">>.
  • The cancel-delete-tiddler-actions macro is defined in $:/core/ui/ViewTemplate and $:/core/ui/EditTemplate.
    • The ViewTemplate version is very simple:
      \define cancel-delete-tiddler-actions(message) <$action-sendmessage $message="tm-$message$-tiddler"/>
    • The EditTemplate version adds an additional nested macro which cleans up state tiddlers:
\define cancel-delete-tiddler-actions(message)
\whitespace trim
<<delete-edittemplate-state-tiddlers>>
<$action-sendmessage $message="tm-$message$-tiddler"/>
\end

In both cases, we’re ultimately using <$action-sendmessage $message="tm-delete-tiddler"/> to handle the deletion, and the tm-delete-tiddler message is itself handled by the navigator widget. So rather than modifying the JS used by the core, I think it’s easiest to redefine the cancel-delete-tiddler-actions macro used by the button.

We can do this without touching any core tiddlers by placing the following code in a new tiddler with the tag $:/tags/Macro/View or $:/tags/Global/View.

\procedure cancel-delete-tiddler-actions()
<$action-confirm $message="Do you wish to delete the current tiddler?">
<$action-deletetiddler $tiddler=<<currentTiddler>> />
<$action-listops $tiddler="$:/StoryList" $field="list" $subfilter="-[<currentTiddler>]" />
</$action-confirm>
\end
  • The tm-delete-tiddler message removes the tiddler from the story river in addition to deleting it. To duplicate this functionality, we need to include the $action-listops widget as well as $action-deletetiddler; otherwise, the newly-missing tiddler will remain in its original place in the river.
  • Using the /View variant rather than simply $:/tags/Macro prevents our new macro from overwriting the version used in the EditTemplate, which you presumably don’t want to change.

Here’s a premade version you can drag into your wiki: ConfirmDelete.tid (400 Bytes)

Note that I’ve used 5.3.0+ features in the above code. If you’re running an older version of TW, you’ll want to use \define rather than \procedure; otherwise, I believe the code should function as-is.

4 Likes

…it works! It’s simple! You’re fantastic. :heart: I can also confirm that changing \procedure to \define makes it work in the 5.2.3 version I had on hand to test with.

And thank you even more for including your process; that helps me understand why I couldn’t figure it out. By now, I really should have thought to track backwards through the existing delete button. I guess I was too hung up on searching the code for “confirm”. It also looks like I need to read up on $:/StoryList too.

1 Like

This feels to me the sort of enhancement that would be good for 5.4.0 - change the delete prompt trigger from “if text field exists” to “if any field other than ‘created, creator, modified, title, type’ exist and with content”?

We need not introduce it with 5.4 as it need can be backward compatible by providing a toggle setrting for the “new behaviour”. Keep in mind a lot of people will be used to the current behaviour.

Good point - could even have a range of settings (never prompt / prompt if text field exists / prompt if any non-core field exists / always prompt).

What should be default is always up to debate, as everyone’s tastes differ, so I’m happy to not wade into that beyond noting I’d definitely appreciate it prompting on non-core fields (more than once I’ve been cleaning up “empty” tids and suddenly remembered they may have exists for field-only reasons, and gone to check my git repo (node tw with a git commit every few days)

I did “bump” the GitHub issue. Since I think it is a bug and should be fixed.

3 Likes