0

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);

    } 
})

closed as unclear what you're asking by Brian Mansfield, battery.cord, Himanshu, glls, Santanu Boral Sep 12 '17 at 22:19

Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • 2
    This is not how Lightning is meant to be used. You should not be trying to inject HTML directly into components. You would have a far easier time of it if you'd use lightning:layout and lightning:layoutItem instead. – sfdcfox Sep 12 '17 at 18:30
1

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.

<aura:application extends="force:slds">
    <aura:attribute name="page" type="String[]" default="[]" />
    <aura:attribute name="items" type="String[]" default="[]" />
    <aura:attribute name="rows" type="Integer" default="3" />
    <aura:attribute name="columns" type="Integer" default="3" />
    <aura:attribute name="colSize" type="Integer" default="4" />
    <aura:attribute name="pageNumber" type="Integer" default="1" />
    <aura:attribute name="maxPage" type="Integer" default="9" />

    <aura:handler name="init" value="{!this}" action="{!c.init}" />

    <lightning:input onchange="{!c.updateView}" value="{!v.columns}" type="range" min="1" max="6" label="Columns" name="cols" />
    <lightning:input onchange="{!c.updateView}" value="{!v.rows}" type="range" min="1" max="12" label="Rows" name="rows" />
    <lightning:input onchange="{!c.updateView}" value="{!v.pageNumber}" type="range" min="1" max="{!v.maxPage}" label="Page" name="pageNumber" />

    <lightning:layout horizontalAlign="spread" multipleRows="true">
        <aura:iteration items="{!v.page}" var="pageItem">
            <lightning:layoutItem size="{!v.colSize}">
                Item: {!pageItem}
            </lightning:layoutItem>
        </aura:iteration>
    </lightning:layout>
</aura:application>

({
    init: function(component, event, helper) {
        var items = [];
        while(items.length<100) {
            items.push(items.length+'');
        }
        component.set("v.items", items);
        var page = items.slice(0, 9);
        component.set("v.page", page);
        console.log(page);
    },
    updateView: function(component, event, helper) {
        var items = component.get("v.items"), cols = component.get("v.columns"),
            pageNum = component.get("v.pageNumber"), rows = component.get("v.rows"), 
            size = rows*cols, colSize = Math.floor(12/cols), 
            maxPage = Math.floor((items.length+(size-1))/size),
            page = items.slice((pageNum-1)*size, pageNum*size);
        component.set("v.page", page);
        component.set("v.colSize", colSize);
        component.set("v.maxPage", maxPage);
    }
})
  • Thanks, for the help @sfdcfox, I have not been able to work on it, but I will shortly and provide the updates – parth Sep 14 '17 at 18:55

Not the answer you're looking for? Browse other questions tagged or ask your own question.