[js] Please help make widget from this js demo?

159 views
Skip to first unread message

Mat

unread,
Mar 25, 2018, 10:11:10 AM3/25/18
to TiddlyWiki
(Similar post in devgroup and github but without the responses I hoped for so here is a more direct plead for help)

@javascript people

W3C has a small and simple dragndrop demo. It also works as well if you add more divs to it.

I hope to be able to use this inside tiddlers, ie so that divs (or similar) can switch places in tiddler view mode. 

The use is for TidBitz which I hope to give to the community soon. TidBitz is meant to simplify coding in general and lower the threshold for newcomers to create stuff in TW. A necessary feature for this is to be able to re-arrange things in a tiddlers text while in tiddler view mode. Specifically it is a matter of rearranging <<macrocalls>> to above or below one another.

But I also think something like in the W3C demo would overall greatly simplify use of DnD in TW. Currently DnD requires a separate list that keeps track of the order of things but I fail to see why this would be necessary - any words or other objects in a tiddlers text field has a natural order... that should be re-orderable, right?

So, anybody capable of tiddlifying that W3C code?

Thank you!

<:-)

Jed Carty

unread,
Mar 25, 2018, 3:03:48 PM3/25/18
to TiddlyWiki
I don't know what can be done with that example. It is essentially what tiddlywiki does now. The state has to be saved somewhere and tiddlywiki works with lists, so it uses lists for keeping track of drag and drop movements.

If you want to re-order the content of tiddlers by dragging and dropping them than that is possible to make happen, but the most tiddlywiki-like way to do that is to make a tiddler for each component you want to move around and then have the drag and drop part modify the order of that list, which as far as I understand it is what the drag and drop widget does.

To tiddlify that code you would say that each div is a tiddler and when you drag from one tiddler into another you move all of the content from one to the other, which I don't think is what you want because it is pretty much just renaming a tiddler. To use the natural ordering of things in a tiddler than you have to first define what those things are, otherwise how do you determine what gets picked up? You have to define that somehow and then as soon as you define it you need to have a listing of the 'things' to be picked up somewhere. Which is why you end up with a list.

You could create some special type of list that makes each item on the list a draggable div similar to how markdown makes interactive checkboxes, but my instinct is that it would do strange things with transclusions that may break a lot of stuff. I am having a hard time coming up with a way to use this that would simplify using it in tiddlywiki, the reason that it is so simple in the example code is that it is all done in the dom because there is no persistent state, which isn't possible in tiddlywiki (it would lead to problems like when you have an edit-text widget edit the same tiddler it is in).

Mat

unread,
Mar 25, 2018, 5:54:38 PM3/25/18
to TiddlyWiki
Jed, thanks for a reply! I have a load of return questions that I am hoping you or anyone would be willing to answer. I really hope to make TidBitz into something useful because I really think we need a lower threshold to start working with TW.


I don't know what can be done with [the W3C DnD] example. It is essentially what tiddlywiki does now. The state has to be saved somewhere and tiddlywiki works with lists, so it uses lists for keeping track of drag and drop movements.

I was about to write this: Why does the "state have o be saved somewhere"? If rearranging actually *moves* the div, as it does in the W3C example (...at least according to the inspector tool). In this sentence the word "this" comes before "sentence" - that fact doesn't have to be stored, it is just the nature of text. -?

...that is what I was about to write... but then I read what you wrote:

the reason that it is so simple in the example code is that it is all done in the dom because there is no persistent state, which isn't possible in tiddlywiki (it would lead to problems like when you have an edit-text widget edit the same tiddler it is in).

Ah. 
...but couldn't such a state be saved either manually by the user (save tiddler button) or as part of the action when dropping? I don't know how close your edit-text widget analogy is, but it IS possible to make changes in the current tiddler via the edit-text field, especially single instantaneous changes... such as when dropping something. 


If you want to re-order the content of tiddlers by dragging and dropping them than that is possible to make happen, but the most tiddlywiki-like way to do that is to make a tiddler for each component you want to move around and then have the drag and drop part modify the order of that list, which as far as I understand it is what the drag and drop widget does.

