Create an Indicator Badge Lightning Component

Now that we've laid the groundwork for our indicator badges on the server, let's get to the fun part: making our indicators show up for ZBS users.

Create a Badge Component

We've built an outer component to hold our indicators, but we still need to fill it with something. Let's build a Lightning component that we use to show individual indicator badges.

  1. In the Developer Console, select File > New > Lightning Component
  2. Name the component IndicatorBadge and click Submit
  3. Replace the generated code with this code:
    <aura:component >
      <aura:attribute name="badge" type="Object" />
      <lightning:icon iconName="{!v.badge.icon}" class="{! 'slds-box slds-box_x-small slds-align_absolute-center slds-size__1-of-1 '+v.badge.color}" alternativeText="{!v.badge.label}" />
    </aura:component>
  4. Click STYLE in the component palette on the right and replace the contents with this code:
    .THIS.DeepPink {
      background-color: deeppink;
    }
    .THIS.DeepSkyBlue{
      background-color: deepskyblue;
    }
    .THIS.LimeGreen{
      background-color: limegreen;
    }
    .THIS.Gold{
      background-color: gold;
    }
    .THIS.Red{
      background-color: red;
    }
    .THIS.RosyBrown{
      background-color: rosybrown;
    }
    .THIS.Tomato{
      background-color: tomato;
    }
    .THIS.Turquoise{
      background-color: darkturquoise;
    }
    .THIS.Violet{
      background-color: violet;
    }
    .THIS.YellowGreen{
      background-color: yellowGreen;
    }
    .THIS{
      height: 3rem;
      width: 3rem;
    }
  5. Code Highlights:

  • The IndicatorBadge.css markup allows us to match the background color of the indicator to the picklist values of our custom metadata type's Badge Color field. It also uses some relative sizing to keep our badges square.
  • The IndicatorBadge uses a lightning:icon base component to create individual icon badges. This component provides all the Lightning Design System icons at your fingertips. We’re passing the name of the Indicator Badge record (using the MasterLabel field value from our custom metadata record) into the alternativeText attribute to provide consistent information to ZBS users who may be using assistive technology.

Modify Indicator Badges Markup and Optimize Logic

We need to update our IndicatorBadges component to embed our new IndicatorBadge component, and make sure our controller and helper are optimized to handle the new functionality.

  1. Navigate to the IndicatorBadges component. Replace <!--Indicator Badge here--> with this code:
    <c:IndicatorBadge badge="{!thisBadge}" />
  2. Now we need to update our controller and helper logic, too.
  3. Click CONTROLLER in the component palette on the right and replace the contents with this code:
    ({
      doInit : function(component, event, helper) {
        var recId = component.get("v.recordId");
        var sObj = component.get("v.sObjectName");
        if(sObj){
          helper.getLabelForRecord(component, sObj);
          helper.getBadgesForRecord(component, recId, sObj);
        }
      },
      //future code here
    })
  4. Click HELPER in the component palette on the right and replace //future code here with this code:
     getBadgesForRecord : function(component, recId, sObj) {
        var action = component.get("c.getIndicators");
        action.setParams({
          recId : recId,
          objectName : sObj
        });
        action.setCallback(this, function(response){
          var state = response.getState();
          if(state === "SUCCESS"){
            var badges = response.getReturnValue();
            component.set("v.badgeList", badges);
          } else if (state === "ERROR"){
            console.log('Error: ' + JSON.stringify(response.error));
          } else {
            console.log('Unknown problem, state: ' + state + ', error: ' + JSON.stringify(response.error));
          }
        });
        $A.enqueueAction(action);
      },
      //future code here
  5. We need to also update the getLabelForRecord method to respond to the changes in our controller. Replace the existing method with the following code:
     getLabelForRecord : function(component, sObj){
        if(!component.get("v.objLabel")){
          var action = component.get("c.getSObjectLabel");
          action.setParams({
            sObjName : sObj
          });
          action.setCallback(this, function(response){
            var state = response.getState();
            if(state === "SUCCESS"){
              var label = response.getReturnValue();
              component.set("v.objLabel", label);
            } else if(state === "ERROR"){
              console.log('Error: ' + JSON.stringify(response.error));
            } else {
              console.log('Unknown problem, state: '+ state + ', error: ' + JSON.stringify(response.error));
            }
          });
          $A.enqueueAction(action);
        }
      },
  6. Your completed helper should now look like this:
    ({
      getLabelForRecord : function(component, sObj){
        if(!component.get("v.objLabel")){
          var action = component.get("c.getSObjectLabel");
          action.setParams({
            sObjName : sObj
          });
          action.setCallback(this, function(response){
            var state = response.getState();
            if(state === "SUCCESS"){
              var label = response.getReturnValue();
              component.set("v.objLabel", label);
            } else if(state === "ERROR"){
              console.log('Error: ' + JSON.stringify(response.error));
            } else {
              console.log('Unknown problem, state: '+ state + ', error: ' + JSON.stringify(response.error));
            }
          });
          $A.enqueueAction(action);
        }
      },
      getBadgesForRecord : function(component, recId, sObj) {
        var action = component.get("c.getIndicators");
        action.setParams({
          recId : recId,
          objectName : sObj
        });
        action.setCallback(this, function(response){
          var state = response.getState();
          if(state === "SUCCESS"){
            var badges = response.getReturnValue();
            component.set("v.badgeList", badges);
          } else if (state === "ERROR"){
            console.log('Error: ' + JSON.stringify(response.error));
          } else {
            console.log('Unknown problem, state: ' + state + ', error: ' + JSON.stringify(response.error));
          }
        });
        $A.enqueueAction(action);
      },
      //future code here
    })
  7. Click File > Save All.
  8. In Salesforce, click the Account tab and select the API First Communications record. Our Account Indicators got a lot more exciting, didn't they?

    API First Communications account detail
  9. Click the Contacts tab, and select Gerta Pickles from the Recently Viewed Contacts related list and refresh your browser. Wow! Now we're getting somewhere.

    Gerta Pickles contact detail

