0

Previously, I have table header values contained inside div element in HTML.

Example:

<div title="quarter1Month1">February2020</div>
<div title="quarter1Month2">March2020</div>
<div title="quarter1Month3">April2020</div>
//and so on...

But I would like those contents dynamic based on the title attribute value per div element, so I used switch statement in javascript to manage such requirement and called this function through onload event. But upon deploying, it does not work. As per checking, value, label, or even name attributes are not valid in div element.

Meanwhile, here's what I've come up so far:

periodLWC.html

<template> 
    <div class="filters">
        
        <lightning-combobox
            class="slds-m-bottom_small slds-m-left_small"
            name="fiscalYear"
            label="Fiscal Year"
            value={yearValue}
            placeholder="--None--"
            options={yearOptions}
            onchange={findOrgFYData}>
        </lightning-combobox>  
        
    </div>
          
    
    <table class="slds-table slds-table_cell-buffer slds-table_bordered slds-table_col-bordered slds-table_row-bordered"> 
        <thead>
            
            <tr class="slds-line-height_reset"> 
                
                <th scope="col">
                    <center><div class="slds-truncate" title="quarter1Month1" onload={findOrgFYData}></div></center>
                </th>  
                <th scope="col">
                    <center><div class="slds-truncate" title="quarter1Month2" onload={findOrgFYData}></div></center>
                </th>    
                <th scope="col">
                    <center><div class="slds-truncate" title="quarter1Month3" onload={findOrgFYData}></div></center>
                </th>   
                <th scope="col">
                    <center><div class="slds-truncate" title="quarter2Month1" onload={findOrgFYData}></div></center>
                </th>  
                <th scope="col">
                    <center><div class="slds-truncate" title="quarter2Month2" onload={findOrgFYData}></div></center>
                </th>    
                <th scope="col">
                    <center><div class="slds-truncate" title="quarter2Month3" onload={findOrgFYData}></div></center>
                </th>   
                <th scope="col">
                    <center><div class="slds-truncate" title="quarter3Month1" onload={findOrgFYData}></div></center>
                </th>  
                <th scope="col">
                    <center><div class="slds-truncate" title="quarter3Month2" onload={findOrgFYData}></div></center>
                </th>    
                <th scope="col">
                    <center><div class="slds-truncate" title="quarter3Month3" onload={findOrgFYData}></div></center>
                </th>  
                <th scope="col">
                    <center><div class="slds-truncate" title="quarter4Month1" onload={findOrgFYData}></div></center>
                </th>  
                <th scope="col">
                    <center><div class="slds-truncate" title="quarter4Month2" onload={findOrgFYData}></div></center>
                </th>    
                <th scope="col">
                    <center><div class="slds-truncate" title="quarter4Month3" onload={findOrgFYData}></div></center>
                </th>  
            </tr>
            
        </thead>   
    </table>
   

</template>

periodLWC.js

import { LightningElement, track} from 'lwc';


import getFYOrgData '@salesforce/apex/PeriodController.getFYOrgData';


export default class periodLWC extends LightningElement {

    @track periodData = [];

    @track startFY;
                    
    @track endFY;

    @track error;

    @track fyValue = '--None--';

    @track fyOptions = [
        {value: 'FY2019', label: 'FY2019'},
        {value: 'FY2020', label: 'FY2020'},
        {value: 'FY2021', label: 'FY2021'}
    ];

