You need to sign in to do that
Don't have an account?
Mee Sharma
Keep selected rows persistent in lightning datatable between two tabs
I have 2 lightning tabs, each of them have a lightning data table in it.
1.The first tab displays a search filter and displays options accordingly
2.Each tab has a checkbox and you can select the options.
3.The 2nd tab displays all the selected options from the first tab.
4.There is a remove button against each row in 2nd tab
Requirement is:-
when I select an option from first tab data table--> display automatically in 2nd tab. when I remove an option from 2nd tab datatable--> uncheck it simultaneously from first tab datatable also.
My issue is:- When I remove an option it is not reflecting in the first tab datatable. However when I reselect category(onChange of category) I am able to see the updated options. How do I achieve this without having to reselect the category each time?
My code:-
component
<aura:component controller="SitePlanController" implements="flexipage:availableForAllPageTypes" access="global">
<aura:handler name="init" value="{!this}" action="{!c.onInit}" />
<lightning:card>
<lightning:layout multipleRows="true">
<lightning:layoutItem size="9">
<lightning:layoutItem size="4" class="slds-m-left_large">
<lightning:tabset selectedTabId="{! v.selectedTabId}">
<lightning:tab label="Add options" id="AO_view" onactive="{! c.handleActiveAO }">
</lightning:tab>
<lightning:tab label="Selected options" id="SO_view" onactive="{! c.handleActiveSO }" >
</lightning:tab>
</lightning:tabset>
</lightning:layoutItem>
<aura:if isTrue="{!v.selectedTabId == 'AO_view'}">
<lightning:layoutItem size="1"></lightning:layoutItem>
<lightning:layoutItem size="2">
<lightning:select label="Category" aura:id="category_selector" class="slds-m-bottom_medium" onchange="{! c.onCategorySelect }" >
<option value="">Select Category</option>
<aura:iteration items="{! v.categories}" var="c">
<option value="{!c.Id}" selected="{!c.Id == v.categoryId}" >{!c.Display_Name__c}</option>
</aura:iteration>
</lightning:select>
</lightning:layoutItem>
<lightning:layoutItem size="1"></lightning:layoutItem>
<lightning:layoutItem size="3" class="slds-m-top_x-large">
<p>{! v.instruction}</p>
</lightning:layoutItem>
<lightning:layoutItem size="8">
<div class="slds-panel__body">
<lightning:datatable columns="{! v.tableFields }" data="{! v.options }" keyField="id"
onrowaction="{! c.showOptionDetail}" onrowselection="{! c.selectOption}"
selectedRows="{! v.selectedRows}" />
</div>
</lightning:layoutItem>
<lightning:layoutItem size="4">
<aura:if isTrue="{! v.option}">
<div
class="slds-panel slds-panel_docked slds-panel_docked-right slds-is-open slds-text-align_center slds-m-right_medium slds-m-top_large"
aria-hidden="false">
<p class="slds-text-body_regular">{! v.option.description}</p>
<img class="product_image slds-m-top_small" src="{!v.imgPrefixURL + v.option.imageId}" />
</div>
</aura:if>
</lightning:layoutItem>
<aura:set attribute="else">
<aura:if isTrue="{!v.selectedTabId == 'SO_view'}">
<lightning:layoutItem size="8">
<div class="slds-panel__body">
<lightning:datatable aura:id="AOTable" columns="{! v.tableFieldsSO }" data="{! v.allUserSelectedOptions }" keyField="id"
hideCheckboxColumn ="true" onrowaction="{! c.removeRow}" />
</div>
</lightning:layoutItem>
</aura:if>
</aura:set>
</aura:if>
</lightning:layoutItem>
</lightning:layout>
</lightning:card>
</aura:component>
Jscontroller
({
onInit: function (cmp, event, helper) {
helper.showCategories(cmp);
},
showOptionDetail: function (cmp, event, helper) {
var option = event.getParam("row");
cmp.set("v.option", option);
},
onCategorySelect: function (cmp, event, helper) {
var categoryId = cmp.find("category_selector").get("v.value");
cmp.set("v.categoryId", categoryId);
cmp.set("v.selectedcategoryId",categoryId);
if(categoryId){
var categories = cmp.get("v.categories");
var i=0;
while(categories[i].Id != categoryId){i++;}
cmp.set("v.instruction", categories[i].Instruction__c);
helper.showOptions(cmp, categoryId);
}else{
cmp.set("v.options", []);
cmp.set("v.instruction", "");
}
},
selectOption: function (cmp, event, helper) {
var categoryId = cmp.get("v.categoryId");
var allSelectedOptions = cmp.get("v.allSelectedOptions");
if(allSelectedOptions.length == 0){allSelectedOptions = [];}
// Get selected option Ids
var selectedRows = event.getParam("selectedRows");
console.log('c.selectop selectedRows'+selectedRows);
if(selectedRows.length == 0){
selectedRows = [];
}else{
var temp = [];
selectedRows.forEach(function(option){
temp.push(option.id);
});
selectedRows = temp;
}
//To get id of selected options
cmp.set("v.selectedRowsId",selectedRows);
//var c = cmp.get(v.selectedRowsId);
//console.log('selectedRowsId'+c);
// Replace options for current category with updated ones
var i=0;
while(i<allSelectedOptions.length && allSelectedOptions[i].categoryId != categoryId){i++;}
if(i<allSelectedOptions.length){
allSelectedOptions[i].categoryId = categoryId;
allSelectedOptions[i].options = selectedRows;
}else{
allSelectedOptions.push({categoryId: categoryId, options: selectedRows});
}
cmp.set("v.allSelectedOptions", allSelectedOptions);
var x = cmp.get('v.allSelectedOptions');
console.log('allSelectedOptions'+x)
},
//loads content when the Selected options tab is selected
handleActiveSO: function (cmp, event, helper) {
var s = cmp.get("v.selectedRowsId");
cmp.set("v.selectedTabId", 'SO_view');
helper.ShowAllUserSelectedoptions(cmp,s);
},
//loads content when the Add option tab is selected
handleActiveAO: function (cmp, event, helper) {
$A.get('e.force:refreshView').fire();
},
//handle remove row action in 'selected options' tab
removeRow: function (cmp, event, helper){
var action = event.getParam('action');
var actname = action.name;
var row = event.getParam('row');
var categoryId = cmp.get("v.categoryId");
if (actname === 'delete') {
helper.removeOption(cmp, row);
}
}
})
Helper method
({
showCategories: function (cmp) {
cmp.set("v.categories", categories);
}else {
$A.log("callback error", res.getError());
}
});
$A.enqueueAction(action);
},
showOptions: function (cmp, categoryId) {
var action = cmp.get("c.getOptions");
action.setParams({"categoryId": categoryId});
action.setCallback(this, function (res) {
var state = res.getState();
if (state === "SUCCESS") {
var options = res.getReturnValue();
cmp.set("v.options", options);
this.showSelectedOptions(cmp, categoryId);
}
$A.enqueueAction(action);
},
showSelectedOptions: function (cmp, categoryId) {
var allSelectedOptions = cmp.get("v.allSelectedOptions");
var i=0;
while(i<allSelectedOptions.length && allSelectedOptions[i].categoryId != categoryId){i++;}
if(allSelectedOptions[i] && allSelectedOptions[i].options){
cmp.set("v.selectedRows", allSelectedOptions[i].options);
}
var x = cmp.get("v.selectedRows");
},
ShowAllUserSelectedoptions: function(cmp,userselectedoptionIds){
var action = cmp.get("c.getallUserSelectedOptions");
action.setParams({"userselectedoptionIds": userselectedoptionIds});
action.setCallback(this, function (res) {
var state = res.getState();
if (state === "SUCCESS") {
var useroptions = res.getReturnValue();
cmp.set("v.allUserSelectedOptions", useroptions);
}e
removeOption: function (cmp, row) {
var removedrowid = row.id;
var rows = cmp.get('v.allUserSelectedOptions');
var AOrows = cmp.get('v.allSelectedOptions');
var SOrowId = cmp.get('v.selectedRows');
//remove row from 'selected options' tab
var rowIndex = rows.indexOf(row);
rows.splice(rowIndex, 1);
cmp.set('v.allUserSelectedOptions', rows);
//remove row from 'Add options' tab
for(var i = 0; i < SOrowId.length; i++){
if(SOrowId[i] == removedrowid){
SOrowId.splice(i, 1);
cmp.set("v.selectedRows", SOrowId);
cmp.set("v.selectedRowsId",SOrowId );
cmp.set("v.allSelectedOptions",SOrowId);
}
}
}
})
1.The first tab displays a search filter and displays options accordingly
2.Each tab has a checkbox and you can select the options.
3.The 2nd tab displays all the selected options from the first tab.
4.There is a remove button against each row in 2nd tab
Requirement is:-
when I select an option from first tab data table--> display automatically in 2nd tab. when I remove an option from 2nd tab datatable--> uncheck it simultaneously from first tab datatable also.
My issue is:- When I remove an option it is not reflecting in the first tab datatable. However when I reselect category(onChange of category) I am able to see the updated options. How do I achieve this without having to reselect the category each time?
My code:-
component
<aura:component controller="SitePlanController" implements="flexipage:availableForAllPageTypes" access="global">
<aura:handler name="init" value="{!this}" action="{!c.onInit}" />
<lightning:card>
<lightning:layout multipleRows="true">
<lightning:layoutItem size="9">
<lightning:layoutItem size="4" class="slds-m-left_large">
<lightning:tabset selectedTabId="{! v.selectedTabId}">
<lightning:tab label="Add options" id="AO_view" onactive="{! c.handleActiveAO }">
</lightning:tab>
<lightning:tab label="Selected options" id="SO_view" onactive="{! c.handleActiveSO }" >
</lightning:tab>
</lightning:tabset>
</lightning:layoutItem>
<aura:if isTrue="{!v.selectedTabId == 'AO_view'}">
<lightning:layoutItem size="1"></lightning:layoutItem>
<lightning:layoutItem size="2">
<lightning:select label="Category" aura:id="category_selector" class="slds-m-bottom_medium" onchange="{! c.onCategorySelect }" >
<option value="">Select Category</option>
<aura:iteration items="{! v.categories}" var="c">
<option value="{!c.Id}" selected="{!c.Id == v.categoryId}" >{!c.Display_Name__c}</option>
</aura:iteration>
</lightning:select>
</lightning:layoutItem>
<lightning:layoutItem size="1"></lightning:layoutItem>
<lightning:layoutItem size="3" class="slds-m-top_x-large">
<p>{! v.instruction}</p>
</lightning:layoutItem>
<lightning:layoutItem size="8">
<div class="slds-panel__body">
<lightning:datatable columns="{! v.tableFields }" data="{! v.options }" keyField="id"
onrowaction="{! c.showOptionDetail}" onrowselection="{! c.selectOption}"
selectedRows="{! v.selectedRows}" />
</div>
</lightning:layoutItem>
<lightning:layoutItem size="4">
<aura:if isTrue="{! v.option}">
<div
class="slds-panel slds-panel_docked slds-panel_docked-right slds-is-open slds-text-align_center slds-m-right_medium slds-m-top_large"
aria-hidden="false">
<p class="slds-text-body_regular">{! v.option.description}</p>
<img class="product_image slds-m-top_small" src="{!v.imgPrefixURL + v.option.imageId}" />
</div>
</aura:if>
</lightning:layoutItem>
<aura:set attribute="else">
<aura:if isTrue="{!v.selectedTabId == 'SO_view'}">
<lightning:layoutItem size="8">
<div class="slds-panel__body">
<lightning:datatable aura:id="AOTable" columns="{! v.tableFieldsSO }" data="{! v.allUserSelectedOptions }" keyField="id"
hideCheckboxColumn ="true" onrowaction="{! c.removeRow}" />
</div>
</lightning:layoutItem>
</aura:if>
</aura:set>
</aura:if>
</lightning:layoutItem>
</lightning:layout>
</lightning:card>
</aura:component>
Jscontroller
({
onInit: function (cmp, event, helper) {
helper.showCategories(cmp);
},
showOptionDetail: function (cmp, event, helper) {
var option = event.getParam("row");
cmp.set("v.option", option);
},
onCategorySelect: function (cmp, event, helper) {
var categoryId = cmp.find("category_selector").get("v.value");
cmp.set("v.categoryId", categoryId);
cmp.set("v.selectedcategoryId",categoryId);
if(categoryId){
var categories = cmp.get("v.categories");
var i=0;
while(categories[i].Id != categoryId){i++;}
cmp.set("v.instruction", categories[i].Instruction__c);
helper.showOptions(cmp, categoryId);
}else{
cmp.set("v.options", []);
cmp.set("v.instruction", "");
}
},
selectOption: function (cmp, event, helper) {
var categoryId = cmp.get("v.categoryId");
var allSelectedOptions = cmp.get("v.allSelectedOptions");
if(allSelectedOptions.length == 0){allSelectedOptions = [];}
// Get selected option Ids
var selectedRows = event.getParam("selectedRows");
console.log('c.selectop selectedRows'+selectedRows);
if(selectedRows.length == 0){
selectedRows = [];
}else{
var temp = [];
selectedRows.forEach(function(option){
temp.push(option.id);
});
selectedRows = temp;
}
//To get id of selected options
cmp.set("v.selectedRowsId",selectedRows);
//var c = cmp.get(v.selectedRowsId);
//console.log('selectedRowsId'+c);
// Replace options for current category with updated ones
var i=0;
while(i<allSelectedOptions.length && allSelectedOptions[i].categoryId != categoryId){i++;}
if(i<allSelectedOptions.length){
allSelectedOptions[i].categoryId = categoryId;
allSelectedOptions[i].options = selectedRows;
}else{
allSelectedOptions.push({categoryId: categoryId, options: selectedRows});
}
cmp.set("v.allSelectedOptions", allSelectedOptions);
var x = cmp.get('v.allSelectedOptions');
console.log('allSelectedOptions'+x)
},
//loads content when the Selected options tab is selected
handleActiveSO: function (cmp, event, helper) {
var s = cmp.get("v.selectedRowsId");
cmp.set("v.selectedTabId", 'SO_view');
helper.ShowAllUserSelectedoptions(cmp,s);
},
//loads content when the Add option tab is selected
handleActiveAO: function (cmp, event, helper) {
$A.get('e.force:refreshView').fire();
},
//handle remove row action in 'selected options' tab
removeRow: function (cmp, event, helper){
var action = event.getParam('action');
var actname = action.name;
var row = event.getParam('row');
var categoryId = cmp.get("v.categoryId");
if (actname === 'delete') {
helper.removeOption(cmp, row);
}
}
})
Helper method
({
showCategories: function (cmp) {
cmp.set("v.categories", categories);
}else {
$A.log("callback error", res.getError());
}
});
$A.enqueueAction(action);
},
showOptions: function (cmp, categoryId) {
var action = cmp.get("c.getOptions");
action.setParams({"categoryId": categoryId});
action.setCallback(this, function (res) {
var state = res.getState();
if (state === "SUCCESS") {
var options = res.getReturnValue();
cmp.set("v.options", options);
this.showSelectedOptions(cmp, categoryId);
}
$A.enqueueAction(action);
},
showSelectedOptions: function (cmp, categoryId) {
var allSelectedOptions = cmp.get("v.allSelectedOptions");
var i=0;
while(i<allSelectedOptions.length && allSelectedOptions[i].categoryId != categoryId){i++;}
if(allSelectedOptions[i] && allSelectedOptions[i].options){
cmp.set("v.selectedRows", allSelectedOptions[i].options);
}
var x = cmp.get("v.selectedRows");
},
ShowAllUserSelectedoptions: function(cmp,userselectedoptionIds){
var action = cmp.get("c.getallUserSelectedOptions");
action.setParams({"userselectedoptionIds": userselectedoptionIds});
action.setCallback(this, function (res) {
var state = res.getState();
if (state === "SUCCESS") {
var useroptions = res.getReturnValue();
cmp.set("v.allUserSelectedOptions", useroptions);
}e
removeOption: function (cmp, row) {
var removedrowid = row.id;
var rows = cmp.get('v.allUserSelectedOptions');
var AOrows = cmp.get('v.allSelectedOptions');
var SOrowId = cmp.get('v.selectedRows');
//remove row from 'selected options' tab
var rowIndex = rows.indexOf(row);
rows.splice(rowIndex, 1);
cmp.set('v.allUserSelectedOptions', rows);
//remove row from 'Add options' tab
for(var i = 0; i < SOrowId.length; i++){
if(SOrowId[i] == removedrowid){
SOrowId.splice(i, 1);
cmp.set("v.selectedRows", SOrowId);
cmp.set("v.selectedRowsId",SOrowId );
cmp.set("v.allSelectedOptions",SOrowId);
}
}
}
})