1

I have a sample code which is independent of any data model for now. I am trying to display data from a JSON using <Aura:Iteration>. I have below two issues with my code:

  1. I do not see the value in <lightning:combobox> when I load the component for the first time. I am expecting to see Achme , John and Mark already populated in the combox. However I see the component like below. I seem to be missing something.

enter image description here

  1. How do I make the selected option from lightning comboBox update the DataList row value. For example if I select a new value - ABC from lightning combox , how can I update that value in the dataList.

  2. I have a change event on this component. However this change event is not detecting any change to the dataList change. Example when I change the Age value of one of the row, the change event does not trigger. I must be using it incorrectly mostly.

Here is the component:

<aura:component implements="lightning:availableForFlowScreens,force:appHostable">
<aura:attribute name="dataList" type="List"/>
    <aura:handler name="change" value="{!v.dataList}" action="{!c.handleDataListChange}"/>
    <aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
    <div class="slds-is-relative slds-scrollable" >
        <!-- MARKUP for the datatable-->
        <table class="slds-table slds-table--bordered " role="grid">
            <thead>
            <tr>
                <th class="slds-is-sortable slds-is-resizable slds-text-title_caps" scope="col">
                    <span class="slds-truncate" title="SegmentChannelName">Name</span>
                    <span class="slds-assistive-text" aria-live="assertive" aria-atomic="true"></span>
                </th>
                <th class="slds-is-sortable slds-is-resizable slds-text-title_caps" scope="col">
                    <span class="slds-truncate" title="Creative">Age</span>
                    <span class="slds-assistive-text" aria-live="assertive" aria-atomic="true"></span>
                </th>
                <th class="slds-is-sortable slds-is-resizable slds-text-title_caps" scope="col">
                    <span class="slds-truncate" title="Channel Start">State</span>
                    <span class="slds-assistive-text" aria-live="assertive" aria-atomic="true"></span>
                </th>
            </tr>
            </thead> 
            <tbody>
                <aura:iteration items="{!v.dataList}" var="row" indexVar="index">
                    <tr onchange="{!c.handleRowChange}">
                        <td role="gridcell">
                            <lightning:combobox aura:id="picklist"
                                                label="Names"
                                                required="true"
                                                variant="label-hidden"
                                                value="{!row.data.Name}"
                                                options="{!row.Names}"/>
                        </td>
                        <td role="gridcell">
                            <ui:inputText class="slds-cell-wrap" value="{!row.data.Age}"/>
                        </td>
                        <td role="gridcell">
                            <ui:inputText class="slds-cell-wrap" value="{!row.data.State}"/>
                        </td> 
                        <td role="gridcell">
                            <ui:inputDate displayDatePicker="true"
                                          class="slds-input"
                                          disabled="false"
                                          updateOn = "change"
                                          value= "{!row.data.Date}"
                                          format="MM/dd/yyyy"/>
                        </td>
                    </tr>
                </aura:iteration>
            </tbody>
        </table>
    </div>

</aura:component>

Controller:

({
     doInit : function(component, event, helper) {
         const json = '[{"data": {"Name": "Acme","Age": "34","State": "TX","Date" : "2020-01-24"},"Names": [{"label": "Acme","value": "Acme"},{"label": "ABC","value": "abc"},{"label": "XYZ","value": "XYZ"}],"RecordTypeName": "Manager"},{"data": {"Name": "John","Age": "21","State": "NY","Date" : "2020-01-24"},"Names": [{"label": "MNM","value": "MNM"},{"label": "TTT","value": "TTT"},{"label": "John","value": "John"}],"RecordTypeName": "Employee"},{"data": {"Name": "Mark","Age": "23","State": "CA","Date" : "2020-01-24"},"Names": [{"label": "Mark","value": "Mark"},{"label": "CD","value": "CD"},{"label": "BD","value": "BD"}],"RecordTypeName": "Employee"}]';
         const obj = JSON.parse(json);
         component.set('v.dataList', obj);
         console.log('dataList === ' + JSON.stringify(component.get('v.dataList')));
     },
    handleDataListChange : function(component, event, helper) {
        console.log('handleDataListChange ==== > ');
    },
    handleRowChange : function(component, event, helper) {
        console.log('handleRowChange ==== > ');
    }    
})

Update:

Based on the answer I update my code and was able to find the solution for point 1 and 2.

I have a new question related invoking the OnChange attribute- I introduced a new Date field in the datalist column. My issue now is the handleRowChange event is not triggering when I change the dates. However it trigger when I change the comboBox or a text field. I tried using updateOn attribute for ui:inputDate however that did not help.

Is there a way to invoke the onChange handler method- handleRowChange when I change the value in ui:inputDate?

enter image description here

2
  1. Your not setting the value attribute for your options, it should be below format

       [{ value: "abc", label: "ABC" },{ value: "xyz", label: "XYZ" }]
    
  2. your Name value is not existing in to your options that's why it's not selected default, in your below Json data Acme is not existing options(Acme not equal abc/xyz).

    {
    "data": {"Name": "Acme","Age": "34","State": "TX"},  //Acme is 
    "Names": [{"label": "ABC"},{"label": "XYZ"}],
    "RecordTypeName": "Manager"
    }
    
  3. i would recommend go through lightning combo box , you need to use onchange event like like onchange="{! c.handleChange }" to update the datalist with selected value.

  4. ---Update with onchange Event-- i don't recommenced to use UI controls because UI name space going to be retired in summer 21 . i added onchange event componenet level not in tr level. here is tested code befor change

