How to apply styles styles based on the value of a field - 3 methods.

236 views
Skip to first unread message

Riz

unread,
Oct 15, 2016, 1:04:37 PM10/15/16
to TiddlyWiki
Warning: Potential "We knew this already, newbie" post. Tread carefully, tiwians.

Some time back PMario showed a classy way to apply styles based on title of tiddler here. Mat took a bit further and attempted to apply styles based value of a particular field. The code he furnished in the thread, according to him, did not work . Whether or not he achieved it later is not clear. So here is a few ways to achieve the same based on PMario's work and Mat's near miss, each with its own advantages.

Method 1

  • Back up
  • Open $:/core/ui/ViewTemplate
  • Add the highlighted code to the default.
\define frame-classes()
tc-tiddler-frame tc-tiddler-view-frame $(missingTiddlerClass)$ $(shadowTiddlerClass)$ $(systemTiddlerClass)$ $(tiddlerTagClasses)$
\end
\define folded-state()
$:/state/folded/$(currentTiddler)$
\end
<$set name="storyTiddler" value=<<currentTiddler>>><$set name="tiddlerInfoState" value=<<qualify "$:/state/popup/tiddler-info">>>
<$tiddler tiddler=<<currentTiddler>>>
<$set name="customstylevar" value={{!!customstylefield}}>
 
<div data-style=<<customstylevar>> class=<<frame-classes>>><$list filter="[all[shadows+tiddlers]tag[$:/tags/ViewTemplate]!has[draft.of]]" variable="listItem"><$transclude tiddler=<<listItem>>/></$list>
</div></$set></$tiddler></$set></$set>
  • Create a tiddler. Make a field named ‘customstylefield’ and give it the value ‘Give me some blue’ (without the single quotes)
  • Create a stylesheet tiddler. Add the following to it
[data-style="Give me some blue"] { 
background: blue; 
}
  • There you have it. To test further, create a second tiddler with the field ‘customstylefield’ and give it the value ‘redbg!?§$%&/()=@€~#yo’. Now to the stylesheet tiddler, define styles as [data-style="redbg!?§$%&/()=@€~#yo"] { background: red; fontweight:bold;}

Advantage: Well, tags can be hard to declare in the stylesheet if they have spaces or special characters. Plus, tags form a part of interface. So if you are developing an app or ebook based on TW5 platform, having a special tag just to apply styles is less than gracious. Fields by the virtue of being hidden from user's view, is an ideal place to dump the variables that drive the process. 

Method2

Here we are taking it further. In a field, we are declaring multiple classes(Not attributes) that will affect that particular tiddler. 
  • Back up
  • Open $:/core/ui/ViewTemplate
  • Add the highlighted code to the default.
\define frame-classes()
tc-tiddler-frame tc-tiddler-view-frame $(missingTiddlerClass)$ $(shadowTiddlerClass)$ $(systemTiddlerClass)$ $(tiddlerTagClasses)$ $(classfield)$
\end
\define folded-state()
$:/state/folded/$(currentTiddler)$
\end
<$set name="storyTiddler" value=<<currentTiddler>>><$set name="tiddlerInfoState" value=<<qualify "$:/state/popup/tiddler-info">>><$tiddler tiddler=<<currentTiddler>>>
<$set name="classfield" value={{!!customstylefield2}}>
<div class=<<frame-classes>>><$list filter="[all[shadows+tiddlers]tag[$:/tags/ViewTemplate]!has[draft.of]]" variable="listItem"><$transclude tiddler=<<listItem>>/></$list>
</div></$set>
</$tiddler></$set></$set>

  • Create a tiddler. Make a field named ‘customstylefield2’ and give it the following value: apple mango orange. Add some text to the text field. 
  • Create a stylesheet tiddler. Add the following to it 
.apple {
background-color:Blue;
}
.mango{
color:red;
}
.orange{
font-weight:bold;
text-align:center;
text-transform:uppercase;
}
.orange .tc-title {
display:none;
}
.mango .tc-subtitle {
display:none;
}
  • There you have it. 
REMEMBER: In case two of your classes have contradictory values, the one declared further down in the stylesheet will take effect. ie, in the above example if .orange had an attribute 'background-color:white;' it will override the background declaration in apple by virtue of being further down. This property can be used to apply styles based on presence on tags that get added only temporarily, without having to remove permanent tags. 

Method 3

Now we are declaring the styles that affect the tiddler directly in the field, removing the stylesheet as the intermediary. 
While this cannot be used to hide elements like title and tags, it can be useful in areas where you want to override a single property from the classes you declared using method 1 or 2.  


  • Back up
  • Open $:/core/ui/ViewTemplate
  • Add the highlighted code to the default.
\define frame-classes()
tc-tiddler-frame tc-tiddler-view-frame $(missingTiddlerClass)$ $(shadowTiddlerClass)$ $(systemTiddlerClass)$ $(tiddlerTagClasses)$
\end
\define folded-state()
$:/state/folded/$(currentTiddler)$
\end
<$set name="storyTiddler" value=<<currentTiddler>>><$set name="tiddlerInfoState" value=<<qualify "$:/state/popup/tiddler-info">>><$tiddler tiddler=<<currentTiddler>>>
<$set name="custominlinestylevar" value={{!!custominlinestylefield3}}>
<div class=<<frame-classes>> style=<<custominlinestylevar>>><$list filter="[all[shadows+tiddlers]tag[$:/tags/ViewTemplate]!has[draft.of]]" variable="listItem"><$transclude tiddler=<<listItem>>/></$list>
</div></$set>
</$tiddler></$set></$set>
 
  • Create a tiddler. Make a field named ‘custominlinestylefield3’ and give it the following value:
background:blue;color:red;
  • Save the tiddler and see the effect.

Now some use cases.

Expanding on the methods and tweaking the filters, we can use them to apply styles based on the first or last word in the text field.

Applying styles based on first word using method 2. (Same can be achieved with method 1)

  • Instead of <$set name="classfield" value={{!!customstylefield2}}> in step 3 code snippet, add <$set name="classfield" filter="[list[!!text]first[]]">
  • Create a tiddler with the text "Mary had a little lamb"
  • In the stylesheet declare a style for Mary. For eg;
 .Mary {
 bacground:yellow;
 color:red;
 }
  • There you have it. 
If you want to apply styles based on the first 5 words or so, set the filter to "[list[!!text]first[5]]" and declare the style as .firstword.secondword.thirdword.fourthword.fifthword {mystyle}
 
REMEMBER: Approach is case sensitive. 




Finally, for funsies.

  • Add the following to  your stylesheet
.animated{-webkit-animation-duration: 1s;animation-duration: 1s;-webkit-animation-fill-mode: both;animation-fill-mode: both}@-webkit-keyframes tada{from{-webkit-transform: scale3d(1, 1, 1);transform: scale3d(1, 1, 1)}10%, 20%{-webkit-transform: scale3d(.9, .9, .9) rotate3d(0, 0, 1, -3deg);transform: scale3d(.9, .9, .9) rotate3d(0, 0, 1, -3deg)}30%, 50%, 70%, 90%{-webkit-transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg);transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg)}40%, 60%, 80%{-webkit-transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg);transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg)}to{-webkit-transform: scale3d(1, 1, 1);transform: scale3d(1, 1, 1)}}@keyframes tada{from{-webkit-transform: scale3d(1, 1, 1);transform: scale3d(1, 1, 1)}10%, 20%{-webkit-transform: scale3d(.9, .9, .9) rotate3d(0, 0, 1, -3deg);transform: scale3d(.9, .9, .9) rotate3d(0, 0, 1, -3deg)}30%, 50%, 70%, 90%{-webkit-transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg);transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg)}40%, 60%, 80%{-webkit-transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg);transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg)}to{-webkit-transform: scale3d(1, 1, 1);transform: scale3d(1, 1, 1)}}.tada{-webkit-animation-name: tada;animation-name: tada}

  • Open $:/core/ui/ViewTemplate
  • Add the highlighted code to the default.
\define frame-classes()
tc-tiddler-frame tc-tiddler-view-frame $(missingTiddlerClass)$ $(shadowTiddlerClass)$ $(systemTiddlerClass)$ $(tiddlerTagClasses)$ $(classfield)$ animated tada
\end
  • Close it. The effect happens everytime a new tiddler is added to storyline.

The effect is taken from animate.css (https://daneden.github.io/animate.css/). Same method will work for other popular css animation libraries like hover.css and CSShake





Take care and be semantic.

 PS: That funsies part is not so funsies after the headache and nausea sets in. Go for a milder animation like fadeIn or something.

 

PMario

unread,
Oct 15, 2016, 2:39:31 PM10/15/16
to TiddlyWiki
Hi Riz,

Nice writeup!

I like the animation. ... But you should add, that it may make you "sea-sick" :)

On Saturday, October 15, 2016 at 7:04:37 PM UTC+2, Riz wrote:
....
 
Method 3

<div class=<<frame-classes>> style=<<custominlinestylevar>>><$list filter="[all[shadows+tiddlers]tag[$:/tags/ViewTemplate]!has[draft.of]]" variable="listItem"><$transclude tiddler=<<listItem>>/></$list>
</div></$set>
</$tiddler></$set></$set>

IMO this method should be the "last resort" if 1 and 2 are not possible!

It's hardcoding a style for the div, which is basically unchangeable. So it has the potential to break themes / CSS rules and the problem will be very hard to find.

-m

Riz

unread,
Oct 15, 2016, 9:15:59 PM10/15/16
to TiddlyWiki


 I like the animation. ... But you should add, that it may make you "sea-sick" :)

I know. Should have opted for a milder animation.


 IMO this method should be the "last resort" if 1 and 2 are not possible!

You are right. I merely intended to show it for completion sake. :-)

PMario

unread,
Oct 16, 2016, 4:32:49 AM10/16/16
to tiddl...@googlegroups.com


On Sunday, October 16, 2016 at 3:15:59 AM UTC+2, Riz wrote:


 I like the animation. ... But you should add, that it may make you "sea-sick" :)

I know. Should have opted for a milder animation.

No, It's cool! Especially the first time.
 

 IMO this method should be the "last resort" if 1 and 2 are not possible!

You are right. I merely intended to show it for completion sake. :-)

That's fine, just: "Use it with care!"
-m


 
Reply all
Reply to author
Forward
Message has been deleted
0 new messages