Reuse core fields - pass opts to nested riot tags with inconsistent mount/update events

I fiddled with nested riot tags and tried to pass options from one field to nested fields.

simplified example:

field options:

{
  "display_field" : "colors",
  "values": ["#111111","#cccccc","#ffffff","#00ff00"]
}

field-custom.tag:

<field-custom>

    <cp-field type="tags" if="{ opts.display_field == 'tags' }" opts="{ {autocomplete:values} }" bind="{ opts.bind }"></cp-field>
    
    <cp-field type="colortag" if="{ opts.display_field == 'colortag' }" opts="{ {colors:values} }" bind="{ opts.bind }"></cp-field>
    
    <div if="{ !opts.display_field }">
        <ul>
          <li each="{ option in opts.values }">
              { option }
          </li>
        </ul
    </div>

</field-custom>

Actually, I try to modify the RequestSelectOptions addon to reuse the core fields for custom visual select styles.

The problem is, that some fields have different mechanisms to load their options. Some load it on mount, some on update and others don’t mount or update and use the opts directly.

If all the fields would load consistent, it would be easier to reuse them when customizing the backend or writing custom field addons. Also a few core views and fields could benefit from it.

I wrote a fix for tags and colortag fields and I try to write some more, but sometimes it’s hard to understand the Uikit/riot.js/jQuery/Utils mixup… and I don’t want to break anything by accident.

A few things, I don’t understand:

var $this = this;
Some fields work without this line.

this.mixin(RiotBindMixin);
This line is in the views and in cp-assets.tag, but I don’t understand, what it is used for.
edit: Got it. It’s for @lang() instead of App.i18n.get() etc.

this.$initBind = function() { this.root.$value = this.selected; };
It doesn’t seem to have any effect.

@artur Can you give some hints, please?

Hi Raffael,

oh boy I don’t know where to start honestly.

Moving away from angular, Cockpit started using riot.js for the front-end components. I started with v1.x, so almost after riot.js came out. Now we’re on v3.x. And between the releases I needed to do some adjustments and sometimes hacks to make my custom data-binding implementation work.

I know I need to find time to clean up the components, but they are pretty stable right now and can wait for a clean-up sprint a little bit longer.

var $this = this; // this is just to prevent function(){ }.bind(this) in some places
this.mixin(RiotBindMixin); // initialize data binding for the component - https://github.com/agentejo/cockpit/blob/next/assets/lib/riot/riot.bind.js
this.$initBind = function() { this.root.$value = this.selected; }; // an artefact to support riot 2.x, but should be removed in the future

I hope I could help with my comments.

Greets,
Artur

1 Like

Thanks. That explains the very different coding styles in several components. I have to investigate it later… And I found a workaround to have nice looking select fields without passing options to nested fields.