My so far unsuccessful attempt to create a "list-tiddler-field-draggable" macro, to reorder title lists in any field

I would like to be able to reorder the elements any field that is similar to the list field (i.e. a title list) in any tiddler pointed to using a macrocall (transclusion).

I’ll share my attempt with you, in case I got close to the solution and made a small mistake I can’t find.
Surely I will have to modify the part after the comment <!-- Using the following 5 lines as replacement makes dragging titles from outside into the dropdown apply the tag --> (but because I honestly didn’t understand what the comment meant)

  • If anyone has any advice, it is greatly appreciated
\define  list-tiddler-field-draggable-drop-actions(tiddler,field)
\whitespace trim
<!-- Save the current ordering of the tiddlers with this tag -->
<$set name="order" filter="[list[<__tiddler__>!!<__field__>]]">
	<!-- Save the new order to the field -->
	<$action-listops $tiddler=<<__tiddler__>> $field=<<__field__>> $filter="+[enlist<order>] +[insertbefore<actionTiddler>,<currentTiddler>]"/>
	<!-- Make sure the newly added item has the right tag -->
	<!-- Removing this line makes dragging tags within the dropdown work as intended -->
	<!--<$action-listops $tiddler=<<actionTiddler>> $tags=<<__field__>>/>-->
	<!-- Using the following 5 lines as replacement makes dragging titles from outside into the dropdown apply the tag -->
	<$list filter="[<actionTiddler>!contains:tags<__field__>]">
		<$fieldmangler tiddler=<<actionTiddler>>>
			<$action-sendmessage $message="tm-add-tag" $param=<<__field__>>/>
		</$fieldmangler>
	</$list>
</$set>
\end

\define list-tiddler-field-draggable(tiddler,field,subFilter,emptyMessage,itemTemplate,genesisType:"div",storyview:"")
\whitespace trim
<span class="tc-tagged-draggable-list">
	<$set name="field" value=<<__field__>>>
		<$list
			filter="[list[<__tiddler__>!!<__field__>]$subFilter$]"
			emptyMessage=<<__emptyMessage__>>
			storyview=<<__storyview__>>
		>
			<$genesis $type=<<__genesisType__>> class="tc-menu-list-item">
				<$droppable
					actions="""<$macrocall $name="list-tiddler-field-draggable-drop-actions" tiddler=<<__tiddler__>> field=<<__field__>>/>"""
					enable=<<tv-enable-drag-and-drop>>
				>
					<$genesis $type=<<__genesisType__>> class="tc-droppable-placeholder"/>
					<$genesis $type=<<__genesisType__>>>
						<$transclude tiddler="""$itemTemplate$""">
							<$link to={{!!title}}>
								<$view field="title"/>
							</$link>
						</$transclude>
					</$genesis>
				</$droppable>
			</$genesis>
		</$list>
		<$tiddler tiddler=<<__tiddler__>>>
			<$droppable
				actions="""<$macrocall $name="list-tiddler-field-draggable-drop-actions" tiddler=<<__tiddler__>> field=<<__field__>>/>"""
				enable=<<tv-enable-drag-and-drop>>
			>
				<$genesis $type=<<__genesisType__>> class="tc-droppable-placeholder"/>
				<$genesis $type=<<__genesisType__>> style="height:0.5em;"/>
			</$droppable>
		</$tiddler>
	</$set>
</span>
\end


I did this editing a copy of list-tagged-draggable-drop-actions and list-tagged-draggable, found in $:/core/macros/list.

If it's convenient, here's the original code
\define list-tagged-draggable-drop-actions(tag)
\whitespace trim
<!-- Save the current ordering of the tiddlers with this tag -->
<$set name="order" filter="[<__tag__>tagging[]]">
	<!-- Remove any list-after or list-before fields from the tiddlers with this tag -->
	<$list filter="[<__tag__>tagging[]]">
		<$action-deletefield $field="list-before"/>
		<$action-deletefield $field="list-after"/>
	</$list>
	<!-- Save the new order to the Tag Tiddler -->
	<$action-listops $tiddler=<<__tag__>> $field="list" $filter="+[enlist<order>] +[insertbefore<actionTiddler>,<currentTiddler>]"/>
	<!-- Make sure the newly added item has the right tag -->
	<!-- Removing this line makes dragging tags within the dropdown work as intended -->
	<!--<$action-listops $tiddler=<<actionTiddler>> $tags=<<__tag__>>/>-->
	<!-- Using the following 5 lines as replacement makes dragging titles from outside into the dropdown apply the tag -->
	<$list filter="[<actionTiddler>!contains:tags<__tag__>]">
		<$fieldmangler tiddler=<<actionTiddler>>>
			<$action-sendmessage $message="tm-add-tag" $param=<<__tag__>>/>
		</$fieldmangler>
	</$list>
</$set>
\end

