2

I am quite new to SF development and as a frontend developer I am experiencing some striggles while taking over a project from a colleague who has just left his job. So please appologize any "stupid" beginner questions...

We are currently developing an APEX class and I need to access the parent container of a LWC component.

Let my element be like this:

<template for:each={objInfo.todoList} for:item='todoListItem' class="slds-p-top_medium">
    <lightning-input 
        key={todoListItem.fieldName} 
        name={todoListItem.fieldName} 
        label={todoListItem.fieldLabel} 
        type={todoListItem.fieldType} 
        value={todoListItem.value} 
        disabled={todoListItem.disabledRes}
        checked={todoListItem.value} >
     </lightning-input>
 </template>

Rendered output then is:

<lightning-input c-todolist_todolist="" class="slds-form-element" lightning-input_input-host="">
    <span lightning-input_input="" data-aria="" class="slds-assistive-text"></span>
    <div lightning-input_input="" class="slds-form-element__control slds-grow">
        <span lightning-input_input="" class="slds-checkbox">
            <input lightning-input_input="" type="checkbox" id="checkbox-10" name="Window Cleaning" value="">
            <label lightning-input_input="" for="checkbox-10" class="slds-checkbox__label">
                <span lightning-input_input="" class="slds-checkbox_faux"></span>
                <span lightning-input_input="" class="slds-form-element__label">Window Cleaning</span>
             </label>
         </span>
     </div>
 </lightning-input>

Now I need to access the containing lightning-input element (which has the class ".slds-form-element") of each checkbox that is currently checked.

I was trying to reach this as follows:

for (let i = 0; i < this.objInfo.todoList.length; i++) {
        if(this.objInfo.todoList[i].value==true) {
            this.objInfo.todoList[i].closest('.slds-form-element').style.backgroundColor = 'green';                
        }
    }

But the response is Uncaught (in promise) TypeError: this.objInfo.todoList[e].closest is not a function

What am I doing wrong here?

console.log("Checked: " + this.objInfo.todoList[i].fieldName);

did work, but

this.objInfo.todoList[i].closest('.slds-form-element').style.backgroundColor = 'green';

does not.

1
  • I found out you can do it with just a line of css - check out my answer Aug 16, 2022 at 22:49

2 Answers 2

1

EDIT

You can use a regular input, as it turns out:

<template for:each={objInfo.todoList} for:item='todoListItem' >
  <lightning-input 
      key={todoListItem.fieldName} 
      name={todoListItem.fieldName} 
      label={todoListItem.fieldLabel} 
      type={todoListItem.fieldType} 
      value={todoListItem.value} 
      disabled={todoListItem.disabledRes}
      checked={todoListItem.value} >
  </lightning-input>
</template>

Then in your css file (name syntax if it does not exist is: componentName.css):

:host {
--slds-c-checkbox-color-background-checked : green;
}

That's it!

1

1.- IIRC, you cannot change the bg color of lightning-input fields that way due to the nature of shadow dom in LWC (you can set bg colors of elements wrapping it, and/or check if the component has any available styling hooks.

2.-You cannot access elements in your DOM with that approach, you need to reference the template.

A better approach would be to have a class property in your JSON that has your "bg color" classes and for greater flexibility on styling, instead of using <lightning-input> components, use HTML which you can copy form the blueprints.

So, everytime a mutation occurs on your this.object array, when the component is re-rendered, it will do so with the appropriate class and will display an updated bg color.

3
  • Thank you for your time and the details! I already have a workaround and include an external CSS (from Static Resources), so it would work to change a class name instead of a background color (which was more of a leftover from testing purpose I guess). The problem is more that I cannot use the .closest for any reason.. Let's say I prepare two classes for checked and unchecked status in my StaticResource CSS and add the class name for unchecked to the <template> tag (right?) it still leaves me with the problem of not getting to this element, does it?
    – JonSnow
    Jan 21, 2022 at 14:29
  • from what i see, you are using Element.closest() to get an element from your template, when you need to use template.querySelector(). this is not an optimal approach, best use conditional rendering with an if:true template directive when iterating over your objects to render stuff and have a bool proeprty indicating if it should render the dom with a certain class for displaying your green or whatever background color.
    – glls
    Jan 21, 2022 at 15:41
  • Sorry, this is the first time I am using LWC and components at all. Usually it's the job of our software developer, but as he has left the company it's now up to me... can you provide kind of a sample where I am wrong and what I have to do to do it right? Is it somwhat like <template for:each={objInfo.todoList} for:item='todoListItem' class="slds-p-top_medium if:true={green}> ?
    – JonSnow
    Jan 24, 2022 at 12:40

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .