0

I have created a custom Aura component to add quote lines in a Quote. We have a custom Product in our system. When someone selects that product, they get options for how many times they want to add that product to the Quote. Based on the number they select, in the next screen, I am displaying the same selected products multiple times with options to edit some fields like Unit Price, Product Name, and some more fields.

We also have a custom sort order where they enter the value in which order they want to add products. When I click on sort, I lose the adjusted list price value, whereas other values remain as they are. This works fine when I add only two products, but as soon as I add a third product, this value gets reset to the default value for some rows.

first Screen HTML:

 <aura:attribute name="selectedCustomProducts" type="Object"/>
        <aura:if isTrue="{!v.displayCustomProduct}">
                
                <!-- Modal/Popup Box starts here-->
                <section role="dialog" tabindex="-1" aria-labelledby="modal-heading-01" aria-modal="true" aria-describedby="modal-content-id-1" class="slds-modal slds-fade-in-open">
                    <div class="slds-modal__container">
                        <!-- Modal/Popup Box Header Starts here-->
                        <header class="slds-modal__header">
                            <lightning:buttonIcon iconName="utility:close"
                                                  onclick="{! c.closeModel }"
                                                  alternativeText="close"
                                                  variant="bare-inverse"
                                                  class="slds-modal__close"/>
                            <h2 id="modal-heading-01" class="slds-text-heading_medium slds-hyphenate slds-align_absolute-center">Custom Product Input</h2>
                        </header>
                        <!--Modal/Popup Box Body Starts here-->
                        <div class="slds-modal__content slds-p-around_medium" id="modal-content-id-1">
                            <lightning:card title="">                         
                                <table class="slds-table slds-table--bordered ">
                                    <thead>
                                        <tr class="slds-text-title--caps">
                                            
                                            <th scope="col" class="slds-size_4-of-12">
                                                <div style="margin-left:0 rem;" class="slds-truncate" required="true" title="Product">Product Name</div>
                                            </th>
                                            <th scope="col" class="slds-size_6-of-12">
                                                <div style="margin-left:-3rem;" class="slds-truncate" required="true" title="Quantity">Product Description</div>
                                            </th>
                                            <th scope="col" class="slds-size_2-of-12">
                                                <div class="slds-truncate" required="true" title="Quantity">No of times Product Needed</div>
                                            </th>
                                        </tr>
                                    </thead>    
                                    <tbody>
                                        <aura:iteration items="{!v.selectedCustomProducts}" var="ct" indexVar="i">
                                            <tr  data-record="{!i}" id ="{!i}">
                                                <td role="gridcell">
                                                    <div class="slds-truncate" title="Value Proposition">{!ct.ProductName}</div>
                                                </td>
                                                <td role="gridcell">
                                                    <div class="slds-truncate" title="Value Proposition">{!ct.ProductDescription}</div>
                                                </td>
                                                <td data-label="Email">
                                                    <lightning:input type="text" name="input1" value="{!ct.customProductQuantity }"></lightning:input>
                                                    
                                                </td>
                                                
                                            </tr>     
                                        </aura:iteration>
                                    </tbody>                                
                                </table>
                            </lightning:card> 
                            
                        </div>
                        <footer class="slds-modal__footer">
                            <lightning:button variant="brand"
                                              label="Confirm"
                                              title="Save"
                                              onclick="{!c.handleConfirmButton}"/>
                        </footer>
                    </div>
                </section>
                <div class="slds-backdrop slds-backdrop_open"></div>
            </aura:if>

First Screen JS:

handleConfirmButton : function(component, event, helper){
        console.log('>>> handleConfirmButton... ');
        let selectedProductList = component.get('v.selectedCustomProducts');
        console.log('>>> selectedProductList... '+JSON.stringify(selectedProductList));
        
        let clonedObject = [];
        for(var i= 0; i<selectedProductList.length ; i++){
            for(var j = 0; j < selectedProductList[i].customProductQuantity-1; j++){
                clonedObject.push(JSON.parse(JSON.stringify(selectedProductList[i])));
            }
        }
        
        let selectedProduct = component.get("v.selectedProducts");
        selectedProduct.push(...clonedObject);
        console.log('>>> selectedProduct in confirm... '+JSON.stringify(selectedProduct));
        
        //component.set("v.displayEditQuote",true);
        component.set("v.isAddProductModalOpen",false);
        component.set("v.selectedProducts",selectedProduct);
        
        component.set("v.displayMargin",true);
        component.set("v.displayCustomProduct",false);
    },

