0

My goal is onclick of any checkbox here, get the data-id of all checked activities. I've tried several things, but new to LWC and fairly new to selectors.

Currently, when I click any checkbox, the last 4 lines in the Console here print. In my reading, it seems that SecureNodeList may not be traversable.

[![enter image description here][1]][1]


<template>
  <lightning-card>
  <h3 slot="title">
      <lightning-icon icon-name="utility:connected_apps" size="small"></lightning-icon>
      Activities
  </h3>
  <div class="slds-m-left_medium slds-m-right_medium slds-text-medium">
    Remember to click Save after checking off activities. Once all Mandated Activities 
    have been checked off, you may Submit to your manager.
  </div>

  <div slot="footer">
    <!-- Neutral variant (default) -->
    <lightning-button label="Save" onchange={selectAllCheckedOffActivities} class="slds-m-left_x-small"></lightning-button>
    <!-- Neutral variant (default) -->
    <lightning-button label="Submit" title="Non-primary action" onclick={handleClick} class="slds-m-left_x-small"></lightning-button>
  </div>


    <div class="slds-m-left_medium slds-m-top_medium slds-m-bottom_medium">
      <div class="slds-text-heading_medium">Mandated Activities</div>
      <template for:each={mandatedActivities} for:item="activity">
          <span key={activity.id}>
            <div class="slds-col">
                <lightning-input type="checkbox" data-id={activity.id} label={activity.title} checked={activity.isChecked}></lightning-input>
            </div>
          </span>
      </template>
      <div class="slds-text-heading_medium slds-m-top_medium">If Appropriate</div>
      <template for:each={ifAppropriateActivities} for:item="activity">
        <span key={activity.id}>
          <div class="slds-col">
              <lightning-input type="checkbox" data-id={activity.id} label={activity.title} checked={activity.isChecked}></lightning-input>
          </div>
        </span>
      </template>
      <div class="slds-text-heading_medium slds-m-top_medium">Optional Activities</div>
      <template for:each={optionalActivities} for:item="activity">
        <span key={activity.id}>
          <div class="slds-col">
              <lightning-input type="checkbox" data-id={activity.id} label={activity.title} checked={activity.isChecked}></lightning-input>
          </div>
        </span>
      </template>
    </div>
  </lightning-card>
</template>

import {LightningElement, wire, track} from 'lwc';
import {CurrentPageReference} from 'lightning/navigation';
import getEventActivityWrappers from '@salesforce/apex/EventActivities_Ctrl.getEventActivityWrappers';
import updateEventActivityCheckboxTracker from '@salesforce/apex/EventActivities_Ctrl.updateEventActivityCheckboxTracker';

export default class EventActivityChecklist extends LightningElement {

  @track currentPageReference = null;
  @track siteSurveyId = '';
  @track activityIdsForTracker = 'a1e1k00000Fvv6TAAR,a1e1k00000Fvv6UAAR,a1e1k00000Fvv6dAAB';

  @track activities = [];
  @track mandatedActivities = [];
  @track ifAppropriateActivities = [];
  @track optionalActivities = [];

  @track checkedBoxesIds = [];

  @wire(CurrentPageReference) getRecordIdFromURL(currentPageReference) {
      if (currentPageReference) {
        this.siteSurveyId = currentPageReference.attributes.recordId;
      }
  }
  
  get selectedIds() {
    return this.checkedBoxesIds.join(',');
  }
  
  selectAllCheckedOffActivities(event) {
    this.checkedBoxesIds = [...this.template.querySelectorAll('lightning-input')].filter(element => element.checked).map(element => element.dataset.id);
    console.log('*** checkedBoxesIds: ' + this.checkedBoxesIds);
  }

  @wire(updateEventActivityCheckboxTracker, {siteSurveyId: '$siteSurveyId', checkedBoxesIds:'$checkedBoxesIds'}) wiredUpdateOfCheckboxTracker({ data, error }) {
    console.log('*** checkedBoxesIds: ' + this.checkedBoxesIds);
  }
  
  @wire(getEventActivityWrappers, {siteSurveyId:'$siteSurveyId'}) 
    wiredGetEventActivityWrappers({data, error}) {
      if (data) {
        console.log(data);
        this.activities = data;
        if(this.activities) {
          this.activities.forEach((activity) => {
            if(activity.type == "Mandated Activity") {
              this.mandatedActivities.push(activity);
            } else if(activity.type == "If Appropriate") {
              this.ifAppropriateActivities.push(activity); 
            } else if(activity.type == "Optional Activity") {
              this.optionalActivities.push(activity); 
            }
          })
        }
      } else if (error) {
        console.log(error);
      }
    }
}

