2

Problem facing: If I change a value in Lightning select.for example Iam changing particularly one row value. But automatically other row values also changing

Image 1 : Iam changing a lightning select value in one row . enter image description here

Image 2:I have changed first row value has payment master, Automatically It effects remaining row value also

enter image description here

 <aura:component controller="ActionController"  implements="force:hasRecordId,force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:lightningQuickAction" access="global">
<aura:attribute name="theId" type="String"/>
<aura:attribute name="options" type="String[]"/>
<aura:attribute name="wrplst" type="WrapperCriteria[]"/>
<aura:attribute name="option" type="List" />
<aura:attribute name="selectedValue" type="String"/>
<aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
<p>
    <b>Creating Action Criteria </b>
</p>
<h3 class="slds-section-title--divider">
    <I> Action Criteria</I>
</h3>
<table >
    <tr class="slds-text-title--caps">
        <th class="head">
            <I>Action</I>
        </th>
        <th class="head">
            <I>Object Name</I>
        </th>
        <th class="head">
            <I>Component</I>
        </th>
        <th class="head">
            <I>Operator</I>
        </th>
        <th class="head">
            <I>Special Operator</I>
        </th>
        <th class="head">
            <I>Special Operator * Value</I>
        </th>
        <th class="head">
            <I>Special Operator / Value</I>
        </th>
    </tr>
    <aura:iteration items="{!v.wrplst}" var="a">
        <tr>
            <td class="cell" >
                <p>
                    <button type="button" onclick="{!c.RemoveClick}">remove</button>
                </p>
            </td>
            <td class="cell" >
                <p>

                        <lightning:select name="mySelect" label=" " aura:id="mySelect" value="{!v.selectedValue}" onchange="{!c.dosomething}">
                            <aura:iteration items="{!v.options}" var="item">
                                <option text="{!item.label}" value="{!item.value}" selected="{!item.selected}"/>
                            </aura:iteration>
                        </lightning:select>

                </p>
            </td>
            <td class="cell" >
                <P>
                    <lightning:select name="select" label=" ">
                        <option value="">None</option>
                    </lightning:select>
                </P>
            </td>
            <td class="cell" >
                <p>
                    <lightning:select name="selectItem" label=" ">
                        <option value="None">None</option>
                        <option value="+ Addition">+ Addition</option>
                        <option value="- Subtract  ">- Subtract</option>
                        <option value="* Multiply ">* Multiply</option>
                        <option value="/ Divide">/ Divide</option>
                    </lightning:select>
                </p>
            </td>
            <td class="cell" >
                <p>
                    <lightning:select name="selectItem" label=" " >
                        <option value="None">None</option>
                        <option value="*">*</option>
                        <option value="*/">*/</option>
                        <option value="/">/</option>
                    </lightning:select>
                </p>
            </td>
            <td class="cell" >
                <p>
                    <ui:inputText value="{!a.specialOperatorValue}"/>
                </p>
            </td>
            <td class="cell" >
                <p>
                    <ui:inputText value="{!a.specialOperatorSlashValue}"/>
                </p>
            </td>
        </tr>
    </aura:iteration>
</table>
<lightning:button label="Add row" onclick="{!c.AddRow}" />

js:

  ({
doInit: function(component, event, helper) {
    helper.pageLoad(component);
    helper.optionval(component);
},
doSomething: function(component, event, helper) {
    alert('iam calling :::');
    var x = component.find("x").get("v.value");
    alert('x value ::::' + x);
},
RemoveClick: function(component, event, helper) {

},
AddRow: function(component, event, helper) {

    var comp1 = component.get("v.wrplst");
    var compJson1 = JSON.stringify(comp1);

    var addAction = component.get("c.addRow");
    addAction.setParams({
        "wrapval": compJson1
    });
    addAction.setCallback(this, function(res) {
        var state = res.getState();
        if (state == 'SUCCESS') {
            component.set("v.wrplst", res.getReturnValue());
        } else if (state == 'ERROR') {
            alert('error');
        } else if (state == 'INCOMPLETE') {
            alert('incompltete');
        }
    });
    $A.enqueueAction(addAction);
},
dosomething: function(component, event, helper) {
    var x = component.get("v.selectedValue");
    alert(x);
}

})

helper :

({

        pageLoad: function(component, event) {
    var action = component.get("c.pageLoading");
    var self = this;
    var Idx = component.get("v.theId");
    action.setParams({
        "id": Idx
    });
    action.setCallback(this, function(g) {
        var state = g.getState();
        if (state == 'SUCCESS') {
            component.set("v.wrplst", JSON.parse(g.getReturnValue()));
            self.Method2(component);
        }
    });
    $A.enqueueAction(action);
},
optionval: function(component, event, helper) {
    var opts = [{
            value: "",
            label: "None"
        },
        {
            value: "Pay_Element_Master__c",
            label: "Pay Element"
        },
        {
            value: "CTC_Master__c",
            label: "CTC Master"
        }
    ];
    component.set("v.options", opts);
},
Method2: function(component, event, helper) {
    var comp = component.get("v.wrplst");
    var compJson = JSON.stringify(comp);
    var Id1 = component.get("v.theId");
    var compAction = component.get("c.getComponent");
    compAction.setParams({
        "wrapval": compJson,
        "id": Id1,
    });
    compAction.setCallback(this, function(re) {
        var state = re.getState();
        if (state == 'SUCCESS') {
            console.log('success');
        }
    });
    $A.enqueueAction(compAction);
}

})

