function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Gilda Rey 8Gilda Rey 8 

How can I remove or add attributes in LWC?

I'm trying to remove an attribute from an input field, specifically 'readonly' when I click on a button. I have tried this way and it is not working for me.
HTML
<lightning-input type="text" class="generalInfo" id="title" value="Title" readonly></lightning-input> <lightning-input type="text" class="generalInfo" value="Sub Title" readonly></lightning-input> <lightning-input type="text" class="generalInfo" value="Publication Date" readonly></lightning-input> <lightning-button-icon icon-name="utility:edit" alternative-text="Edit" title="Edit" onclick={editGeneralInfo}>
editGeneralInfo() in JS
this.template.querySelectorAll(".generalInfo").forEach(element => { if(element.hasAttribute('readonly')){ console.log('YES'); element.removeAttribute('readonly'); } });
Thank you!
Best Answer chosen by Gilda Rey 8
ANUTEJANUTEJ (Salesforce Developers) 
Hi Gilda,

I tired finding any such use cases that have been implemented previously but unfortunately I was not able to find any, however on checking I see that there are many such use cases implemented using lightning components.

On checking the documentation I found that the readonly attribute in lightning component is a boolean value however in LWC it is a attribute i.e., in LC:
<lightning:input name="input4" readonly="true" value="initial value" label="Read-only text field with a predefined value" />

Changes to 
 
<lightning-input type="date" name="input6" label="Read-only date field" readonly value="2020-09-07" ></lightning-input>

The only possible way was mentioned in this Stackexchange thread: https://salesforce.stackexchange.com/questions/272967/dynamically-adding-read-only-attribute-to-lightning-input-element-in-lwc-framewo

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.

I tried the above part after the UPDATE but unfortunately, it didn't work.

Let me know if it helps you and close your query by marking it as solved so that it can help others in the future.  

Thanks.

All Answers

VinayVinay (Salesforce Developers) 
Hi Gilda,

Check below example of dynamically adding read-only attribute to lightning-input

https://salesforce.stackexchange.com/questions/272967/dynamically-adding-read-only-attribute-to-lightning-input-element-in-lwc-framewo

Thanks,
ANUTEJANUTEJ (Salesforce Developers) 
Hi Gilda,

I tired finding any such use cases that have been implemented previously but unfortunately I was not able to find any, however on checking I see that there are many such use cases implemented using lightning components.

On checking the documentation I found that the readonly attribute in lightning component is a boolean value however in LWC it is a attribute i.e., in LC:
<lightning:input name="input4" readonly="true" value="initial value" label="Read-only text field with a predefined value" />

Changes to 
 
<lightning-input type="date" name="input6" label="Read-only date field" readonly value="2020-09-07" ></lightning-input>

The only possible way was mentioned in this Stackexchange thread: https://salesforce.stackexchange.com/questions/272967/dynamically-adding-read-only-attribute-to-lightning-input-element-in-lwc-framewo

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.

I tried the above part after the UPDATE but unfortunately, it didn't work.

Let me know if it helps you and close your query by marking it as solved so that it can help others in the future.  

Thanks.
This was selected as the best answer
Gilda Rey 8Gilda Rey 8
Thanks to both! Both answers work correctly. Thank you!
ANUTEJANUTEJ (Salesforce Developers) 
Glad to know the answer worked as per the use case.