2

Scenario: I have a LWC with a lightning-button which calls an action in the JS controller. Within the JS controller, I am trying to target the button element and update it's innerHTML and/or update it to disabled=true.


Per the Salesforce LWC Documentation "Access Elements the Component Owns":

To access elements rendered by a component, use the template property.

this.template.querySelector();

this.template.querySelectorAll();

and per How to migrate aura:id to Lightning Web Components data-id acts as the LWC equivilent of aura:id from Aura components.


So, following that guidance, I added a data-id to a lightning-button in my markup:

<template if:true={showSendSignature}>
    <lightning-button name="Send for Signature" data-id="adobeSignBtn" variant="success" label="Send for Signature" onclick={adobeSendForSignature} ></lightning-button>  
</template>

In my JavaScript, I then do:

const adobeButton = this.template.querySelector('[data-id="adobeSignBtn"]');
console.log(adobeButton);

When I inspect the page, I notice that the data-id is actually on a parent element to the button itself, rather than on the button element:

<lightning-button c-alphacreateorderform_alphacreateorderform="" data-id="adobeSignBtn"
    <button name="Send for Signature" type="button" class="slds-button slds-button_success slds-button_first">Send for Signature</button>
</lightning-button>

In console, adobeButton returns SecureElement: [object HTMLElement]

When I do console.log(adobeButton.childNodes), I get back SecureNodeList: [object NodeList]

However, when I do adobeButton.childNodes[0], I get undefined


Question: How do I correctly access this button in a LWC JS controller?

3
  • 3
    Why not just use event.target?
    – Adrian Larson
    Jul 16 at 17:46
  • event.target.value returns undefined, and event.target.setAttribute("disabled", true); does nothing. What am I missing? Jul 16 at 17:52
  • event.target.nodeName returns LIGHTNING-BUTTON, event.target.querySelector('button') returns null, event.target.childNodes.length and event.target.children.length return 0 Jul 16 at 17:59
2

Both querySelector and Event.target will refer to the element so you can do the following with them.

Access the disabled attribute directly:

const adobeButton = this.template.querySelector('[data-id="adobeSignBtn"]');
adobeButton.disabled = true;
handleButtonClick(event){
    event.target.disabled = true;
}

You're not just limited to the attributes, you can do more on the element like styles

const adobeButton = this.template.querySelector('[data-id="adobeSignBtn"]');
adobeButton.style.visibility = 'hidden';
handleButtonClick(event){
    event.target.style.visibility = 'hidden';
}

You can also interact with the class of the element

const adobeButton = this.template.querySelector('[data-id="adobeSignBtn"]');
adobeButton.className += " slds-hide";
handleButtonClick(event){
    event.target.className += " slds-hide";
}

You can see this all of these in the following playground.

2
  • Choosing this answer because it more correctly answers the core question "how to get Button element in JS Controller from LWC" Jul 16 at 21:53
  • For completeness: is it possible to access any element property, such as style/class/name/id/etc directly in this way? Jul 16 at 21:54
1

I personally like to keep by button declarations in a property to avoid these kinds of "scenarios" and If I need to modify anything, I just need to do so in the JS file without having to modify the HTML template and can easily access its props and modify them.

Example:

export default class MyLwcWithJSButtonProps extends LightningElement {

    actionBtns = [{ label: 'a label', value: 'a value', disabled: false, class: 'if applicable', variant: 'if applicable', action: (e) => { this.handlerSomething(e) }}}]
    
    handlerSomething(e){
        
        const btn = e.detail.name;
        this.actionBtns - this.actionBtns.map( btn => { return {...btn, disabled:(some condition) ? true : false}})

    }
}

template

<template>
    <template for:each={actionButtons} for:item="btn">
            <lightning-button key={btn.value} variant={btn.variant} label={btn.label} title={btn.label} onclick={btn.action}
              class={btn.class} disabled={btn.disabled}></lightning-button>
          </template>
</template>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.