Second Screen HTML:

<aura:attribute name="selectedNotRequiredQuoteLine" type="PriceBookEntryWrapper"/>
<aura:attribute name="selectedQuoteLine" type="PriceBookEntryWrapper" />

    <div class="slds-m-around_xx-large">


            <!--Use aura:if tag to display/hide popup based on isModalOpen value-->  
            <aura:if isTrue="{!v.isModalOpen}">
                <aura:if isTrue="{!v.displayEditQuote}">

                <!-- Modal/Popup Box starts here-->
                <section role="dialog" tabindex="-1" aria-labelledby="modal-heading-01" aria-modal="true" aria-describedby="modal-content-id-1" class="slds-modal slds-fade-in-open">
                    <div class="slds-modal__container">
                        <!-- Modal/Popup Box Header Starts here-->
                        <header class="slds-modal__header">
                            <lightning:buttonIcon iconName="utility:close"
                                                  onclick="{! c.closeModel }"
                                                  alternativeText="close"
                                                  variant="bare-inverse"
                                                  class="slds-modal__close"/>
                            <h2 id="modal-heading-01" class="slds-text-heading_medium slds-hyphenate slds-align_absolute-center">Edit Selected Quote Line Items</h2>
                        </header>
                        <!--Modal/Popup Box Body Starts here-->
                        <div class="slds-modal__content slds-p-around_medium" id="modal-content-id-1">
                            <aura:if isTrue="{!v.selectedQuoteLine.length &gt; 0}">  
                            <lightning:card title="Required Products">                         
                                <table class="slds-table slds-table--bordered ">
                                    <thead>
                                        <tr class="slds-text-title--caps">
                                            <th scope="col" class="slds-size_1-of-12">
                                                <div class="slds-truncate" title="Required">Required</div>
                                            </th>
                                            <th scope="col" class="slds-size_3-of-12">
                                                <div style="margin-left:0 rem;" class="slds-truncate" required="true" title="Product">Product Name</div>
                                            </th>
                                            <th scope="col" class="slds-size_6-of-12">
                                                <div style="margin-left:-3rem;" class="slds-truncate" required="true" title="Quantity">Product Description</div>
                                            </th>
                                            <th scope="col" class="slds-size_2-of-12">
                                                <div class="slds-truncate" required="true" title="Quantity">Quantity</div>
                                            </th>
                                            <th scope="col" class="slds-size_1-of-12">
                                                <div class="slds-truncate" required="true" title="Quantity">List Price</div>
                                            </th>

                                            <th scope="col" class="slds-size_2-of-12">
                                                <div class="slds-truncate" required="true" title="Quantity">Adjusted List Price</div>
                                            </th>
                                            <th scope="col" class="slds-size_2-of-12">
                                                <div class="slds-truncate" required="true" title="Quantity">Total Price</div>
                                            </th>
                                            <th scope="col" class="slds-size_1-of-12">
                                                <div class="slds-truncate" required="true" title="Quantity">Sort Order</div>
                                            </th>


                                        </tr>
                                    </thead>    
                                    <tbody>
                                        <aura:iteration items="{!v.selectedQuoteLine}" var="ct" indexVar="i">
                                            <aura:if isTrue="{!!ct.deleted}">
                                                <aura:if isTrue="{!or(not(empty(ct.heading)),!v.selectedIndex == !i)}">
                                                    <aura:if isTrue="{!v.isDisplayselectedIndex}">
                                                        <tr>
                                                            <td></td>
                                                            <td>
                                                                <div class="slds-size_1-of-2">
                                                                    <lightning:input type="text" name="input1" value="{!ct.heading}" placeholder="Enter heading here"></lightning:input>
                                                                </div>
                                                            </td>
                                                            <td></td>
                                                            <td></td>
                                                            <td></td>
                                                            <td></td>
                                                            <td></td>
                                                            <td></td>
                                                        </tr>
                                                    </aura:if>     
                                                </aura:if>    
                                                <tr  data-record="{!i}" id ="{!i}">
                                                    <td data-label="Email">
                                                        <div class="slds-p-top_none" style="width:1rem;"><lightning:input type="Checkbox" name="{!ct.priceBook.Id}" label="" checked="{!ct.Required}" onchange="{!c.onChangeRequired}"/>
                                                        </div>

                                                    </td>
                                                    <td data-label="Last Name">
                                                        <div class="slds-p-top_none slds-p-left_none" style="width: 14rem;margin-left:0 rem">
                                                            <lightning:input type="text" name="input1" value="{!ct.priceBook.Product2.Name}"></lightning:input>
                                                        </div>
                                                    </td>
                                                    <td data-label="Email">
                                                        <div style="margin-left:-3rem;margin-top: 1.6rem;" aria-label="" class="slds-rich-text-area__content slds-grow slds-cell-wrap slds-p-top_none slds-p-left_none">
                                                            <lightning:textarea name="input1" value="{!ct.priceBook.Product2.Description}"/>
                                                        </div>
                                                    </td>
                                                    <td data-label="Email">
                                                        <div class="slds-p-top_none" style="width: 1rem;"></div>
                                                        <lightning:input type="text" name="input1" value="{!ct.Quantity}" onchange="{!c.onChangeQuantity}"></lightning:input>
                                                    </td>
                                                    <td data-label="Email">
                                                        <ui:outputCurrency class="slds-p-top_none" value="{!ct.priceBook.UnitPrice}" format="{!v.currencyFormatter}"/>

                                                    </td>
                                                    <td data-label="Email">
                                                        <ui:inputCurrency aura:id="amount" class="slds-p-top_none" value="{!ct.adjustedListPrice}" keyup="{!c.onChangeUnitPrice}" format="{!v.currencyFormatter}" updateOn="keyup"/>
                                                    </td>
                                                    <td data-label="Email">
                                                        <div class="slds-p-top_none" style="width: 1rem;"></div>
                                                        <lightning:input type="text" name="input1" value="{!ct.adjustedListPrice * ct.Quantity}" readonly="true"></lightning:input>
                                                    </td>
                                                    <td data-label="Email">
                                                        <div class="slds-p-top_none" style="width: 1rem;margin-top: -1rem;"></div>                                                   
                                                            <lightning:input type="text" name="input1" value="{!ct.sortOrder}"></lightning:input> 
                                                    </td>
                                                    <!--
                                                    <td data-label="Email">
                                                        <div style="margin-top:1rem;">
                                                            <lightning:buttonMenu alternativeText="Show menu" onselect="{! c.handleSelect }">
                                                                <lightning:menuItem aura:id="{!i}" value="{!i}" label="Add header above"/>
                                                            </lightning:buttonMenu>
                                                        </div>
                                                    </td>
                                                    -->
                                                    <td data-label="Email">
                                                        <div class="slds-p-top_none" style="margin-top:1rem;">
                                                            <lightning:button  label="" name="{!ct.priceBook.Id}" iconName="utility:delete" iconPosition="left"  variant="destructive" onclick="{! c.onDelete }"/>
                                                        </div>
                                                    </td>
                                                </tr>     
                                            </aura:if>
                                        </aura:iteration>
                                    </tbody>                                
                                </table>
                            </lightning:card> 
                            <p class="slds-align_absolute-center" style="margin-left: 39rem;">Subtotal : {!v.subtotal}</p>
                            <div><form class="slds-form slds-form_horizontal">
                                <lightning:input class="slds-size_1-of-4"
                                                 style="margin-left: 50rem; text-align: right;" 
                                                 value="{!v.discount}" label="Discount:"
                                                 onchange="{! c.discountValue }"
                                                 placeholder="{!v.discount}"
                                                 type="number"
                                                 name="input1" />
                                </form>
                            </div>
                            <p class="slds-align_absolute-center" style="margin-left: 39rem;">Total : {!v.total}</p>
                            </aura:if>

                        </div>
                        <!--Modal/Popup Box Footer Starts here-->
                        <footer class="slds-modal__footer">
                            <lightning:button variant="brand"
                                              label="Previous"
                                              title="Previous"
                                              class="slds-float_left"
                                              onclick="{! c.navigatePreviousScreen }"
                                              />
                            <lightning:button variant="neutral"
                                              label="Cancel"
                                              title="Cancel"
                                              onclick="{! c.closeModel }"
                                              />
                            <lightning:button variant="brand"
                                              label="Save"
                                              title="Save"
                                              onclick="{!c.saveLineItem}"/>
                            <lightning:button variant="brand"
                                              label="Sort"
                                              title="Sort"
                                              onclick="{!c.sortLineItem}"/>
                        </footer>
                    </div>
                </section>
              </aura:if>
            </aura:if>
        </div>

