[SalesForce] In the dynamic table, how do you dynamically set the value for each row’s inputSelect

These problems have plagued me too much time. Maybe my implementation method is problematic. Is there a better way? Ask a friend to help me.

Question 1: When I get each row value in a dynamic table, if I define [aura:id="ParentField"], this won't work because aura:id is limited to one row.

Question 2: If I use labelClass="{!index}" to get the current row,

var getLabel = event.getSource().get('v.labelClass');

I will assign a value to the {!v.childList}, but if the table has multiple rows, all rows will have values.
How to assign values only to rows of operations, not all rows?

Question 3: I have 2 ui:inputSelect needs to set the change method. When I add [labelClass="{!index}"] for the first [ui:inputSelect], the second one still needs to add [labelClass="{ !index}"], these 2 [labelClass="{!index}"] will affect each other and will not work.

This is my CMP file

<aura:component implements="flexipage:availableForAllPageTypes,force:appHostable" controller="AccountGroupController">
    <aura:handler name="init" value="{!this}" action="{!c.doInit}" />

    <aura:attribute name="PackTag" type="GroupLabel__c[]"/>
    <aura:attribute name="parentList" type="list" default="[]" description=""/>
    <aura:attribute name="childList" type="list" default="[]"/>
    <aura:attribute name="pickListMap" type="map"/>
    <aura:attribute name="disabledChildField" type="boolean" default="true"/>
    <aura:attribute name="objectName" type="string" default="GroupLabel__c"/>
    <aura:attribute name="parentFieldAPI" type="string" default="ParentPicklist__c"/>
    <aura:attribute name="childFieldAPI" type="string" default="ChildPicklist__c"/>
    <aura:attribute name="parentFieldLabel" type="string" />
    <aura:attribute name="childFieldLabel" type="string"/>
    <aura:attribute name="parentValue" type="string" default=""/>
    <aura:attribute name="childValue" type="string" default=""/>

    <div class="slds-box">
        <table class="slds-table slds-table_bordered slds-table_cell-buffer">
            <thead>
                <tr class="slds-text-title_caps">
                    <th scope="col">
                        <div class="slds-truncate">S.No</div>
                    </th>
                    <th scope="col">
                        <div class="slds-truncate" title="Classify">Classify</div>
                    </th>
                    <th scope="col">
                        <div class="slds-truncate" title="Field">Field</div>
                    </th>
                    <th scope="col">
                        <div class="slds-truncate" title="Operator">Operator</div>
                    </th>
                    <th scope="col">
                        <div class="slds-truncate" title="Value">Value</div>
                    </th>
                </tr>
            </thead>
            <tbody>
                <aura:iteration items="{!v.PackTag}" var="item" indexVar="index">
                <tr class="slds-text-title_caps" id="{!index}">
                    <td>
                        {!index}
                    </td>
                    <td>
                        <ui:inputSelect value="{!item.ParentPicklist__c}" aura:id="ParentField" labelClass="{!index}" change="{!c.classifyChange}">
                            <aura:iteration items="{!v.parentList}" var="value">
                                <option value="{!value}">{!value}</option>
                            </aura:iteration>
                        </ui:inputSelect>
                    </td>
                    <td>
                        <ui:inputSelect value="{!item.ChildPicklist__c}" aura:id="childField" change="{!c.onSelectChange}">
                            <aura:iteration items="{!v.childList}" var="value">
                                <option value="{!value}">{!value}</option>
                            </aura:iteration>
                        </ui:inputSelect>
                    </td>
                    <td>
                        <ui:inputSelect>
                            <option value="null">-None-</option>
                            <option value="equal">equal</option>
                            <option value="not equal to">not equal to</option>
                            <option value="Less than">Less than</option>
                            <option value="greater or equal to">greater or equal to</option>
                        </ui:inputSelect>
                    </td>
                    <td>
                        {!v.body}
                    </td>
                    <td>
                        <!-- conditionally Display Add or Delete Icons if rowIndex is 0 then show Add New Row Icon else show delete Icon -->
                        <aura:if isTrue="{!index == 0}">
                            <a onclick="{!c.AddNewRow}">
                                <lightning:icon iconName="utility:add" class="slds-icon slds-icon_small" size="small" alternativeText="add"/>
                                <span class="slds-assistive-text">Add Icon</span>
                            </a>
                            <aura:set attribute="else">
                                <a onclick="{!c.removeRow}" id="{!index}">
                                    <lightning:icon variant="error" iconName="utility:delete" class="slds-icon slds-icon_small" size="small" alternativeText="icon"/>
                                    <span class="slds-assistive-text">Delete Icon</span>
                                </a>
                            </aura:set>
                        </aura:if>
                    </td>
                </tr>
                </aura:iteration>
            </tbody>
        </table>
    </div>