\define list-tagged-draggable(tag,subFilter,emptyMessage,itemTemplate,elementTag:"div",storyview:"")
\whitespace trim
<span class="tc-tagged-draggable-list">
	<$set name="tag" value=<<__tag__>>>
		<$list
			filter="[<__tag__>tagging[]$subFilter$]"
			emptyMessage=<<__emptyMessage__>>
			storyview=<<__storyview__>>
		>
			<$genesis $type=<<__elementTag__>> class="tc-menu-list-item">
				<$droppable
					actions="""<$macrocall $name="list-tagged-draggable-drop-actions" tag=<<__tag__>>/>"""
					enable=<<tv-enable-drag-and-drop>>
				>
					<$genesis $type=<<__elementTag__>> class="tc-droppable-placeholder"/>
					<$genesis $type=<<__elementTag__>>>
						<$transclude tiddler="""$itemTemplate$""">
							<$link to={{!!title}}>
								<$view field="title"/>
							</$link>
						</$transclude>
					</$genesis>
				</$droppable>
			</$genesis>
		</$list>
		<$tiddler tiddler="">
			<$droppable
				actions="""<$macrocall $name="list-tagged-draggable-drop-actions" tag=<<__tag__>>/>"""
				enable=<<tv-enable-drag-and-drop>>
			>
				<$genesis $type=<<__elementTag__>> class="tc-droppable-placeholder"/>
				<$genesis $type=<<__elementTag__>> style="height:0.5em;"/>
			</$droppable>
		</$tiddler>
	</$set>
</span>
\end

I wonder if anyone has already tried to do something similar.

1 Like

I have not read your code, and you may find the answer frustrating, given your work above.

  • FYI: this is not valid [list[<__tiddler__>!!<__field__>]] you can’t use variables to compose a text reference. But see below.
<$macrocall $name="list-links-draggable" tiddler=<<currentTiddler>> field=tags/>
  • I use the macrocall so I can pass the tiddler=<<currentTiddler>> because this macro fails if you don’t give a “tiddler” value.
  • For the demo I simple reused “tags field” but any field containing a list of titles would work, it defaults to list which is used in the tag tiddlers, for tags.
  • Now add some tags and drag and drop reorder in view mode.

Review list-links-draggable Macro to do more.

1 Like

Frustrating?
I think you just gave me the solution! :joy:

Understood

Sure, now I’ll see what I can do.
Thank you very much!

Just one thing: is there a way to disable the links?
That is, make sure that when you click on it nothing happens

If you think about this is a little self contradictory, they must be links if you are going to drag and drop them, and by looking like links they suggest they are both draggable and clickable.

  • Is this because they may not be actual tiddlers?, and you want to reorder some strings in your custom fields.

The macro I used is list-links-draggable Macro which implies they are links.

  • We may be able to make use of the class or itemTemplate parameters to stop them, I will see what I can find.
  • Otherwise we may need to build the draggable list from other widgets, or redefine the existing widget, likle you did at the top.

Maybe someone else can help?

Yes

I’m currently making an attempt with the $button widget using its attributes “dragTiddler” or “dragFilter”. I will return here if I’ll find somthing useful to share

1 Like

Good idea. Try the tag=div option and the disable attribute.

1 Like

list-buttons-draggable macro

Done, I’ll leave it here in case it might be of use to anyone.

I added the possibility to also give a class to the button via the “button-class:” parameter.

\define list-buttons-draggable-drop-actions()
<$action-listops $tiddler=<<targetTiddler>> $field=<<targetField>> $subfilter="+[insertbefore<actionTiddler>,<currentTiddler>]"/>
\end

\define list-buttons-draggable(tiddler,field:"list",emptyMessage,type:"div",class:"",button-class:"",itemTemplate)
\whitespace trim
<span class="tc-links-draggable-list">
	<$vars targetTiddler="""$tiddler$""" targetField="""$field$""">
		<$genesis $type=<<__type__>> class="$class$">
			<$list filter="[list[$tiddler$!!$field$]]" emptyMessage=<<__emptyMessage__>>>
				<$droppable
					actions=<<list-buttons-draggable-drop-actions>>
					enable=<<tv-enable-drag-and-drop>>
				>
					<div class="tc-droppable-placeholder"/>
					<div>
						<$transclude tiddler="""$itemTemplate$""">
							<$button class="tc-btn-invisible $button-class$" dragTiddler=<<currentTiddler>>>
									<$transclude field="caption">
										<$view field="title"/>
									</$transclude>
							</$button>
						</$transclude>
					</div>
				</$droppable>
			</$list>
			<$tiddler tiddler="">
				<$droppable
					actions=<<list-buttons-draggable-drop-actions>> 
					tag="div"
					enable=<<tv-enable-drag-and-drop>>
				>
					<div class="tc-droppable-placeholder">
						{{$:/core/images/blank}}
					</div>
					<div style="height:0.5em;"/>
				</$droppable>
			</$tiddler>
		</$genesis>
	</$vars>
</span>
\end