    findOrgFYData(event) {
        const orgFY = event.target.value;

        var orgFYstart = orgFY.substring(2);

        var orgFYstartInt = parseInt(orgFYstart, 10);

        var startFYInt;

        var endFYInt;

        if(orgFYstartInt) {
           
            getFYOrgData({orgFYstartInt})
            .then(result => {
                if(result) {

                    var divTitle = this.template.querySelector('title').value;
                    
                    
                    this.orgFYData = result;
                    
                    
                    this.startFY = result[0];
                    
                    startFYInt = this.startFY;
                    
                    this.endFY = result[1];
                    
                    endFYInt = this.endFY;
                    
                    switch(divTitle) {
                        case "quarter1Month1":
                            this.template.querySelector('div').innerHTML = 'February'.concat(startFYInt);
                            break;
                        case "quarter1Month2":
                            this.template.querySelector('div').innerHTML='March'.concat(startFYInt);
                            break;    
                        case "quarter1Month3":
                            this.template.querySelector('div').innerHTML='April'.concat(startFYInt);
                            break; 
                        case "quarter2Month1":
                            this.template.querySelector('div').innerHTML='May'.concat(startFYInt);
                            break;    
                        case "quarter2Month2":
                            this.template.querySelector('div').innerHTML='June'.concat(startFYInt);
                            break;   
                        case "quarter2Month3":
                            this.template.querySelector('div').innerHTML='July'.concat(startFYInt);
                            break; 
                        case "quarter3Month1":
                            this.template.querySelector('div').innerHTML='August'.concat(startFYInt);
                            break;   
                        case "quarter3Month2":
                            this.template.querySelector('div').innerHTML='September'.concat(startFYInt);
                            break;    
                        case "quarter3Month3":
                            this.template.querySelector('div').innerHTML='October'.concat(startFYInt);
                            break; 
                        case "quarter4Month1":
                            this.template.querySelector('div').innerHTML='November'.concat(endFYInt);
                            break;   
                        case "quarter4Month2":
                            this.template.querySelector('div').innerHTML='December'.concat(endFYInt);
                            break;  
                        case "quarter4Month3":
                            this.template.querySelector('div').innerHTML='January'.concat(endFYInt);
                            break;                                    
                    }
            
                }

                
            })
            .catch(error => {
                this.error = error;
            })    
        }
        
    }
     
    
}

4

The onload event does not work on a div element.

Supported HTML tags:  <body>, <frame>, <iframe>, <img>, <input type="image">, <link>, <script>, <style>

Source and another source.

I can see that you are trying to modify the innerHTML for the divs. To do that you need to add lwc:dom="manual" to any HTML which HTML you want to manipulate. You can read more here.

Additionally your query this.template.querySelector('div') is not specific enough. You have many divs in your template so the query will randomly pick one and return it to you. Likely not the one you are looking for.

I think that if you have a reasonably finite number of divs you can use the @track decorator on a few variables.

For instance in your HTML you can have:

<center><div class="slds-truncate">{quarter1Month1Value}</div></center>

In your JS you can set quarter1Month1Value as a variable like so:

@track quarter1Month1Value;
@track quarter1Month2Value;
....
@track quarter4Month3Value;

// some code goes here

getFYOrgData({orgFYstartInt})
        .then(result => {
            if(result) {
               this.quarter1Month1Value = 'February'.concat(startFYInt);
               this.quarter1Month2Value = 'March'.concat(startFYInt);
               ....
               this.quarter4Month3Value = 'January'.concat(startFYInt);

// more code goes here
| improve this answer | |
  • I implemented your suggestions and header labels are dynamic now. Thanks for your immediate response and providing a much simpler approach. – Ertyq Jun 22 at 10:23
  • 1
    @Ertyq you got it! – Arthlete Jun 22 at 15:07
3

Further to @Arthlete's response, the use of JavaScript-based DOM manipulation is not the right approach in LWCs. Instead, you should make sure you deal with this directly in the template via use of property values.

The cleanest approach would be to leverage an array-based tracked property and use an iteration in your template. Something like this:

Template:

<table class="slds-table slds-table_cell-buffer slds-table_bordered slds-table_col-bordered slds-table_row-bordered"> 
    <thead>
        <tr class="slds-line-height_reset"> 
            <template for:each={headings} for:item="heading">
                <th scope="col" key={heading}>
                    <center><div class="slds-truncate" title={heading}>{heading}</div></center>
                </th>  
            </template>
            ...

The JavaScript:

@track headings;

getFYOrgData({orgFYstartInt}).
    then(result => {
        if (result) {
            headings = ["January", "February", "March", ..., "December"].map(month => month + result);
        });

This basically creates you an array of month name plus year value and gets these rendered as your column headings. Adjust as you need in order to handle it the way you need it.

| improve this answer | |
  • 2
    +1 for the iterative solution. Thanks for the addition Phil. – Arthlete Jun 22 at 15:17

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.