Wouldn't that also require that the content is output from some listwidget? In my case, not only does it not make sense to turn them into tiddlers because they're 
just macro calls - but they are also literal macro calls, not output from some listwidget.


To tiddlify that code you would say that each div is a tiddler and when you drag from one tiddler into another you move all of the content from one to the other, which I don't think is what you want because it is pretty much just renaming a tiddler. To use the natural ordering of things in a tiddler than you have to first define what those things are, otherwise how do you determine what gets picked up? [...]
 
Isn't "everything between <div...> and </div>" defined? I.e with some good attributes in the div. There could even be an id attribute in the div.
And I think the most important use case is not to drag things between tiddlers but within the same tiddlers text field (in view mode). Does this change anything?

[...] You have to define that somehow and then as soon as you define it you need to have a listing of the 'things' to be picked up somewhere. Which is why you end up with a list.

So, couldn't <div>this</div> sentence be a <div>list</div> with ten elements?

..where element #3 and #7 are such that they trigger actions when manipulated? I.e the list is the text in the textfield.

...

Again, thank you or anyone for explaining things.

<:-)

Jed Carty

unread,
Mar 26, 2018, 4:46:20 AM3/26/18
to TiddlyWiki
You are not wrong about what you want, and I am trying to come up with a way to make it happen because I like this idea, but here are the current problems and hopefully some clarification about why it doesn't work that way now.

First, about the state:

The problem is that the state you are describing when dragging and dropping is completely in the DOM, which in tiddlywiki can be refreshed and recreated at any time. So the state has to be saved when it is changed or it may all be lost by something else on the wiki changing. Jeremy and others have put a lot of effort into reducing the number of refreshes that happen so it doesn't happen constantly, but that just means you would lose your work inconsistently when the dom refreshes instead of constantly. This makes having the state saved manually by the user a bad solution because it may seemingly randomly lose work.

Most of the rest of the problem comes from how tiddlywiki has to know what you are trying to move, and what is a valid location for dropping it. If you can pick up individual words than how do you tell tiddlywiki you want to pick up the whole paragraph? And adding transclusions to that creates problems like, what happens if you drag a word from inside of a transclusion to the containing tiddler around it. I think that making something to let you rearrange words in plain text by dragging and dropping would be relatively straight forward. Extending that to being able to drag some sort of generic entity becomes much much more difficult, particularly when you can have nested div tags. If you click on a word inside a tag for the sentence, which is nested inside a tag for the paragraph which one is supposed to be picked up? That is the sort of UI problem that makes me stop using software.

And in your example, yes, we can do exactly that. The problem is that you then introduce something new to add to the text that I think is just as confusing as needing an external list. Because you need to mark both the things that are possible to drag and all of the potential places where you can drop something. You could say 'you can drag any paragraph' or 'you can drag any word' and use drag and drop to rearrange them, but then in order to make it work on the text you are going to have to lose some formatting and transclusions will break it because you are going from raw next -> wikitext -> html and then back from html->raw text. I am sure that is possible but I doubt it is easy to do in a way that preserves the specific markup in what you originally wrote.

Unless I am completely misunderstanding what you are asking for. If you want something like a button but you click and drag an item from one place and drop it in another and the resulting action is based on which starting and ending point is used than that is a different problem. BUT, and this is very important I think, it wouldn't let you rearrange text any differently than you can rearrange plain text using existing wikitext widgets.

TonyM

unread,
Mar 26, 2018, 8:23:51 AM3/26/18
to TiddlyWiki
Mat,

I applaud what you are trying to do. Perhaps there is another way to do this that would add even more value.

Here is a quick summary.

Provide a location at the bottom of every tiddler where you can drop a snipit. Such as the widgets you mention. Each time you drop such a snipit it is added as content in a field such as snipit-row-1 then snipit-row-2 etc... Perhaps you could replace line breaks with <br>

Now in a tiddler tagged view template transclude each of the fields beginning snipit-row in the order they apear. See MyMenus plugin as I do this for each menu-item

