Dynamically add custom attribute to element

I’m trying to conditionally add a custom attribute to an element and couldn’t find a way to do it.

An example: Suppose we have a list of items (blog posts or whatever), and we want to use route-href to link to the edit state for each item, but only if the item is not read-only.

If the item is editable, we want to have:

<a route-href="route: edit; params.bind: {itemId: item.id}">Some complex markup for that item</a>

But if it’s read-only, we want to have

<a>Some complex markup for that item</a>

Duplicating the element, once with route-href and once without, and using if.bind is not an option since that creates combinatorial explosion when there’s more than one conditional attribute.

In AngularJS this problem could be solved trivially with ng-attr-*:

<a ng-attr-route-href="{{editable ? 'route: edit; params.bind: {itemId: item.id}' : undefined}}">Some complex markup for that item</a>

But as discussed in this templating feature request, Aurelia still has no builtin way to do this.

OK, fine, I’m willing do create a custom attribute or binding behavior to add the route-href manually if the condition is met. The problem: I can’t find a way to attach a custom attribute to an existing element from inside another custom attribute.

There are plenty of other use-cases for this, eg., only adding a tooltip if a certain condition is met. Has anyone ever done this before or knows how to do it?

1 Like

Just off the top of my head, if you inject the element into your custom attribute, you can add the attribute to it by calling element.setAttribute().

That works only for normal HTML attributes. Aurelia won’t pick up on your changes and won’t create the corresponding components if you add a custom attribute via element.setAttribute().

Add a custom attribute and use templatingEngine to enhance the element

Or create your own route-href which will take an additional parameter

That’s what I did as a workaround, but it’s not a solution for the general case.

That’s what I’d like to do, but I couldn’t find any example of how to do it properly. Do you have any references to where that has been done?

The following is adding a new element but you can find the one you need, alter html and enhance it

let html = document.createElement("alert-modal");
let view = this.templatingEngine.enhance(html);
view.bind({});
view.attached();
document.querySelector("[aurelia-app]").appendChild(html);

I was afraid that this would mess with other custom attributes on this element and/or its child elements. But I’ll give it a try, thanks.

I still think a custom route-href is a better solution