11
  • 1
    I just threw your code into my org and it worked fine.. – martin Mar 17 '17 at 12:46
  • 1
    I think your code will work....I think you are setting same aura:Id for other tags in your markup cmp.verify it – vignesh Mar 17 '17 at 20:22
  • Hi I updated the code please check it. I have tried like this also : var xval= component.find("obId").get("v.value"); but its shows error..I have copied and tried same code its working for me..but here itsnt working... – Annappa Mar 18 '17 at 4:46
  • 1
    I am confused, your first line says "in Lightning select its working." yet your title says it is not. You last comment says it shows error but then you say you have tried same code and its working for you. Then say here its not working. How can it be working yet not, and same code is but isn't???? – Eric Mar 18 '17 at 4:54
  • 1
    As others have said, that select in isolation works without issue. I just verified it on my end as well. If you cannot find another element with the id obId in your markup, Try commenting out all of your component elements except that one and see if it works (it should). then start adding back in until it breaks, then you will know what caused it. – Eric Mar 18 '17 at 5:02
0

Try this ;)

In the main component replace the aura:iteration with child component like:

<aura:iteration items="{!v.wrplst}" var="a" indexVar="i">
  <c:formFields options="{!v.options}" selectedValue="" />
</aura:iteration>

formFields.cmp Child Component

NOTE: I have added only select field add more as per the need.

<aura:component >
  <aura:attribute required="true" name="options" type="String[]"/>
  <aura:attribute required="true" name="selectedValue" type="String"/>

  <tr>
    <td class="cell" >
        <p>
            <!--  @todo implement RemoveClick in formFieldsController.js -->   
            <button type="button" onclick="{!c.removeClick}">remove</button>
        </p>
    </td>
    <td class="cell" >
        <p>
            <lightning:select name="mySelect" label=" " value="{!v.selectedValue}" onchange="{!c.selectChanged}">
                <aura:iteration items="{!v.options}" var="item">
                    <option text="{!item.label}" value="{!item.value}" selected="{!item.selected}"/>
                </aura:iteration>
            </lightning:select> 
        </p>
    </td>
  </tr>
</aura:component>

formFieldsController.js

({

  selectChanged: function(component, event, helper){
    var x = component.get("v.selectedValue");
    alert(x);
  },
  removeClick: function(component, event, helper){
    /**
     * @todo Implement functionality here.
     */
  }
})
1

I can see what the problem is here. Here is explanation of why it is behaving so->

As you are binding v.options aura attribute with lightning:select, as soon as you add new row, the lightning select of other row is also bound to the same v.options attribute.

Now if you change the select from UI in one of the data row, it will change the v.options by putting selected true in the selected option. As same v.options is connected by the second i.e. 'in your case all rows', that changed value in it will be reflected to all data rows.

This is why when you change select in one rows, others also get changed to the same value.

Soluton - >

Better solution would be to associate javascript attributes named options and selectedValue with the wrapper of each row. This will not hard bind options of each row with the v.options attribute. Something like tihs->

  1. Change this line of code in your component's cmp file->

TO

<lightning:select name="mySelect" label=" " aura:id="mySelect" value="{!v.wrplst.selectedValue}" onchange="{!c.dosomething}">
 <aura:iteration items="{!v.wrplst.options}" var="item">
    <option text="{!item.label}" value="{!item.value}" selected="{!item.selected}"/>
  </aura:iteration>
</lightning:select>
  1. Change this line of code in your controller file's add row function - >

    component.set("v.wrplst", res.getReturnValue());

TO

//I assume this returns a row of wrapper
var row = res.getReturnValue();

// this line will create copy of options and selectedvalue for each row
row['options'] = JSON.parse(JSON.stringify(comopnent.get('v.options')));
row['selectedValue'] = //what ever you want to select by default on first load of the screen from options.

// now set it in wrplist
var wrapperList = component.get('v.wrplst');
wrapperList.push(row);
component.set('v.wrplst',wrapperList);
  1. Change this line in your pageLoad helper method ->

    component.set("v.wrplst", JSON.parse(g.getReturnValue()));

TO

//I assume that this response g is returning a list of wrappers
var rowList = JSON.parse(g.getReturnValue());
rowList = rowList.map(function(row){
 row['options'] = JSON.parse(JSON.stringify(comopnent.get('v.options')));
 row['selectedValue'] = //what ever you want to select by default on first load of the screen from options.
 return row;
});
component.set('v.wrplst',rowList);

You may need some code changes in a way how to handle the select change, but this much will solve your query. You can email me on sawneyaman3@gmail.com for any query related to lightning development.

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.