</aura:component>

This is my JS file

({
    doInit : function(component, event, helper) {

        var RowItemList = component.get("v.PackTag");
        RowItemList.push({
            'sobjectType': 'GroupLabel__c',
            'ParentPicklist__c':'',
            'FieldAPI__c': '',
            'Operator__c': '',
            'Input_Value__c': ''
        });

        component.set("v.PackTag", RowItemList);

        var action = component.get("c.getDependentPicklist");
        action.setParams({
            ObjectName : component.get("v.objectName"),
            parentField : component.get("v.parentFieldAPI"),
            childField : component.get("v.childFieldAPI")
        });

        action.setCallback(this, function(response){
            var status = response.getState();
            if(status === "SUCCESS"){
                var pickListResponse = response.getReturnValue();

                //save response 
                component.set("v.pickListMap",pickListResponse.pickListMap);
                component.set("v.parentFieldLabel",pickListResponse.parentFieldLabel);
                component.set("v.childFieldLabel",pickListResponse.childFieldLabel);

                // create a empty array for store parent picklist values 
                var parentkeys = []; // for store all map keys 
                var parentField = []; // for store parent picklist value to set on lightning:select. 

                // Iterate over map and store the key
                for (var pickKey in pickListResponse.pickListMap) {
                    parentkeys.push(pickKey);
                }

                //set the parent field value for lightning:select
                if (parentkeys != undefined && parentkeys.length > 0) {
                    parentField.push('-None-');
                }

                for (var i = 0; i < parentkeys.length; i++) {
                    parentField.push(parentkeys[i]);
                }  
                // set the parent picklist
                component.set("v.parentList", parentField);

            }
        });

        $A.enqueueAction(action);
    },

    AddNewRow : function(component, event, helper){
        var addRowInList = component.get("v.PackTag");
        var contactObj = new Object();
        addRowInList.push(contactObj);
        component.set("v.PackTag",addRowInList);
    },
    removeRow : function(component, event, helper){
        var whichOne = event.target.getAttribute("id")
        var AllRowsList = component.get("v.PackTag");
        AllRowsList.splice(whichOne, 1);
        component.set("v.PackTag", AllRowsList);
    },

    classifyChange : function(component, event, helper) {

        var controllerValue = component.find("parentField").get("v.value");
        var pickListMap = component.get("v.pickListMap");

        if (controllerValue != '-None-') {
             //get child picklist value
            var childValues = pickListMap[controllerValue];
            var childValueList = [];
            childValueList.push('-None-');
            for (var i = 0; i < childValues.length; i++) {
                childValueList.push(childValues[i]);
            }
            // set the child list
            component.set("v.childList", childValueList);

            if(childValues.length > 0){
                component.set("v.disabledChildField" , false);  
            }else{
                component.set("v.disabledChildField" , true); 
            }

        } else {
            component.set("v.childList", ['-None-']);
            component.set("v.disabledChildField" , true);
        }
    },

    onSelectChange : function(component, event, helper) {
        var selected = component.find("childField").get("v.value");
        console.log('get = ' + selected);

        if (selected === 'Child Option 1') {
            component.set("v.body",[]);
            $A.createComponent(
                "ui:inputText",
                {
                    "placeholder":"Enter Child Option 1",
                    "class": "slds-input"
                },
                function(newInp, status, errorMessage){
                    if (status === "SUCCESS") {
                        var body = component.get("v.body");
                        body.push(newInp);
                        component.set("v.body", body);
                    }
                }
            );
        }else{
            component.set("v.body",[]);
        }
    }
})

This is the result I want to achieve:
If [CLASSIFY] selects option 1, [FIELD] only [child option 1] can be selected. [VALUE] will also change, such as data input, select input, input box, etc.
enter image description here

enter image description here

I have completed the single line feature, but if it is multiple lines, these features will not be available.

Best Answer

you have to take current row Item and then Update it then rebind to PackTag list with same Place by index, i just use Classify and field columns in below code snippet. and in your AddNewRow function, you pushing normal JSobject it shouldn't , you need to push 'sobjectType': 'GroupLabel__c' type let me know if you find any issue.

cmp

<aura:component controller="SeTesting" implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,forceCommunity:availableForAllPageTypes" 
        access="global" >
<aura:attribute name="pickListMap" type="map" default="{'Option1':['Child Option1','Grand Child option1'],'Option2':['Child Option1','Grand Child option1','Grand Child option2']}"/>
<aura:attribute name="parentList" type="list" default="['Option1','Option2']" />
<aura:attribute name="childList" type="list" default=""/>
 <aura:attribute name="PackTag" type="List"/>

<aura:handler name="init" value="{!this}" action="{!c.doInit}"/>

