1

Below is all the code for my component, the issue is this line

this.cabinetId ='';
this.serialOptions =[{label:'', value:''}];
return refreshApex(this._serialOptionsResponse);

I want all the current selections erased and the entire dual-listbox to reset, see i'm trying to blank the values before calling on apex to refresh. The refresh works in other instances where i want to filter values based on the cabinetId. IE i select 1 record and then it only shows other applicable records on the left side. But in this case where they select values that don't match i want the entire thing reset as if the user never made a selection......what my code does is just blanks the dual-listbox

import { LightningElement, api, wire, track} from 'lwc';
import getSerials from '@salesforce/apex/MultiSelectSerialBoxHandler.getSerials';
import { refreshApex } from '@salesforce/apex';
import { ShowToastEvent } from 'lightning/platformShowToastEvent'


export default class multiSelectOptionBox extends LightningElement {
    @api recordId;
    error;
    priorLength;
    cabinetId ='';
    _selectedAssets = [];
    _selectedCabinets = [];
    serialOptions;
    selectedValues = [];
    

    _serialOptionsResponse;
    @wire(getSerials, { recordId: '$recordId', cabinetId: '$cabinetId'}) 
    serials(response){
        this._serialOptionsResponse = response;
        let {data, error} = response;
        if(data){
        this.serialOptions = data.map((br) => Object.assign({}, { label: br.Name, value: br.Id, cabinetValue: br.Cabinet__c}));
         } else if(error){
            this.error = error;
            console.log('@wire getSerials error ' + error);
        }
    }

    get selectedassets() {
        return this._selectedAssets.length ? this._selectedAssets : 'none';
    }

    get selectedcabinets(){
        return this._selectedCabinets.length ? this._selectedCabinets : 'none';

    }

    onListBoxChange(event){
        this.priorLength = this._selectedAssets.length;
        this._selectedAssets = event.detail.value;
        this._selectedCabinets = event.target.options.filter((options) =>{
            return this._selectedAssets.some((selected) => {
                return selected === options.value;
            });
        }).map(function(obj){
            return obj.cabinetValue;
          });;

          this.checkArrayIsEmpty(event);
          this.handleSelectionChange();
    }

    /**
     * if empty reset options, if not empty filter options
     */
    checkArrayIsEmpty(event){

        if (!this._selectedCabinets.length || this._selectedCabinets.length ==0){
            this.cabinetId ='';
            return refreshApex(this._serialOptionsResponse);
        } else if(this._selectedCabinets.length ==1) {
            if(this.cabinetsAreEqual()){
            this.cabinetId = this._selectedCabinets[0];
            return refreshApex(this._serialOptionsResponse);
            } else {
                this.cabinetsNotEqual();
            }
        } else if(this._selectedCabinets.length > 1 && this.priorLength ==0){
            if(this.cabinetsAreEqual()){
                this.cabinetId = this._selectedCabinets[0]
                return refreshApex(this._serialOptionsResponse);
            } else {
                this.cabinetsNotEqual();

            }
        }
        
    }


    /**
     * send a copy of Cabinet array to parent lwc
     */
    handleSelectionChange(){
        if(this._selectedAssets.length){
        let cabinetChange = new CustomEvent('selectionchange',{
            detail  :{ 
                cabinets : [...this._selectedCabinets],
                assets : [...this._selectedAssets]
            }
        });
        this.dispatchEvent(cabinetChange);
    }else if(!this._selectedAssets.length){
        let cabinetChange = new CustomEvent('selectionchange',{
            detail  :{ 
                cabinets : [''],
                assets : ['']
            }
        });
        this.dispatchEvent(cabinetChange);
    }
    }

    /**
     * all cabinets must be the same
     */
    cabinetsAreEqual(){
      let result = this._selectedCabinets.every(element => {
        if(element === this._selectedCabinets[0]){
            return true;
        } else {
            return false;
        }
      });
      console.log('result of t/f ' + result);
      return result;
    }