after change after change

cmp:

<aura:attribute name="dataList" type="List"/>
    <aura:attribute name="changedrow" type="List"/>
    <!--<aura:handler name="change" value="{!v.dataList}" action="{!c.handleDataListChange}"/>-->
    <aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
    <div class="slds-is-relative slds-scrollable" >
        <!-- MARKUP for the datatable-->
        <table class="slds-table slds-table--bordered " role="grid">
            <thead>
            <tr>
                <th class="slds-is-sortable slds-is-resizable slds-text-title_caps" scope="col">
                    <span class="slds-truncate" title="SegmentChannelName">Name</span>
                    <span class="slds-assistive-text" aria-live="assertive" aria-atomic="true"></span>
                </th>
                <th class="slds-is-sortable slds-is-resizable slds-text-title_caps" scope="col">
                    <span class="slds-truncate" title="Creative">Age</span>
                    <span class="slds-assistive-text" aria-live="assertive" aria-atomic="true"></span>
                </th>
                <th class="slds-is-sortable slds-is-resizable slds-text-title_caps" scope="col">
                    <span class="slds-truncate" title="Channel Start">State</span>
                    <span class="slds-assistive-text" aria-live="assertive" aria-atomic="true"></span>
                </th>
            </tr>
            </thead> 
            <tbody>
                <aura:iteration items="{!v.dataList}" var="row" indexVar="index">
                    <tr>
                        <td role="gridcell">
                            <lightning:combobox aura:id="Nameid"
                                                label="Names"
                                                required="true"
                                                name="{!'' +'Nameid=>'+index}"
                                                variant="label-hidden"
                                                value="{!row.data.Name}"
                                                options="{!row.Names}"
                                                onchange="{!c.rowaction}"/>
                        </td>
                        <td role="gridcell">
                            <lightning:input aura:id="ageid" class="slds-cell-wrap" name="{!'' +'Ageid=>'+index}" value="{!row.data.Age}" onchange="{!c.rowaction}"/>
                        </td>
                        <td role="gridcell">
                            <lightning:input class="slds-cell-wrap" aura:id="stateid" name="{!'' +'Stateid=>'+index}" value="{!row.data.State}" onchange="{!c.rowaction}"/>
                        </td>
                    </tr>
                </aura:iteration>
            </tbody>
        </table>

        <lightning:card title="changed row">
       <aura:iteration items="{!v.changedrow}" var="row" indexVar="index">
           <p><lightning:formattedText value="{!row.data.Name}"/></p>
           <p><lightning:formattedText value="{!row.data.Age}"/></p>
           <p><lightning:formattedText value="{!row.data.State}"/></p>
            </aura:iteration>

    </lightning:card>
    </div>

controller:

 doInit : function(component, event, helper) {
    const json = '[{"data": {"Name": "Acme","Age": "34","State": "TX"},"Names": [{"label": "Acme","value": "Acme"},{"label": "ABC","value": "abc"},{"label": "XYZ","value": "XYZ"}],"RecordTypeName": "Manager"},{"data": {"Name": "John","Age": "21","State": "NY"},"Names": [{"label": "MNM","value": "MNM"},{"label": "TTT","value": "TTT"},{"label": "John","value": "John"}],"RecordTypeName": "Employee"},{"data": {"Name": "Mark","Age": "23","State": "CA"},"Names": [{"label": "Mark","value": "Mark"},{"label": "CD","value": "CD"},{"label": "BD","value": "BD"}],"RecordTypeName": "Employee"}]';
    const obj = JSON.parse(json);
    component.set('v.dataList', obj);
    console.log('dataList === ' + JSON.stringify(component.get('v.dataList')));
},
rowaction: function(component, event, helper){
    var index = event.getSource().get("v.name");
    var idAndindex = event.getSource().get("v.name").split("=>"),
        datalist = component.get('v.dataList'),
        changedvalue = event.getSource().get("v.value"),
        currentrow = datalist[idAndindex[1]];
    switch (idAndindex[0]){
        case 'Nameid':
            currentrow.Name = changedvalue;
            break;
        case 'Ageid':
            currentrow.Age = changedvalue;
            break;
        case 'Stateid':
            currentrow.State = changedvalue;
            break;
    }
    var changedrows = [].concat(currentrow);
    component.set("v.changedrow",changedrows);
    datalist.splice(idAndindex[1] ,1, currentrow);

    component.set("v.dataList",datalist);

},
| improve this answer | |
  • Ah thats right. I am trying this out. However i see that if i add onchange event with <tr> tag , i noticed that the onchange method does not get invoked when i update the Age / State field but gets invoked when i change the lightning comboBox. Could this be because it is text field? The OnChange event is on <tr> tag. – SfdcBat Jan 14 at 23:39
  • The onChange event is trigger on change of ui inputText , but does not trigger when I change the date value on ui inputDate – SfdcBat Jan 15 at 17:36
  • up dated my answer with tested code, let me know if had any issues – sdandamud1 Jan 15 at 18:07
  • If you see my updated code, I have an onChange attribute on <tr> tag. Are you suggesting to use OnChange on each of the field? My problem with using onChange on <tr> level is it does not detect changes to ui:inputDate field but it detects for every other field. – SfdcBat Jan 15 at 18:16
  • 1
    i haven't tested with ui:inputDate but it's working if i use <lightning:input type="date" in my above code – sdandamud1 Jan 15 at 18:33

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.