Second Screen JS:

sortLineItem : function(component, event, helper){
        var sortAsc = component.get("v.sortAsc");
        let sortQuoteLine = component.get('v.selectedQuoteLine'); 
        console.log('>>> sortQuoteLine before sort... '+JSON.stringify(sortQuoteLine));
        let sortField = 'sortOrder' ;
        if(sortQuoteLine != null && sortQuoteLine.length > 0){
            sortQuoteLine.sort(function(a,b){
                var t1 = a[sortField] == b[sortField],
                    t2 = a[sortField] > b[sortField];
                return t1? 0: (sortAsc?-1:1)*(t2?-1:1);
            });
            component.set('v.selectedQuoteLine',sortQuoteLine);
            console.log('>>> sortQuoteLine after sort... '+JSON.stringify(sortQuoteLine));
        }
        
        let sortNotRequiredQuoteLine = component.get('v.selectedNotRequiredQuoteLine');
        if(sortNotRequiredQuoteLine != null && sortNotRequiredQuoteLine.length > 0){
            sortNotRequiredQuoteLine.sort(function(a,b){
                var t1 = a[sortField] == b[sortField],
                    t2 = a[sortField] > b[sortField];
                return t1? 0: (sortAsc?-1:1)*(t2?-1:1);
            });
            component.set('v.selectedNotRequiredQuoteLine',sortNotRequiredQuoteLine);
        }
        
    }

