Is it possible to prevent overwriting of fields when action-setfield widget is used?

I use some buttons to add fields to some selected tiddlers by using action-setfield widget. But if the field is already present in that tiddler, it is getting overwritten by my custom button actions. Is there a way to avoid overwriting of fields if they are already present?

You could use the setmultiplefields widget, and select the fields only if they do not exist:

Click <$button>
<$list filter={{!!list}} variable="tiddler">
<$action-setmultiplefields
$tiddler=<<tiddler>>
$fields="[<tiddler>has{!!field}else{!!field}]"
$values="[{!!value}]" />
</$list>
this button
</$button> to set the field <$edit-text field="field" tag="input"/> to <$edit-text field="value" tag="input"/> if the field {{!!field}} is empty or missing on the tiddlers <$edit field="list" class="tc-edit-texteditor"/>

<ul>
<$list filter={{!!list}} variable="tiddler">
<li><$link to=<<tiddler>>/>: <$view tiddler=<<tiddler>> field={{!!field}}/></li>
</$list>
</ul>

Demo

1 Like

@Theophile … It’s problematic to have action-widgets inside button-widgets. All the parameters are evaluated when the button is created.

There can be problems like this:

  • If you open a tiddler that contains the button it will save the wiki state.
  • If you manually add the field to the target tiddler the action inside the button-widget does not get the new info.
  • So if the button is clicked the field will be overwritten.

With buttons always use:

\procedure test-actions()
<!-- do something -->
\end

<$button actions=<<test-actions>> >
Click
</$button>

The button-widget has a “disabled” parameter which can be used to deactivate the button. This makes the test-action much simpler, because there have to be no “field exists” tests anymore. eg:

\procedure test-actions()
<!-- do something -->
\end

<$button actions=<<test-actions>>
    disabled={{{ [[TargetTiddler]has[yourFieldName]then[yes]else[no]] }}}
>
    Click
</$button>

Since “TargetTiddler” is part of the button-widget now. If the TargetTiddler is updated the button will be refreshed.

5 Likes

I am adding 4 to 5 fields to a tiddler using this button. So I want this button to be disabled only if all those fields are already present in the tiddler. Is it possible to do that ?

For example, here is a tiddler with three fields with fieldvalue as shown below

A:a
B:b
C:c

The button is supposed to add 4 fields with fieldvalues as below - A:a B:b C: D:d

Field C is kept empty since I will be manually entering it. Suppose I had previously added C:c field manually to this tiddler.

Now since D field is missing, I will press the button and this will add D field, but should not overwrite the C field and make the fieldvalue empty by deleting the already entered fieldvalue `c

Is it possible ?

Edit: https://all-demo-wiki.tiddlyhost.com/#O-RADS-2_tweet_danatsouza

Here is an example tiddler. On opening this wiki, press Alt+A. Now you can see the fields on the right side. Press the button image
and see the field topic is getting overwritten

@Theophile
I will take a look at this code. I have to adapt this to my needs.I will respond after my testing. Thanks for taking time to help me.

1 Like

Actions inside a button or the seperate actions macro as per marios advice can themselves be wrapped in a list widget so they are only used when the filter condition is true.

<$list filter="[all[current]!has[fieldname]]" variable=~>
Actions here only when field name has no value
</$list>

Why not just filter at the selection-point? That is, get tiddlers “in your sights” for this set-field action based on a filter condition that includes [!has[field-to-set]]?

(Sorry @TW_Tones, I see my response duplicates yours!)

That produces invalid HTML.

I think it should be possible to rework that code and have it produce valid HTML, but TiddlyWiki is not complying – all of these produce junk…

<$button {{{ [[TargetTiddler]has[yourFieldName]then[disabled]else[]] }}} ...

<$button {{{ [[TargetTiddler]has[yourFieldName]then[disabled]else[not-disabled]] }}} ...

<!-- with $eventcatcher -->
<button {{{ [[TargetTiddler]has[yourFieldName]then[disabled]else[]] }}} ...

At the very least, the raw HTML button should work, IMO. If filtered transclusion works inline in free text, IMO it should work without being an assignment in a tag’s attribute space.

Anyway, the above is academic… @TW_Tones’ reply contains the cleanest, best solution to the OP.