Let’s suppose we want to make a general-purpose drag-and-drop mechanism to copy fields between tiddlers that are being edited. The basic methodology would be something like this:
- wrap the field names displayed in the EditTemplate/fields in a
$draggable
widget
- the widget’s
startActions
param writes fieldname
and fieldvalue
to a temp tiddler (e.g., $:/temp/dragdata
)
- the widget’s
endActions
param deletes the temp tiddler to clean up afterwards
- wrap the background of the EditTemplate in a
$droppable
widget
- the widget’s
actions
param gets the fieldname
and fieldvalue
from the $:/temp/dragdata tiddler and uses $action-setfield
to add that field to the current tiddler.
Here’s a quick example of how to accomplish this:
First, to make the tiddler editor’s field names draggable, edit $:/core/ui/EditTemplate/fields
and replace the first occurence of this:
<$text text=<<currentField>>/>:
with this:
<$draggable tiddler={{{ [<currentTiddler>get<currentField>else[]] }}}
startActions='<$action-setfield $tiddler="$:/temp/dragdata"
fieldname=<<currentField>> fieldvalue={{{ [<currentTiddler>get<currentField>] }}}/>'
endActions='<$action-deletetiddler $tiddler="$:/temp/dragdata"/>'>
<$text text=<<currentField>>/>:
</$draggable>
Then, to handle the “drop on a tiddler editor’s background”, edit $:/core/ui/EditTemplate
, and change this:
<$transclude tiddler=<<listItem>>/>
to this:
<$droppable actions=<<dropfield>>><$transclude tiddler=<<listItem>>/></$droppable>
and add this \procedure
definition to the top of the tiddler:
\procedure dropfield()
<%if [[$:/temp/dragdata]is[tiddler]] %>
<$let newfield={{{ [[$:/temp/dragdata]get[fieldname]] }}} newvalue={{{ [[$:/temp/dragdata]get[fieldvalue]] }}}>
<$action-confirm
$message=`A field named "$(newfield)$" already exists. OK to overwrite?`
$prompt={{{ [<currentTiddler>!has:field<newfield>then[no]else[yes]] }}}>
<$action-setfield $field=<<newfield>> $value=<<newvalue>>/>
</$action-confirm>
</$let>
<%endif%>
\end
Notes:
- In the
$draggable
widget, the $tiddler
param is set to the value of the field being dragged (or blank if it has no value). This allows you to drag a field name and drop it into an $edit-text
widget to copy the field’s value into that input control (all text inputs have a built-in drop handler to accept text values!)
- The
dropfield()
handler makes sure that a $:/temp/dragdata
tiddler exists. This prevents it from responding to other drop events (such as dropping a link or some text).
- The
dropfield()
handler also checks to see if the “target” fieldname already exists. If it does, the handler asks for confirmation to overwrite it.
Note that this is only a very basic example of how to use drag-and-drop to copy fields between tiddlers while they are being edited.You could add more to it, such as using a $:/config
tiddler to enable/disable the $draggable
widget.
enjoy,
-e