public with sharing class EventActivities_Ctrl {
  
  @AuraEnabled (cacheable=true)
  public static void updateEventActivityCheckboxTracker(String siteSurveyId, String activityIdsForTracker) {
    System.debug('*** siteSurveyId: ' + siteSurveyId);
    System.debug('*** activityIdsForTracker: ' + activityIdsForTracker);

    Site_Survey__c siteSurvey = [SELECT Id, Event_Activity_Checkbox_Tracker__c
                                 FROM Site_Survey__c 
                                 WHERE Id = :siteSurveyId];
    siteSurvey.Event_Activity_Checkbox_Tracker__c = activityIdsForTracker;
    update siteSurvey;

    System.debug('***Tracker from DB: ' + [SELECT Id, Event_Activity_Checkbox_Tracker__c
                                        FROM Site_Survey__c 
                                        WHERE Id = :siteSurveyId]);
  }

  @AuraEnabled (cacheable=true)
  public static List<EventActivityWrapper> getEventActivityWrappers(String siteSurveyId) {
    List<EventActivityWrapper> eventActivityWrappers = new List<EventActivityWrapper>();
    List<Event_Activity__c> eventActivities = [SELECT Id, Title__c, Type__c 
                                               FROM Event_Activity__c 
                                               ORDER BY Type__c ASC];
    Site_Survey__c siteSurvey = [SELECT Id, Event_Activity_Checkbox_Tracker__c
                                        FROM Site_Survey__c 
                                        WHERE Id = :siteSurveyId];

    for(Event_Activity__c eventActivity: eventActivities) {
      EventActivityWrapper eventActivityWrapper = new EventActivityWrapper(eventActivity.Id, 
                                                                           eventActivity.Title__c, 
                                                                           eventActivity.Type__c, 
                                                                           false);

      for(String activityIdFromTracker : siteSurvey.Event_Activity_Checkbox_Tracker__c.split(',')){
        if(activityIdFromTracker == eventActivity.Id){
          eventActivityWrapper.isChecked = true;
        }
      }
      eventActivityWrappers.add(eventActivityWrapper);
    }
    return eventActivityWrappers;
  }

  public class EventActivityWrapper{
        
    @AuraEnabled
    public Id activityId{get;set;}
    @AuraEnabled
    public String title{get;set;}
    @AuraEnabled
    public String type{get;set;}
    @AuraEnabled
    public Boolean isChecked{get;set;}

    public EventActivityWrapper(String activityId, String title, String type, Boolean isChecked) {
      this.activityId = activityId;
      this.title = title;
      this.type = type;
      this.isChecked = isChecked;
    }
  }
}
2

You can query the elements, filter by the checkbox, and then grab the data you want. This is pretty trivial:

this.checkedBoxesIds = [...this.template.querySelectorAll('lightning-input')]
  .filter(element => element.checked)
  .map(element => element.dataset.id);

Where [...iterable] copies an array or array-like element into a proper Array, Array.filter checks the condition and returns only the matching elements, and Array.map translates an array into another array (by "mapping" the value).

10
  • Thanks sfdcfox! See Response to SFDC Fox in original message. Why is "*** checkedBoxesIds:" null in the Console? Also, I unchecked a single box. Why does "*** checkedBoxesIds:" print twice? Jul 30 at 20:43
  • 1
    @RyanMcNeely change your onclick to an onchange Jul 30 at 21:51
  • @sfdcfox why does checkedBoxesIds return null? also, I'm not clear on how element.dataset.id can grab onto the id from data-id attribute. When I tried element.dataset.data-id I got an error. Jul 30 at 23:17
  • @RyanMcNeely See my demo. It works fine for me.
    – sfdcfox
    Jul 31 at 0:14
  • @digglemister onclick works just fine. See demo (above).
    – sfdcfox
    Jul 31 at 0:14
0

The final code works like a charm. When user clicks Save, it gets all IDs, sends all Ids to Apex as a String[]. In apex, updates a field with that string of Ids. So when the page is reloaded, all prior checkboxes are still checked.


    <template>
  <lightning-card>
  <h3 slot="title">
      <lightning-icon icon-name="utility:connected_apps" size="small"></lightning-icon>
      Activities
  </h3>
  <div class="slds-m-left_medium slds-m-right_medium slds-text-medium">
    Remember to click Save after checking off activities. Once all Mandated Activities 
    have been checked off, you may Submit to your manager.
  </div>

  <div slot="footer">
    <lightning-button label="Save" onclick={selectAllCheckedOffActivities} class="slds-m-left_x-small"></lightning-button>
    <lightning-button label="Submit" title="Non-primary action" class="slds-m-left_x-small"></lightning-button>
  </div>


    <div class="slds-m-left_medium slds-m-top_medium slds-m-bottom_medium">
      <div class="slds-text-heading_medium">Mandated Activities</div>
      <template for:each={mandatedActivities} for:item="activity">
          <span key={activity.activityId}>
            <div class="slds-col">
                <lightning-input type="checkbox" data-id={activity.activityId} data-type={activity.type} label={activity.title} checked={activity.isChecked}></lightning-input>
            </div>
          </span>
      </template>
      <div class="slds-text-heading_medium slds-m-top_medium">If Appropriate</div>
      <template for:each={ifAppropriateActivities} for:item="activity">
        <span key={activity.activityId}>
          <div class="slds-col">
              <lightning-input type="checkbox" data-id={activity.activityId} label={activity.title} checked={activity.isChecked}></lightning-input>
          </div>
        </span>
      </template>
      <div class="slds-text-heading_medium slds-m-top_medium">Optional Activities</div>
      <template for:each={optionalActivities} for:item="activity">
        <span key={activity.activityId}>
          <div class="slds-col">
              <lightning-input type="checkbox" data-id={activity.activityId} label={activity.title} checked={activity.isChecked}></lightning-input>
          </div>
        </span>
      </template>
    </div>
  </lightning-card>
