Like any other component in aura, the body
attribute accepts array of Aura.Component instances(Aura.Component[]
).
In our case aura:html expects body
to be of type Aura.Component[]
.I think it is ignored because of the type mismatch.
You can set the aura:html's body attribute in the markup implictly by doing this:
<aura:html tag="div">Hello World</aura:html>
Anything within the start tag and end tag be it a custom component, aura/ui/lightning namespaced component is considered as the body
of that particular component.
Hope it is not too late, I did some digging on my own and did not find enough evidence to set dynamic javascript methods using the set() method. Even returning concrete references did not help in this case. So here is my theory
When we use
iconID.set('v.onclick',component.getReference('c.showDefaultValue'));
We get the following error
As it states "Value provider does not implement set(key,value)", It looks like the set property is not available for the onclick attributes. Maybe it is working as designed. Salesforce does not want us to implement it this way.
Solution :
In our scenario, as you suggested earlier you could use an if-else condition to perform your logic. But it looks messy, you would have to go through 2 methods (openDropdown & showDefaultValue ) every time some-one clicks, and this would add complexity to the logic. Hence I propose the following one.
Use Dynamic Components instead of setting the values. It works kinda similar to the set() approach that you used.
Component :
<div aura:id="container" class="container">
<lightning:buttonIcon aura:id="downIcon"
iconName="utility:down"
variant="bare"
alternativeText="Settings"
iconClass="dark"
class="slds-button slds-input__icon slds-text-color--default"
onclick="{!c.openDropdown}"/>
</div>
Controller :
({
openDropdown : function(component, event, helper) {
console.log("**** Inside openDropdown method ****");
$A.createComponent(
"lightning:buttonIcon",
{
"aura:id": "closeIcon",
"iconName": "utility:close",
"variant": "bare",
"alternativeText": "Close me",
"iconClass" : "dark",
"class" : "slds-button slds-input__icon slds-text-color--default",
"onclick": component.getReference("c.showDefaultValue")
},
function(newButton){
var divComponent = component.find("container");
divComponent.set("v.body",newButton);
}
);
},
showDefaultValue : function(component,event,helper){
console.log("**** Inside showDefaultValue method ****");
}
})
Results :
Lightning button before clicking
Lightning button after clicking, it enters the opendropdown method
Finally, when clicking on the close button, it enters showDefaultValue methd without entering the opendropdown method. This approach kind of works in the same as your component.set() logic but in addition, it creates a dynamic component and sets the v.body attribute of the outer container to the newly created component.
Best Answer
you need to use
aura:html
to create a html tag dynamically using$A.createComponent
.So to create a button tag below is how you do it: