Dynamic Fields View in Lightning Component

Are you trying for dynamic fields view in Lightning Component then you are on the right place. I was having this requirement to get the fields of the object dynamically but this feature is not yet available in lighting so I have build it myself.

We will leverage $A.createComponents of lighting. In lighting if you want to add a div to the component then you need to create it as component.

Lets start with the code that we need to put in.

Component:
 <aura:component implements="force:appHostable,flexipage:availableForAllPageTypes" access="global" >  
   <aura:attribute name="fieldsMap" type="Map"/>  
   <aura:attribute name="outputFields" type="Aura.Component[]"/>  
   <aura:handler name="init" value="{!this}" action="{!c.doInit}"/>  
   <div class="slds-form slds-form_stacked">  
     {!v.outputFields}  
   </div>  
 </aura:component>  

In this component we are having two attributes one is to store the field & its value and second is to store the dynamic components. Map of fields will like this {"Name":"Numaan","Email":"mohd.numaanahmed@gmail.com"}.


Component Controller:

 ({  
   doInit : function(component, event, helper) {  
     helper.createComponents(component);  
   }  
 })  

Simple JS controller which contains doInit method. This is called on the intial load of the component. We will directly call the helper create component method. All our magic is happening in the helper.

Component Helper:

 ({
    createComponents : function(component) {
        
        var fieldsMap = component.get("v.fieldsMap");
        var fields = Object.keys(fieldsMap); 
        var newComponents = [];
        //Building the structure of component
        for(var i=0;i<fields.length;i++){
            newComponents.push(
                ["aura:HTML", {
                    tag: "div",
                    HTMLAttributes:{"class": "slds-form-element"}             
                }],
                ["aura:HTML", {
                    tag: "label",
                    HTMLAttributes:{"class": "slds-form-element__label"}    
                }],
                ["ui:outputText", {
                    "value": fields[i]
                }],
                ["aura:HTML", {
                    tag: "div",
                    HTMLAttributes:{"class": "slds-form-element__control"}    
                }],
                ["aura:HTML", {
                    tag: "input",
                    HTMLAttributes:{"type":"text","disabled":"true","class": "slds-input","placeholder":fieldsMap[fields[i]] }    
                }]
            );
        }
        
        //Creating the components in one shot
        $A.createComponents(newComponents,function(components, status, errorMessage){
                if (status === "SUCCESS") {
                    var outputFields = [];
                    
                    for(var i=0;i<components.length;i+=5){
                        var divComp = components[i];
                        var labelComp = components[i+1];
                        var outputComp = components[i+2];
                        var div2Comp = components[i+3];
                        var output2Comp = components[i+4];
                        
                        labelComp.set("v.body", outputComp);
                        div2Comp.set("v.body", output2Comp);
                        var tddd = [];
                        tddd.push(labelComp);
                        tddd.push(div2Comp);
                        divComp.set("v.body", tddd);
                        outputFields.push(divComp);
                    }
                    component.set("v.outputFields",outputFields);
                }
                else {
                    // Show error message
                    console.log("Error: ");
                    console.log(errorMessage);
                    
                }
            }
            ); 
 }
})

If you see in the above helper JS you will find that I am first building the structure and then creating the components. It is always a good practice to create the structure first and then call the $A.createComponent, by doing this you will increase the performance of your component onload. I have used the SLDS for styling.

Lightning App:

We will create a lighting app to test the component which we have built. I am passing the static fields and its value to the <c:DynamicFieldsView /> which we have created.



 <aura:application extends="force:slds">  
   <aura:attribute name="fieldsMap" type="Map" default="{'Name':'Numaan','Email':'mohd.numaanahmed@gmail.com','Phone':'7XXXXXXXX0'}"/>  
   <c:DynamicFieldsView fieldsMap="{!v.fieldsMap}"/>  
 </aura:application>  


Component Preview:





Pretty simple isn't it. Use the lightning design system to modify the look and feel of the component.


No comments:

Post a comment