Code Highlights:

  • The doInit method in our controller file is now calling two distinct functions: getLabelForRecord and getBadgesForRecord. This level of complexity (i.e., calling multiple functions synchronously) is only supported in Lightning by leveraging a helper class.
  • We're making two calls to the server (instead of combining everything into one call) in order to keep our component's title markup displaying correctly, even when a record has no Indicators to display.
  • In order to not make extraneous calls to the server, we've modified our getLabelForRecord helper method to only call the server if the objLabel attribute hasn't already been populated with valid data.
  • We use aura:iteration, and pass the entire Indicator object to our IndicatorBadge component, rather than breaking out individual attributes. Because we added the @AuraEnabled tag to attributes in our Indicator inner class, we can use dot notation from within our component and reference those values.

Indicator Badge All The Things!

We've added our component onto the Account and Contact record pages. Let's get really dynamic and add our component to all the record pages in the ZBSLightning app. Because everything is better with badges.

  1. In Salesforce, from the App Launcher (App Launcher Icon), find and select ZBSLightning, then click the Shows tab. Select Is Not Null from the list. (If no records appear in the Recently Viewed list, change to the All Shows list.)
  2. Click the gear icon (Gear Icon), then select Edit Page to open the Lightning App Builder.
  3. Drag the IndicatorBadges custom component from the Lightning Components list to the page and place it in the right column.
  4. Click Save.
  5. Click Activate.
  6. Click Assign as Org Default, then click Next and then Save.
  7. Click Back to exit Lightning App Builder and return to the record home page.
    Is Not Null show detail pageLook at what we're finding out about this record by just adding our component! There is a lot going on with this show: it's a ZBS Audience Favorite (which we decided to display as a tomato-colored thermometer/custom97 SLDS icon when setting up our "Audience Favorite" custom metadata record), and it's a Vlog (which we set to be a violet-colored TV). And we can see this immediately, without having to drill into any fields. Let's keep spicing up ZBS.
  8. In Salesforce, click the Syndications tab. Select any record from the list. (If no records appear in the Recently Viewed list, change to the All Syndications list.)
  9. Click the gear icon (Gear Icon), then select Edit Page to open the Lightning App Builder.
  10. Drag the IndicatorBadges custom component from the Lightning Components list to the page and place it in the right column.
  11. Click Save.
  12. Click Activate.
  13. Click Assign as Org Default, then click Next and then Save.
  14. Click Back to exit Lightning App Builder and return to the record home page.

Notice any indicators? Click the Details tab (if it isn't already the active tab) and look at the value of the IsActive field. If the box is unchecked, our component should be empty. In this object context, we see that our component doesn't just communicate complex details about records. It can also help busy ZBS users notice simple, but critical, data quality issues.

But what happens to our component, in its current state, if a user changes some data on a record and we need to display different indicators? (Hint: nothing.) Let's fix that in our next step.

Keep learning for
free!
Sign up for an account to continue.
What’s in it for you?
  • 1 in 4 land a new job
  • 50% receive a promotion or raise
  • 80% learn new technologies that boost their resume
  • 66% say it increases productivity
Source: Trailblazer Community Impact Survey 2019