    showMessage( t, m,type ){
        const toastEvt = new ShowToastEvent({
            title: t,
            message:m,
            variant: type
        });
        this.dispatchEvent(toastEvt);
    };


    /**
     * cabinets are not equal
     */
    cabinetsNotEqual(){
        console.log(' they are not equal');
        this.showMessage('Notification','These cabinets do not match','error');
        this.selectedValues = [];
        this._selectedAssets = [];
        this._selectedCabinets = [];
       
    }
}

html:

<template>
<div class="slds-form-element">
        <lightning-dual-listbox name="Serials"
                                label="Select Serials"
                                source-label="Available"
                                selected-label="Selected"
                                field-level-help="Select your serials to convert"
                                options={serialOptions}
                                onchange={onListBoxChange}
                                >
        </lightning-dual-listbox>
        <div class="slds-box" >
            <p>Selected values: {selectedassets} and  {selectedcabinets}</p>
        </div>
    </div>
</template>

EDIT: clarification

if you pick two values that don't match the dual-listbox resets. Say you have this as your list box

the listbox

Then for whatever reason lets say picking both english and german is not a valid selection we want. Picking english by itself is fine, picking german by itself is fine, picking either with a combination of any other language is fine, but having them both selected is not a valid selection.

So if they're both selected there should be an error and then the dual-listbox should be reset to it's original state IE all possible options should now be back in the left listbox and the right listbox should be empty. How does one reset a dual listbox to its original state?

EDIT UPDATE: i'm able to prevent an initial bad selection, IE The user selects two bad values and the code stops them from doing so and keeps all the values in the left box. But if they do it again it does fire a warning message BUT it allows them to select bad values. I think it has something to do with the @wire service not seeing data changes. I tried imperative code but that doesn't work either.

TLDR; i want to know how to reset a dual-listbox to how it was initially when i loaded a page without refreshing the entire page.

edit: solved showing code

5
  • It is really hard to work out what you're trying to achieve and what part of it isn't working. Why don't you add some screenshots so we can get a better idea of what you're trying to do? Also, if you add a @track decorator to the serialOptions variable, does that help?
    – Nick Cook
    Oct 31, 2022 at 4:52
  • added clarification
    – ensir
    Oct 31, 2022 at 16:20
  • Try setting serial options to an empty array. Oct 31, 2022 at 17:14
  • You could always just use my component (which selects with a double click and allows drag and drop) github.com/rapsacnz/OrderedListGroup Oct 31, 2022 at 17:16
  • what setting serial options to empty does is it blanks out the list for a moment then calls the @wire service returns all the values and then those values on the right side are still there but now the values on the left side aren't filtered.
    – ensir
    Oct 31, 2022 at 18:50

1 Answer 1

1
+250

My understanding is, you are trying to reset dual list box back to no option selected if wrong combination(English/German) is selected, for simplicity, I am just focus on the reset part without referencing your code if that is okay. I am thinking why not just use the value attribute and reset selectedassets to empty array?

A simple POC: Code: enter image description here

enter image description here

When valid combo selected: enter image description here

When you select 'English' and 'German', the code auto reset the dual list box to blank. enter image description here

3
  • I tried that, at it works but only for the first time it needs to prevent it. I think the issue has to do with the @wire service call. i'll clean up my code and try it again.
    – ensir
    Oct 31, 2022 at 23:24
  • 1
    Hi ensir, I took a closer look of your code, it could be the wire service call causing this issue or it could be this one: i noticed that in lightning-dual-listbox, you didn't specify the value attribue and binding it with a variable, instead, you query it and set the field value programatically. Do you mind trying my way first? If still doesn't work, i will take a closer look what we can do to fix the blocker caused by wire service.
    – Wayne Ni
    Nov 1, 2022 at 0:46
  • yep it was the @wire causing issues. Your solution solved it
    – ensir
    Nov 1, 2022 at 17:27

You must log in to answer this question.

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