1 Answer 1

0

There's a lot of code here, so it's hard to be certain, but I'm guessing the culprit is this line:

<aura:if isTrue="{!or(not(empty(ct.heading)),!v.selectedIndex == !i)}">

An Aura expression starts with {! and ends with }, and inside the expression, it acts as the not operator. In JavaScript, that turns a falsy value into true, and a truthy value becomes false. So, instead of comparing the selectedIndex to i, you're comparing if the selectedIndex equals 0 to if the value of i is 0.

I know that might sound confusing, so let's make a couple of simple examples:

Expression Expanded Result
!0 == !0 true == true true
!0 == !1 true == false false
!1 == !1 true == true true
!1 == !2 true == true true

As you can see, running a value through the not operator can yield unexpected results. This also explains why there are no behavior problems with only two records, but there are with three; you're accidentally rendering the UI incorrectly, binding values to the wrong variables.

Variables are not referenced by ! inside an expression. It's easy enough to make this assumption because of the syntax. I think this is part of the reason why LWC doesn't use {!...}, but instead an unambiguous {...} syntax.

3
  • so instead of {!or(not(empty(ct.heading)),!v.selectedIndex == !i)}, I need to use {!or(not(empty(ct.heading)), v.selectedIndex == i)}? Commented Jan 18 at 14:37
  • @salesforceDeveloper correct.
    – sfdcfox
    Commented Jan 18 at 14:43
  • it didn't work, On further debugging I noticed that the Input value not getting updated correctly for adjustedListPrice field and that's the only attribute for which I'm seeing this issue. this attribute is of type Decimal Commented Jan 23 at 17:55

You must log in to answer this question.

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