Get Wrapper Data from Selected Rows in SLDS Table

htmljavascriptlightning-web-components

Due to styling contraints I am unable to use the standard lightning-datatable in my LWC. I had tried creating a custom type and extending those using a custom lightning-datatable but we have too many unique use cases regarding Icons and being able to disable checkboxes to proceed with the standard approach.

I've created a standard table using the SLDS styling and I'm looping through data provided from a Wire method.

I know this is a relatively straightforward ask but the Proxy object returned is confusing my understanding of what to loop through to get the Wrapper Data from the Selected Rows on the custom table. I tried using the Closest function but it appears I'm looking in the wrong area. I'm still expanding my LWC knowledge and I've always used the standard lightning-datatable before.

What I need is to be able to loop through all selected rows when a button is clicked, then pass the Wrapper class behind that row to an Apex Method which will do the back end updates needed on the Salesforce side.

Any help would be greatly appreciated. Thank you so much.

Below is my table

<table class="slds-table slds-table_cell-buffer slds-table_bordered">
                      <thead>
                        <tr class="slds-line-height_reset">
                          <th class="" scope="col">
                            <div class="slds-truncate">
                              <lightning-input onchange={allSelectedOriginal} type="checkbox">
                              </lightning-input>
                            </div>
                          </th>
                          <th class="" scope="col">
                            <div class="slds-truncate" title="Description"></div>
                          </th>
                          <th class="" scope="col">
                            <div class="slds-truncate" title="Name">Name</div>
                          </th>
                          <th class="" scope="col">
                            <div class="slds-truncate" title="Permission Set Group Details"></div>
                          </th>
                        </tr>
                      </thead>
                      <tbody>
                        <template for:each={originalUserPermissionSetOutput} for:item="perm">
                          <tr key={perm.outputUniqueId} style="height: 30px">
                            <th scope="col">
                              <template if:false={perm.hideRow}>
                                <div>
                                  <lightning-input class="originalUserCheckbox" type="checkbox"
                                    value={perm.outputName} data-id={perm.outputUniqueId}></lightning-input>
                                </div>
                              </template>
                            </th>
                            <th scope="col">
                              <div>
                                <template if:false={perm.hideRow}>
                                  <template if:true={perm.displayDescription}>
                                    <lightning-helptext content={perm.outputDescription}>
                                    </lightning-helptext>
                                  </template>
                                </template>
                              </div>
                            </th>
                            <th scope="col">
                              <template if:false={perm.hideRow}>
                                <div>{perm.outputName}
                                </div>
                              </template>
                            </th>
                            <th scope="col">
                              <div>
                                <template if:false={perm.hideRow}>
                                  <template if:true={perm.displayPSDescription}>
                                    <lightning-helptext icon-name="utility:groups"
                                      content={perm.parentPermissionSetGroupName}>
                                    </lightning-helptext>
                                  </template>
                                  <template if:true={perm.displayPsStar}>
                                    <lightning-helptext icon-name="utility:favorite">
                                    </lightning-helptext>
                                  </template>
                                </template>
                              </div>
                            </th>
                          </tr>
                        </template>
                      </tbody>
                    </table>

Function being called:

assignselected() {

//Get all selected records across the tabs
//Display records to be selected to user
//Create the necessary records
let allRows = this.template.querySelectorAll(".originalUserCheckbox");
let selectedRows = [];

for (let i = 0; i < allRows.length; i++) {

  if (allRows[i].checked === true) {

    //Get our row Data
    let trData = allRows[i].closest("template > tr");

    //Loop through our Original Records
    for (let record of this.originalUserPermissionSetOutput) {
      if (trData.dataset.id === record.outputUniqueId) {
        selectedRows.push(record);
      }
    }
  }

}

console.log(selectedRows);
console.log(selectedRows.length);

assignPermissionRecords({ permsToAssign: JSON.stringify(selectedRows) })
  .then((results) => {
    console.log('Entered Assign Function');

  })
  .catch((error) => {
    console.log('Into Errors');
    this.notifyUser(
      "Error working on the Assignment Process",
      "Error working on the Assignment Process",
      "info"
    );
    // eslint-disable-next-line no-console
    console.error("Lookup error", JSON.stringify(error.body.message));
    this.errors = [error];
  });

}

Best Answer

An easier approach would be to and add an extra attribute to your array of objects returned from (or use an existing one - boolean that indicates what should be checked or not). Ex:

const newOriginalUserPermissionSetOutput = originalUserPermissionSetOutput.map( data => { return {...data, selected: false} })

Now you have a new array with objects +1 property (boolean) and you will need to modify your checkbox to have a handler.

So, on click of your input, you will can check against the ID of the selected row vs the one in your array.

return { ...data, selected: (event.target.data.id === data.id) ? !data.outputChecked : data.outputChecked }
or even better: return { ...data, selected: (event.target.data.id === data.id) ? target.event.checked : data.outputChecked }

and when you click your assign button, you just do

const checkedData = newOriginalUserPermissionSetOutput.filter( data => data.selected === true)

which should return an array of all objects that are selected, you can then pass that to whatever function you need to process selected rows.

Related Topic