You need to sign in to do that
Don't have an account?
Moshe Baitelman
Adding Lightning component breaks community builder
I have a custom lightning component. It works fine in almost all instances I choose to use it. The functionality is fine. It works in apps, on record page, etc.
When I add the component to the layout of a communities page in the Community Builder, the builder breaks.
This happens before the Init handler is called and everything works when I use lightning app builder so it is unrelated to the controller but I have included that code as well.
To Replicate:
Go to Communities > Choose a community builder > Create a new page (any layout) > Add in the Custom Component (code shown below).
The moment you do so, the container where you placed the component disappears and cannot be reached again. This means I am unable to make changes to the design resources, delete the component, move the component, etc.
Can't figure out for the life of me why. Salesforce error on reload is highly uninformative.
Before adding component:
After adding component:
After page reload:
Component Code:
Component Helper
Design
Apex Controller
When I add the component to the layout of a communities page in the Community Builder, the builder breaks.
This happens before the Init handler is called and everything works when I use lightning app builder so it is unrelated to the controller but I have included that code as well.
To Replicate:
Go to Communities > Choose a community builder > Create a new page (any layout) > Add in the Custom Component (code shown below).
The moment you do so, the container where you placed the component disappears and cannot be reached again. This means I am unable to make changes to the design resources, delete the component, move the component, etc.
Can't figure out for the life of me why. Salesforce error on reload is highly uninformative.
Before adding component:
After adding component:
After page reload:
Component Code:
<aura:component description="PriorityOrdersList" implements="force:appHostable,flexipage:availableForAllPageTypes,forceCommunity:availableForAllPageTypes,lightning:availableForFlowScreens" access="global" controller="priorityOrdersListController" > <!-- handlers--> <aura:handler name="init" value="{! this }" action="{! c.init }"/> <aura:handler name="modalClosed" event="c:rsModalClosed" action="{!c.onModalClosed}"/> <!-- attributes --> <aura:attribute name="listStatus" type="String" access="public" default="Waiting" /> <aura:attribute name="orderData" access="private" type="Object" /> <aura:attribute name="columns" type="List" access="private" /> <aura:attribute name="sortOrder" type="String" required="true" default="rw_Priority__c" /> <aura:attribute name="urlSeed" type="String" required="true" default="https://rlscn.force.com/WMS/s/packing" /> <aura:attribute name="isLoading" type="Boolean" access="private" default="true" /> <aura:attribute name="isModalOpen" type="boolean" access="private" required="false" /> <aura:attribute name="modalMessage" type="string" access="private" required="false" /> <lightning:card class="slds-card__body slds-card__body_inner"> <div style="height: 200px;"> This is here just to give height to the component and create visibility. </div> <aura:if isTrue="{! not(v.isLoading) }"> <aura:if isTrue="{!v.orderData}"> <!-- the container element determines height of the datatable --> <h1 class="slds-m-vertical_small">Orders to fulfill (temporary interface)</h1> <lightning:button label="Refresh List" onclick="{! c.refreshOrders}" iconName="utility:refresh" iconPosition="right"/> <div style="height: auto"> <lightning:datatable columns="{! v.columns }" data="{! v.orderData }" keyField="Id" hideCheckboxColumn="true" onrowaction="{! c.handleRowAction }"/> </div> <aura:set attribute="else"> <div class="slds-box slds-p-around_small slds-m-vertical_medium"> <i>Hooray! You've fulfilled all the orders!</i> </div> </aura:set> </aura:if> <aura:set attribute="else"> <lightning:spinner variant="brand" size="medium" alternativeText="Loading..."/> </aura:set> </aura:if> </lightning:card> <!-- Only display Modal if there is not a blocking operation taking place. --> <c:rsModal aura:id="modal" isOpen="{!v.isModalOpen}"> <aura:unescapedHtml value="{!v.modalMessage}"/> </c:rsModal> </aura:component>
({ init: function (cmp, event, helper) { cmp.set('v.columns', [ {label: 'Order', fieldName: 'Name'}, {label: 'Customer', fieldName: 'Account_Owner_for_Sharing_2__c'}, {label: 'Brand ', fieldName: 'Brand_RL__c'}, {label: 'Order Number', fieldName: 'rw_Customer_Order__c'}, {label: 'Priority', fieldName: 'rw_Priority__c'}, {label: 'Order Date', fieldName: 'Order_Date__c'}, { label: 'Fulfill', type: 'button', typeAttributes: { label: 'Fulfill', name: 'fulfill', title: 'Click to fulfill this order', disabled: {fieldName: 'unfillable'} } } ]); if (cmp.get("v.listStatus") == 'Waiting') { helper.getOrders(cmp); } else { let message = 'Unknown error'; console.log(message + ': Did not call for orders.'); } }, refreshOrders: function (cmp, event, helper) { cmp.set("v.isLoading", true); helper.getOrders(cmp); }, handleRowAction: function (cmp, event, helper) { var action = event.getParam('action'); var row = event.getParam('row'); switch (action.name) { case 'fulfill': helper.launchScanner(cmp, row.Id); helper.disableRow(cmp, row); break; } }, // To Close Modal onModalClosed: function (cmp, event, helper) { cmp.set('v.modalMessage', null); cmp.set('v.isModalOpen', false); } });
Component Helper
{ getOrders: function (cmp) { var helper = this; var action = cmp.get('c.getOrderPriorityList'); var sortOrder = cmp.get('v.sortOrder'); action.setParams({sortOrder: sortOrder}); action.setCallback(helper, function (response) { var state = response.getState(); if (state === "SUCCESS") { var orderList = response.getReturnValue(); if(orderList.length > 0) { var rows = response.getReturnValue(); //storing the response in a temporary variable //looping through each row of the result for (var i = 0; i < rows.length; i++) { var row = rows[i]; // data columns with relationship __r can not be displayed directly in data table, so generating dynamic columns row.unfillable = false; } orderList = response.getReturnValue(); cmp.set("v.orderData", orderList); } } else if (state === "ERROR") { let errors = response.getError(); let message = 'Unknown error'; // Default error message // Retrieve the error message sent by the server if (errors && Array.isArray(errors) && errors.length > 0) { message = errors[0].message; } // Display the message this.alert( cmp, 'Error Fetching Data', message, 'error', false ); } else { console.log("Failed with state: " + state); } cmp.set("v.isLoading", false); cmp.set("v.listStatus", 'DataReady') }); // Send actions to be executed $A.enqueueAction(action); }, launchScanner: function (cmp, orderId) { var pageUrl = cmp.get("v.urlSeed"); window.open(pageUrl + "?recordId=" + orderId); }, disableRow: function(cmp, row) { var data = cmp.get('v.orderData'); var rowIndex = data.indexOf(row); data[rowIndex].unfillable = true; cmp.set('v.orderData', data); }, getModalCmp: function(cmp, isRequired) { return this.getCmp(cmp, 'modal', isRequired); }, getCmp: function(cmp, auraId, isRequired) { if(isRequired === undefined) { isRequired = true; } var output = cmp.find(auraId); if(isRequired && !output) { throw new Error('Could not find component with Aura ID: '+auraId); } return output; }, alert: function(cmp, title, message, theme, hideCloseButton) { var modalCmp = this.getModalCmp(cmp); if(hideCloseButton === undefined) { hideCloseButton = false; } if(modalCmp) { var messageEscaped = this.escapeHtml(message); var messageHtml = messageEscaped.replace(/\n/g, '<br />'); cmp.set('v.isModalOpen', false); cmp.set('v.modalMessage', messageHtml); modalCmp.set('v.hideDefaultCloseControls', hideCloseButton); modalCmp.set('v.variant', 'alert'); modalCmp.set('v.title', title); modalCmp.set('v.theme', theme || 'default'); cmp.set('v.isModalOpen', true); } else { cmp.set('v.modalMessage', message); alert(message); } }, escapeHtml: function(text) { // Copied from://stackoverflow.com/a/4835406 var map = { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }; return text.replace( /[&<>\x22\x27]/g, function(m) { return map[m]; } ); } })
Design
<design:component> <design:attribute name="sortOrder" description="Fields by which to sort the orders" default="Order_Date__c, rw_Priority__c" required="true" label="Sort ORDER BY" /> <design:attribute name="urlSeed" description="URL to append the RecordID to when initiating the packing interface" default="https://rlscn.force.com/WMS/s/packing" required="true" label="Base URL" /> </design:component>
Apex Controller
public with sharing class priorityOrdersListController { @AuraEnabled public static List<rw_Shipment__c> getOrderPriorityList(String sortOrder) { try { String queryString = 'SELECT Id, Name, rw_Status__c, Warehouse_Status__c, CreatedDate, ' + 'Account_Owner_for_Sharing_2__c, Brand_RL__c, Brand_RL__r.Name, rw_Customer_Order__c, rw_Priority__c, Order_Date__c ' + 'FROM rw_Shipment__c ' + 'WHERE rw_Status__c = \'SAVED\' AND ' + '(Warehouse_Status__c = \'Allocated\' ' + 'OR Warehouse_Status__c = \'Picking Slip Generated\' ' + 'OR Warehouse_Status__c = \'Packing Slip Generated\') ' + 'ORDER BY '+ sortorder + ' LIMIT 50'; List<rw_Shipment__c> orderPriorityList = database.query(queryString); return orderPriorityList; } catch (Exception ex) { throw new AuraHandledException('No orders found found matching ' + ex.getMessage()); } } }
I dove deeper on this. lightning:card needs to have the title attribute. Without it, it causes this error.
Adding the title attribute solves this. If you are looking to use card for body styling only and do not want to display a title, you can do as Thuy suggests above.
All Answers
I ran into this exact problem too, and what solved it for me was eliminating the <lightning:card> tags. I was using it for styling purposes and was really interested in just using the body portion of the lightning:card. I replaced <lightning:card> with <div class="slds-media__body">, and Community Builder is working now and the component displays with the correct styling.
I referred to https://www.lightningdesignsystem.com/components/cards/ for the appropriate HTML and SLDS classes for styling.
Hope this helps you!
I dove deeper on this. lightning:card needs to have the title attribute. Without it, it causes this error.
Adding the title attribute solves this. If you are looking to use card for body styling only and do not want to display a title, you can do as Thuy suggests above.