</template>

    import {LightningElement, wire, track} from 'lwc';
import {CurrentPageReference} from 'lightning/navigation';
import getEventActivityWrappers from '@salesforce/apex/EventActivities_Ctrl.getEventActivityWrappers';
import updateEventActivityCheckboxTracker from '@salesforce/apex/EventActivities_Ctrl.updateEventActivityCheckboxTracker';

export default class EventActivityChecklist extends LightningElement {

  @track currentPageReference = null;
  @track siteSurveyId = '';
  @track activityIdsForTracker = [];

  @track activities = [];
  @track mandatedActivities = [];
  @track ifAppropriateActivities = [];
  @track optionalActivities = [];


  @wire(CurrentPageReference) getRecordIdFromURL(currentPageReference) {
      if (currentPageReference) {
        this.siteSurveyId = currentPageReference.attributes.recordId;
      }
  }
  
  selectAllCheckedOffActivities(event) {
    this.activityIdsForTracker = [...this.template.querySelectorAll('lightning-input')].filter(element => element.checked).map(element => element.dataset.id);
    console.log('*** activityIdsForTracker: ' + this.activityIdsForTracker);
    
    updateEventActivityCheckboxTracker(
      {siteSurveyId: this.siteSurveyId, activityIdsForTracker: this.activityIdsForTracker});
  }


  @wire(getEventActivityWrappers, {siteSurveyId:'$siteSurveyId'}) 
    wiredGetEventActivityWrappers({data, error}) {
      if(data) {
        console.log(data);
        this.activities = data;
        if(this.activities) {
          this.activities.forEach((activity) => {
            if(activity.type == "Mandated Activity") {
              this.mandatedActivities.push(activity);
            } else if(activity.type == "If Appropriate") {
              this.ifAppropriateActivities.push(activity); 
            } else if(activity.type == "Optional Activity") {
              this.optionalActivities.push(activity); 
            }
          })
        }
      } else if (error) {
        console.log(error);
      }
    }
}

public with sharing class EventActivities_Ctrl {
  
  @AuraEnabled
  public static void updateEventActivityCheckboxTracker(String siteSurveyId, String[] activityIdsForTracker) {
    System.debug('*** siteSurveyId: ' + siteSurveyId);
    System.debug('*** activityIdsForTracker: ' + activityIdsForTracker);
    
    Site_Survey__c siteSurvey = [SELECT Id, Event_Activity_Checkbox_Tracker__c
                                 FROM Site_Survey__c 
                                 WHERE Id = :siteSurveyId];

    siteSurvey.Event_Activity_Checkbox_Tracker__c = 
      activityIdsForTracker.toString().remove('(').remove(')').remove(' ');

    update siteSurvey;
  }

  @AuraEnabled (cacheable=true)
  public static List<EventActivityWrapper> getEventActivityWrappers(String siteSurveyId) {
    List<EventActivityWrapper> eventActivityWrappers = new List<EventActivityWrapper>();
    List<Event_Activity__c> eventActivities = [SELECT Id, Title__c, Type__c 
                                               FROM Event_Activity__c 
                                               ORDER BY Type__c ASC];

    Site_Survey__c siteSurvey = [SELECT Id, Event_Activity_Checkbox_Tracker__c
                                 FROM Site_Survey__c 
                                 WHERE Id = :siteSurveyId];

    for(Event_Activity__c eventActivity: eventActivities) {
      EventActivityWrapper eventActivityWrapper = new EventActivityWrapper(eventActivity.Id, 
                                                                           eventActivity.Title__c, 
                                                                           eventActivity.Type__c, 
                                                                           false);
      if(siteSurvey.Event_Activity_Checkbox_Tracker__c != null){
        for(String activityIdFromTracker : siteSurvey.Event_Activity_Checkbox_Tracker__c.split(',')){
          if(activityIdFromTracker == eventActivity.Id){
            eventActivityWrapper.isChecked = true;
          }
        }
      }
      eventActivityWrappers.add(eventActivityWrapper);
    }
    return eventActivityWrappers;
  }

  public class EventActivityWrapper{
        
    @AuraEnabled
    public Id activityId{get;set;}
    @AuraEnabled
    public String title{get;set;}
    @AuraEnabled
    public String type{get;set;}
    @AuraEnabled
    public Boolean isChecked{get;set;}

    public EventActivityWrapper(String activityId, String title, String type, Boolean isChecked) {
      this.activityId = activityId;
      this.title = title;
      this.type = type;
      this.isChecked = isChecked;
    }
  }
}

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.