2

Based on the selection of a radio button, I would like to toggle the read-only attribute of lightning-input element. setAttribute method on DOM element doesn't seem to work.

app.html

<template>
    <div class="slds-grid">
        <div class="slds-col">
            <lightning-radio-group name="opportunityCreation"
            label="Create an Opportunity"
            options={options}
            value={createOpp}
            onchange={createOppHandler}>
            </lightning-radio-group>
        </div>
        <div class="slds-col">
            <lightning-input label="Opportunity Name" data-id="oppName">

            </lightning-input>
        </div>
    </div>
</template>

app.js

import { LightningElement, track, api } from 'lwc';

export default class App extends LightningElement {

    @track options = [{'label': 'Yes', value:'yes'},{'label':'No', value:'no'}];
    @track createOpp = 'yes';
    createOppHandler(event){
        this.createOpp = event.detail.value;
        let inputTextElem = this.template.querySelector("[data-id='oppName']");
        if(this.createOpp === 'no'){
            inputTextElem.setAttribute("read-only", "");
        }
        else{
            inputTextElem.removeAttribute("read-only");
        }
    }
}

Playground link

4

The usual way to address this is to hold the "read-only-ness" as tracked state (a change to it causes refresh of the UI) and to then conditionally render the input with or without the required read-only flag.

app.html

<template>
    <div class="slds-grid">
        <div class="slds-col">
            <lightning-radio-group name="opportunityCreation"
            label="Create an Opportunity"
            options={options}
            value={createOpp}
            onchange={createOppHandler}>
            </lightning-radio-group>
        </div>
        <div class="slds-col">
            <template if:false={readOnly}>
                <lightning-input label="Opportunity Name" data-id="oppName">
                </lightning-input>
            </template>
            <template if:true={readOnly}>
                <lightning-input label="Opportunity Name" data-id="oppName" read-only>
                </lightning-input>
            </template>
        </div>
    </div>
</template>

app.js

import { LightningElement, track, api } from 'lwc';

export default class App extends LightningElement {

    @track options = [{'label': 'Yes', value:'yes'},{'label':'No', value:'no'}];
    @track createOpp = 'yes';
    @track readOnly = false;

    createOppHandler(event) {
        this.createOpp = event.detail.value;
        this.readOnly = this.createOpp == "no";
    }
}

Also updated in your playground.

UPDATE:

I suspect the markup:

            <template if:false={readOnly}>
                <lightning-input label="Opportunity Name" data-id="oppName">
                </lightning-input>
            </template>
            <template if:true={readOnly}>
                <lightning-input label="Opportunity Name" data-id="oppName" read-only>
                </lightning-input>
            </template>

Can be replaced by:

            <lightning-input label="Opportunity Name" data-id="oppName" read-only={readOnly}>
            </lightning-input>

Though I haven't tested it. The technique I showed is, however, good for other cases where you want to pass different parameters rather than just different parameter values.

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.