Now provide a way to alter the order of these fields even if they must be renamed.

Do you follow?

Tony

Mat

unread,
Mar 26, 2018, 4:14:12 PM3/26/18
to TiddlyWiki
Jed - very informative. Big thank you!

... DOM, which in tiddlywiki can be refreshed and recreated at any time. [...] This makes having the state saved manually by the user a bad solution because it may seemingly randomly lose work.

And to have the state saved by/in the very last action in the drop action? Because it at least very unlikely that DOM is refreshed during the DnD... right?

 
Most of the rest of the problem comes from how tiddlywiki has to know what you are trying to move, and what is a valid location for dropping it. If you can pick up individual words than how do you tell tiddlywiki you want to pick up the whole paragraph?

My point with bringing up "words" was merely to clarify that everything has an intrinsic position in a text, not to actually be able to drag individual words. Rather it is blocks, possibly delimited by <div> tags, which should be drag'n droppable in relation to other such <div> tags. My point in exemplifying such blocks with <div> tags, specifically, is that divs are manipulable in html. E.g we can CSS a div to light up when hovering over it. ...so isn't JS also able to target and manipulate individual <div>s?
 
...and it could use the exact same rules as when nesting html  - be it in transclusions, in nested divs or whatever. So that if you click anything (any word) in a div, then the whole div should be selected.  ...and if divs are nested, then clicking outside the inner div targets the outer div. Like with ad-blockers - you hover over html elements and have them light up. If you hover outside of the element, then instead the next level lights up which includes also the inner one. I think that is the only reasonable way to select elements that are nested.


[...] 'drag any paragraph' ... you are going to have to lose some formatting and transclusions will break it because you are going from raw next -> wikitext -> html and then back from html->raw text. I am sure that is possible but I doubt it is easy to do in a way that preserves the specific markup in what you originally wrote.

Do you mean like how dragging //away <div>this</div> would// loose the italics? That's a fair price to pay I would say. Moving out a block from inside a transcluded text to outside of it... I'm unsure how a transclusion actually functions but I guess that would either "work" or be a forbidden move (kinda like trying to move something out of an iframe).


Unless I am completely misunderstanding what you are asking for. If you want something like a button but you click and drag an item from one place and drop it in another and the resulting action is based on which starting and ending point is used than that is a different problem.

Specifically in TidBitz, the only application for the discussed DnD concept is to rearrange literal macro calls within a tiddlers text field. A luxury version would be to be able to move it between different tiddlers. (And it is assumed that the droplocation is onto another such drag'ndroppable area (i.e another macro call).


BUT, and this is very important I think, it wouldn't let you rearrange text any differently than you can rearrange plain text using existing wikitext widgets.

Not quite sure what you mean here. But I believe it would be possible to make some contrived solution where a listwidget takes a tiddlers text field and searches up a specific segment in the text and then re-builds the text with that segment moved. Is that what you mean a js widget would do also?


<:-)

Mat

unread,
Mar 26, 2018, 4:29:47 PM3/26/18
to TiddlyWiki
Tony, that is an interesting idea, basically adding an index to each snips, to make a kind of numbered list or array if you will. And then use some kind of listwidget to have them output'ed in sequence. However that would prevent the possibility of any interspersing things (e.g text) between the snips.

I want the user to be able to discover TW gradually. The edit mode is intended to be viewed as a kind of "behind the scenes area" where you go when you eventually want more fine grained control over your TidBit based tiddlers (that are constructed in view mode). For instance you might want to intersperse the 'snips' a.k.a 'TidBitz' a.k.a macrocalls with something... which is not possilbe if the macrocalls were merely output from a ListWidget.

Still, I much appreciate your idea and please keep 'em coming. They may trigger other ideas and solutions.

<:-)

TonyM

unread,
Mar 26, 2018, 5:41:11 PM3/26/18
to TiddlyWiki
Mat,

Maintain your vision and keep going. I see how you want control detail in the text field.

In my suggestion previously you can include text snipits between macro calls to have text throughout. In fact snipits can include;
Macro call functions
Custom text
Links and lists to other tiddlers
Transclusions of other tiddlers
References to the text and other fields in the current tiddler

With the approach you are taking it seems you will will have complex process ahead of you, perhaps the result will be worth it. However I cant help but feel there is a way to simplify.

Best of luck, I will share if I can help.

Tony

BurningTreeC

unread,
Mar 27, 2018, 5:39:03 AM3/27/18
to TiddlyWiki
Hi Mat ,

looking at your evolving TidBitz , I would do this:

modify the $:/core/ui/ViewTemplate like so:

<$set name="storyTiddler" value=<<currentTiddler>>><$set name="tiddlerInfoState" value=<<qualify "$:/state/popup/tiddler-info">>><$set name="curr" value=<<qualify "$:/tidbitz/scratch">> ><$tiddler tiddler=<<currentTiddler>>><$droppable actions="""<<TidBit-dropactions>>"""><div class=<<frame-classes>>><$list filter="[all[shadows+tiddlers]tag[$:/tags/ViewTemplate]!has[draft.of]]" variable="listItem"><$transclude tiddler=<<listItem>>/></$list></div></$droppable></$tiddler></$set></$set></$set>


Then I'd modify the TidBit-dropactions Macro:

Note: you need a tiddler (I call it $:/list/numbers) with a list of integers from 1 to a big number in its list field. You can get one from here: http://tiddlytouch.tiddlyspot.com/#%24%3A%2Fplugins%2FBTC%2Ftiddly-touch%2Flists%2Fnumbers


\define setScratchTiddlerField()
<$action-setfield $tiddler="""$(curr)$""" $field="tidbit-row-$(nextTidbitCount)$" $value="""your TidBit""/>
\end
\define TidBit-dropactions()
<$set name=TidBit filter="
[[$(actionTiddler)$]removeprefix[TidBit/]]">
<$wikify name="
id" text=<<TidBit-id>>>
<$wikify name="
TidBitid" text=<<TidBitid>>>
<$list filter="
[[$(actionTiddler)$/temp]fields[]prefix<TidBitid>!suffix[-id]]" variable="fld">
  <<TidBit-setfields>>
</$list>
</$wikify>
<$set name="
tidbitCount" filter="[[$(curr)$]fields[]prefix[tidbit-row]count[]]">
<$set name="
nextTidbitCount" filter="[<tidbitCount>next[$:/list/numbers]]">

<<setScratchTiddlerField>>

</$set>
</$set>
</$wikify>
</$set>
\end


You then modify the $:/core/ui/ViewTemplate/body
There you can access the <<curr>> :

\define renderTidbit()

$
(tidbitContent)$

\end
\define getScratchFieldsContent()
<$list filter="[[$(curr)$]get[tidbit-row-$(tidbitRow)$]]" variable="tidbitContent">
<<renderTidbit>>
</$list>
\end
<$set name="tidbitCount" filter="[<curr>fields[]prefix[tidbit-row]count[]]">
<$list filter="[list[$:/list/numbers]limit<tidbitCount>]" variable="tidbitRow">

<<getScratchFieldsContent>>

</
$list>
</$set>

I haven't tested this code but it's the basic idea

...

Then I'd make the tidbitContent within renderTidbit() draggable and place a droppable surrounding it
The droppable actions there have access to the $(curr)$ and to the unique field where the tidbit is stored: tidbit-row-$(tidbitRow)$

So, the draggable must be: <$draggable tiddler="tidbit-row-$(tidbitRow)$">
and the droppable actions then should do nothing else than exchanging the contents of the tidbit-row-fields


-----------------------------------------------------------------------

If this works, you probably need a solution for preventing the full-tiddler droppable not to trigger when re-ordering tidbits within a tiddler
There are solutions that can be done by applying css classes to the draggable widgets and preventing things by css in a stylesheet tiddler
That can be figured out in the end

BTC
Reply all
Reply to author
Forward
0 new messages