<div class="slds-box">
    <table class="slds-table slds-table_bordered slds-table_cell-buffer">
        <thead>
            <tr class="slds-text-title_caps">
                <th scope="col">
                    <div class="slds-truncate">S.No</div>
                </th>
                <th scope="col">
                    <div class="slds-truncate" title="Classify">Classify</div>
                </th>
                <th scope="col">
                    <div class="slds-truncate" title="Field">Field</div>
                </th>                    
            </tr>
        </thead>
        <tbody>               
                <aura:iteration items="{!v.PackTag}" var="item" indexVar="index">
                    <tr class="slds-text-title_caps" id="{!index}">
                        <td>
                            {!index}
                        </td>
                        <td>
                            <lightning:select aura:id="select"  name="{!index}" Class="slds-col slds-size_1-of-2 slds-p-horizontal_x-small" onchange="{! c.classifyChange }" value="{!item.ParentPicklist__c}">
                                <option value="-None-">-None-</option>
                                <aura:iteration items="{!v.parentList}" var="value">
                                    <option value="{!value}">{!value}</option>
                                </aura:iteration>
                            </lightning:select>
                        </td>
                        <td>
                            <lightning:select aura:id="select"  name="{!index}" Class="slds-col slds-size_1-of-2 slds-p-horizontal_x-small" onchange="{! c.onSelectChange }" value="{!item.ChildPicklist__c}">
                                <option value="-None-">-None-</option>
                                <aura:iteration items="{!v.childList}" var="value">
                                    <option value="{!value}">{!value}</option>
                                </aura:iteration>
                            </lightning:select>
                        </td>
                        <td>
                            {!v.body}
                        </td>
                        <td>
                            <!-- conditionally Display Add or Delete Icons if rowIndex is 0 then show Add New Row Icon else show delete Icon -->
                            <aura:if isTrue="{!index == 0}">
                                <a onclick="{!c.AddNewRow}">
                                    <lightning:icon iconName="utility:add" class="slds-icon slds-icon_small" size="small" alternativeText="add"/>
                                    <span class="slds-assistive-text">Add Icon</span>
                                </a>
                                <aura:set attribute="else">
                                    <a onclick="{!c.removeRow}" id="{!index}">
                                        <lightning:icon variant="error" iconName="utility:delete" class="slds-icon slds-icon_small" size="small" alternativeText="icon"/>
                                        <span class="slds-assistive-text">Delete Icon</span>
                                    </a>
                                </aura:set>
                            </aura:if>
                        </td>
                    </tr>
                </aura:iteration>

        </tbody>
    </table>
</div>
<div>
    <aura:iteration items="{!v.PackTag}" var="item" indexVar="index">
        {!item.ParentPicklist__c} --- {!item.ChildPicklist__c}
    </aura:iteration>
</div>

cmpController

({
doInit: function (component,event,helper) {       
  helper.AddgetnewObject(component);
},
AddNewRow : function(component, event, helper){
     helper.AddgetnewObject(component);
    //['Child Option1','Grand Child option1','Grand Child option2']
},
classifyChange : function(component, event, helper) {
     var pickListMap = component.get("v.pickListMap"),
         index = event.getSource().get("v.name"),
         RowItemList = component.get("v.PackTag"),
         currentrow = RowItemList[index],
         controllerValue = event.getSource().get("v.value");
    if (controllerValue != '-None-') {
         //get child picklist value
        var childValues = pickListMap[controllerValue];
        var childValueList = [];
        childValueList.push('-None-');
        for (var i = 0; i < childValues.length; i++) {
            childValueList.push(childValues[i]);
        }
        // set the child list
        currentrow.childList = childValueList;
        //component.set("v.childList", childValueList); 


    } else {
       currentrow.childList = ['-None-'];
        //component.set("v.childList", ['-None-']);

    }
    currentrow.ParentPicklist__c = controllerValue;
    RowItemList.splice(index, 1, currentrow);
    component.set("v.PackTag",RowItemList);
},
 onSelectChange : function(component, event, helper) {
     var index = event.getSource().get("v.name"),
         RowItemList = component.get("v.PackTag"),
         currentrow = RowItemList[index],
         selected = event.getSource().get("v.value");
     if(selected !== '-None-'){
         currentrow.ChildPicklist__c = selected;
         RowItemList.splice(index, 1, currentrow);
         component.set("v.PackTag",RowItemList);
     }
}

})

cmphelper

({
AddgetnewObject : function(component){
     var RowItemList = component.get("v.PackTag");
    RowItemList.push({
        'sobjectType': 'GroupLabel__c',
        'ParentPicklist__c':'',
        'ChildPicklist__c': ''
    });
    component.set("v.PackTag", RowItemList);
}
})