2

I add/remove rows dynamically in Lightning component. First row shows by default with plus button. Onclick plus button - adds row 2,3,4,etc., On first row Project picklist loads with values. But on 2nd, 3rd rows picklist value is not loading even though i call the same function which returns picklist value on the first row.

enter image description here

  <td>
     <div class="slds-select_container">
     <ui:inputSelect  aura:id="projectId"   class="slds-select"/>
     </div>
  </td>

 getemployeeProjects: function(component) {

   var parentId = component.get("v.userEmpRecdId");

    var action = component.get("c.getEmpProject");

    action.setParams({
        "empRecdId": parentId
    });
    var opts = [];
    action.setCallback(this, function(response) {
        console.log('test === pick'+JSON.stringify(response.getReturnValue()));
         var allValues = response.getReturnValue();

        if (response.getState() == "SUCCESS") {
            var allValues = response.getReturnValue();

            if (allValues != undefined && allValues.length > 0) {
                opts.push({
                    class: "optionClass",
                    label: "--- None ---",
                    value: ""
                });
            }
            for (var i = 0; i < allValues.length; i++) {
                opts.push({
                    class: "optionClass",
                    label: allValues[i],
                    value: allValues[i]
                });
            }
            console.log('test opts=='+opts);
            component.find('projectId').set("v.options", opts);

       }
    });
    $A.enqueueAction(action);
},

I get the below warning message in the console. Please help me fix the issue. enter image description here

  • 1
    You may have to use a separate component for picklist. which is used as a child component in the iteration. – Venky Jan 17 '18 at 5:42
1

The problem with your code is in line

component.find('projectId').set("v.options", opts);

When you have a single row then there is only one ui:input select with id as "projectId" so when you do component.find('projectId') it will return a object. on which you can set or get options value.

Now in 2nd case when you have multiple rows there are multiple ui:inputSelect components with aura:id as "projectid" so when you do component.find('projectId') it will return a array of objects.

Now if you want to append only one row at once you can just change component.find('projectId').set("v.options", opts); with

var inputSelects = component.find('projectId');
if(inputSelects && !Array.isArray(inputSelects)){
   inputSelects.set('v.options',opts);
} else if (Array.isArray(inputSelects)) {
  inputSelects[inputSelects.length-1].set('v.options',opt)
}
  • thank you. This works for my scenario. Appreciated your help. – user51204 Jan 17 '18 at 18:15
  • you can up vote my answer if it is correct :p – Manjot Singh Jan 18 '18 at 14:08
  • i couldn't do it... reason I need more reputation to vote it... sorry for that.. i had accepted your answer. – user51204 Jan 18 '18 at 18:42
2

You're only setting the options list on the first set of parameters. Instead, you should bind the options parameter and set it as an attribute:

<aura:attribute name="projectOptionList" type="Object[]" default="[{ label: '-- Loading --', value: ''}]" />

...

 <ui:inputSelect  aura:id="projectId"   class="slds-select" options="{!v.projectOptionList}" />

...

component.set('v.projectOptionList', opts);

This will allow the list to work on all of the rows at once.


Demo code:

<aura:application extends="force:slds">
    <aura:attribute name="items" type="List" default="[]" />
    <aura:attribute name="options" type="List" default="[{label:'-- Default --'}]" />

    <aura:iteration items="{!v.items}" var="item">
        <ui:inputSelect options="{!v.options}" label="Item" />
    </aura:iteration>
    <ui:button press="{!c.addOption}" label="Add Option" />
    <ui:button press="{!c.addItem}" label="Add Item" />
</aura:application>

({
    addOption: function(component, event, helper) {
        var opts = component.get("v.options");
        opts.push({label: 'Option '+(opts.length+1), value: 'opts.length' });
        component.set("v.options", opts);
    },
    addItem: function(component, event, helper) {
        var items = component.get("v.items");
        items.push({});
        component.set("v.items", items);
    }
})
  • Thanks for your response. The above idea didn't work. When i select a value on first row the same value applied on all other rows. Requirements is i need to select different project in each rows. Project 1, Project 2 ,etc... – user51204 Jan 17 '18 at 6:10
  • @user51204 Then you did something wrong. I literally wrote up an example that skips the server-side call, but can dynamically add rows and new options. Try it out and see. – sfdcfox Jan 17 '18 at 6:18
  • @user51204 Based on your edited comment, check your "value" attribute. You've possibly bound the same value to each row item. This is different than what this answer addresses. – sfdcfox Jan 17 '18 at 6:20

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.