I have built a component that will accept a user input for dimensions for the size of a table they desire, and then the component will pull image URL's from an object that have been added and display them in a table. I have added a functionality of where the user can click through multiple images using the next/previous buttons. The way I have written the component is that the majority of the work is done in the controller. I want to be able to perform this same functionality but where the table is displayed through the component instead, where I will be able to move it towards using the lightning:grid instead of a data table. I have copied the code below so you can see what I am doing.
I am basically having trouble on how to write a nested aura:iteration statement with a table to where the user can dynamically change the size of the table, or I am thinking of the approach in the wrong direction.
Component
<aura:component controller="imageUrlDisplay" >
<!-- attributes -->
<aura:attribute name="imageHolder" type="Object" />
<aura:attribute name="imgList" type="List"/>
<aura:attribute name="recordId" type="String" />
<aura:attribute name="totalImages" type="Integer" />
<aura:attribute name="pageCounter" type="Integer" />
<aura:attribute name="rows" type="Integer" />
<aura:attribute name="cols" type="Integer" />
<aura:attribute name="maxPage" type="Integer"/>
-->
<!-- this is for a fancyish header for the page -->
<lightning:card title="Tables">
<!-- This is for the user to input how many rows and columns is desired -->
<ui:inputText aura:id="cols" label="Enter Number of Columns" value="{!v.cols}"/>
<ui:inputText aura:id="rows" label="Enter Number of Rows" value="{!v.rows}"/>
<ui:button label="Submit" press="{!c.doInit}"/>
<div aura:id="target-div">
</div>
<br/>
<ui:button aura:id="previous" label="Previous" press="{!c.prevClicked}"/>
<ui:button aura:id="next" label="Next" press="{!c.nextClicked}"/>
</lightning:card>
</aura:component>
Controller
({
doInit : function(component, event, helper) {
// variables
var recId;
var action = component.get("c.getImgUrl");
var table = '';
var rows = component.get("v.rows");
var cols = component.get("v.cols");
var displayNumber = rows * cols;
// var imgList;
var pageCounter=1;
var tableImageCounter =0;
// setting value to recId
action.setParams({
recordId:recId
});
//All actions for the table are in this block of code
action.setCallback(this, function(response){
//sets all the url values into the variable which is being used as a list
var imgList = response.getReturnValue();
var keys = Object.keys(imgList);
var totalImages = keys.length;
console.log(totalImages);
//for loops to populate table correctly
for(var r=0; r<rows; r++){
console.log("In first for loop");
table +='<tr>';
for(var c =1; c<= cols; c++){
// to insure incrementing of the images is done properly regardless of table demensions
console.log("In second");
table +='<td >' + '<img src='+ '"' + imgList[tableImageCounter].imageUrlRich__c + '"' + 'style=' + '"'+'width:42px;height:42px;border:1px;'+'"'+ + '/>'+ '</td>';
if(cols>rows){
tableImageCounter++;
}
else if(rows>cols){
tableImageCounter++;
}
else if(rows==cols){
tableImageCounter++;
}
}
// to insure incrementing of the images is done properly regardless of table demensions
table +="</tr>"
}
var codeContent = '<table class=' +'"'+'slds-table slds-table_bordered slds-table_cell-buffer'+'"'+'>' + table + '</table>';
component.find('target-div').getElement().innerHTML = codeContent;
component.set("v.pageCounter", pageCounter);
component.set("v.imgList", imgList);
component.set("v.totalImages", totalImages);
});
$A.enqueueAction(action);
console.log("Got to enqueue");
},
nextClicked : function(component, event, helper){
var table = '';
var rows = component.get("v.rows");
var cols = component.get("v.cols");
var displayNumber = rows * cols;
var imgList = component.get("v.imgList");
var pageCounter = component.get("v.pageCounter");
pageCounter++;
var totalImages = component.get("v.totalImages");
var maxPage;
var tableImageCounter;
maxPage = totalImages/displayNumber;
if((totalImages%displayNumber) != 0){
maxPage++;
}
if(pageCounter == 2){ tableImageCounter = displayNumber+1;}
if(pageCounter > 2){tableImageCounter = ((pageCounter *displayNumber)-displayNumber)+1;}
// stops it from breaking where the pages exceeds number of items to display.
if(pageCounter >= maxPage){tableImageCounter = (maxPage * displayNumber)-displayNumber+1;}
//for loops to populate table correctly
for(var r=0; r<rows; r++){
console.log("In first for loop from next click");
table +='<tr>';
for(var c =1; c<= cols; c++){
// to insure incrementing of the images is done properly regardless of table demensions
console.log("In second from next click");
if(imgList[tableImageCounter] == null){
var btn = event.getSource();
btn.set("v.disabled", true);
break;
}
table +='<td >' + '<img src='+ '"' + imgList[tableImageCounter].imageUrlRich__c + '"' + 'style=' + '"'+'width:42px;height:42px;border:1;'+'"'+ + '/>'+ '</td>';
if(cols>rows){
tableImageCounter++;
}
// to insure incrementing of the images is done properly regardless of table demensions
else if(rows>cols){
tableImageCounter++;
}
else if(rows==cols){
tableImageCounter++;
}
}
table +="</tr>";
}
if(pageCounter != 1){
var btn = component.find("previous");
btn.set("v.disabled", false);
}
var codeContent = '<table class=' +'"'+'slds-table slds-table_bordered slds-table_cell-buffer'+'"'+'>' + table + '</table>';
component.find('target-div').getElement().innerHTML = codeContent;
console.log("Got to enqueue from nextClicked");
component.set("v.pageCounter", pageCounter);
component.set("v.maxPage", maxPage);
},
prevClicked : function(component, event, helper){
var table = '';
var rows = component.get("v.rows");
var cols = component.get("v.cols");
var displayNumber = rows * cols;
var imgList = component.get("v.imgList");
var pageCounter = component.get("v.pageCounter");
pageCounter--;
var tableImageCounter;
var maxPage = component.get("v.maxPage");
if(pageCounter > 2){ tableImageCounter = ((pageCounter *displayNumber)-displayNumber)+1;}
if(pageCounter == 2){tableImageCounter = ((displayNumber+1));}
if(pageCounter <2){tableImageCounter=0;}
//for loops to populate table correctly
for(var r=0; r<rows; r++){
console.log("In first for loop from next click");
table +='<tr>';
for(var c =1; c<= cols; c++){
// to insure incrementing of the images is done properly regardless of table demensions
if(pageCounter == 1){
var btn = event.getSource();
btn.set("v.disabled", true);
}
console.log("In second from next click");
table +='<td >' + '<img src='+ '"' + imgList[tableImageCounter].imageUrlRich__c + '"' + 'style=' + '"'+'width:42px;height:42px;border:1;'+'"'+ + '/>'+ '</td>';
if(cols>rows){
tableImageCounter++;
}
// to insure incrementing of the images is done properly regardless of table demensions
else if(rows>cols){
tableImageCounter++;
}
else if(rows==cols){
tableImageCounter++;
}
}
table +="</tr>"
}
if(pageCounter < maxPage){
var btn = component.find("next");
btn.set("v.disabled", false);
}
var codeContent = '<table class=' +'"'+'slds-table slds-table_bordered slds-table_cell-buffer'+'"'+'>' + table + '</table>';
component.find('target-div').getElement().innerHTML = codeContent;
component.set("v.pageCounter", pageCounter);
}
})
Best Answer
Here's a very rough design that does what you want it to, mostly. It's got a few hiccups that need to be sorted out, but this should get you started.