I'm trying to build a column filter component for a table where there can be multiple column filter can be specified.
When I click on the Add button, new filter item appears below. But if I delete the filter item using remove button, the actual object in the array is removed but it is not reflected in the view.
I tried couple of workarounds, but it doesn't work. I'm running out of options here.
Here's the code:
filterBox.cmp
<aura:component>
<aura:attribute name="columns" type="List" default="['Name','Email','Birthdate']" />
<aura:attribute name="operators" type="List" default="['less than','greater than','equal to']" />
<aura:attribute name="filters" type="List" default="[{'column':'','op':'','value':''}]" />
<div class="filter-box">
<aura:iteration items="{!v.filters}" var="filter" indexVar="index">
<div class="filter-item">
<ui:inputSelect value="{!filter.column}">
<aura:iteration items="{!v.columns}" var="column">
<ui:inputSelectOption label="{!column}" text="{!column}" />
</aura:iteration>
</ui:inputSelect>
<ui:inputSelect value="{!filter.op}">
<aura:iteration items="{!v.operators}" var="op">
<ui:inputSelectOption label="{!op}" text="{!op}" />
</aura:iteration>
</ui:inputSelect>
<ui:inputText value="{!filter.value}" />
<button type="button" onclick="{!c.addFilter}">Add</button>
<aura:if isTrue="{!index != 0}">
<button type="button" onclick="{!c.removeFilter}" data-index="{!index}">Remove</button>
</aura:if>
</div>
</aura:iteration>
</div>
</aura:component>
filterBoxController.js
({
addFilter : function(cmp, event, helper) {
var filters = cmp.get("v.filters");
filters.push({'column':'','op':'','value':''});
cmp.set("v.filters",filters);
console.log(cmp.get("v.filters"))
},
removeFilter : function(cmp, event, helper) {
var index = event.target.getAttribute('data-index');
var filters = cmp.get("v.filters");
filters.splice(Number(index),1);
console.log(filters,index);
cmp.set("v.filters",filters); // didn't work
cmp.set("v.filters",[].concat(filters)); // didn't work
cmp.set("v.filters",JSON.parse(JSON.stringify(filters))); // didn't work
}
})
FYI, I see the same behavior with locker service turned on and off as well.
Best Answer
This is a known issue with ui:inputSelectOption inside an aura:iteration. If you file a case you can reference the internal bug number W-3430029.
For now I'd see if you can structure your code to not use the ui:inputSelectOption inside your iteration.
I'll update this answer if I find a workaround for the issue.
Edit (12/2): A dirty workaround you can try is to destroy the last ui:inputSelect component in the list before removing the item from the array. For example, put an aura:id on each ui:inputSelect component and then do the following when you remove the row: