2

How can I conditionally add an attribute with Riot.js?

Suppose I have the following:

<progress max="10" value="{progressValue}"></progress>

This sets the value attribute to whatever progressValue is. However, there may be cases where I don't want to add this attribute at all. Specifically in this example, if I want the progress element to have an indeterminate state, I need to remove the value attribute entirely.

I know that for some attributes (such as disabled), there is special handling. Is it configurable somehow?

Brad
  • 159,648
  • 54
  • 349
  • 530

3 Answers3

2

The other answers give non ideal solutions.

Generally all attributes can be removed by passing a falsy expression in the same way as boolean atributes, e.g. <div class={ null }></div> will be rendered as <div></div>.

But values attributes are special ones: on form elements it is not recomended to set them using setAttribute (more info), so they are handled using an ad hoc binding expression different from the one of generic attributes.
This binding expression seems to have a different behaviour with falsy values so the previous example does not work. It is probably a bug, I'll update the answer when this behaviour will be cleared.

Update:
The problem has been fixed in Riot.js 4.3.7

raxell
  • 677
  • 6
  • 19
0

I know that for some attributes (such as disabled), there is special handling. Is it configurable somehow?

no, attributes like disabled or checked are evaluated by browsers as true when just the attribute is present, they do not require a value, that's why there is special handling for them.

to set it dynamically you could probably NOT use an expression but the this.$() DOM helper to set the attribute, e.g. somewhere suitable do:

if ( <var-to-add-attr> ) {
    this.$('progress').setAttribute('value', progress);
}

if ( <var-to-remove-attr> ) {
    this.$('progress').removeAttribute('value')
}

although untested something in that direction could work.

exside
  • 3,736
  • 1
  • 12
  • 19
0

On riot.js I prefer to use if or show attributes:

Create your tag component using show or if:

<progress>
    <div show={ opts.loading }>
        your HTML here
    </div>
</progress>

Using if:

<progress>
    <div if={ opts.loading }>
        your HTML here
    </div>
</progress>

You can call your component like this:

<progress loading={ this.loading }></progress>

<script>
    this.loading = true // add your code logic here
    this.update()
</script>

Don't worry about remove the loading attribute, when you do this.update() the riot.js will do that for you if the value is false.

EDIT

If you are using Riot.js >= 4.0 use props instead opts