Skip to content

Instantly share code, notes, and snippets.

@sfcure
Last active October 27, 2020 19:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save sfcure/c2124c546c1e035c4fc07cf2613192e0 to your computer and use it in GitHub Desktop.
Save sfcure/c2124c546c1e035c4fc07cf2613192e0 to your computer and use it in GitHub Desktop.
Lightning Component for Insert/Update Custom Metadata Type Records
<aura:component implements="force:appHostable" controller="CreditCardSettingsController">
<aura:attribute name="data"
type="Object"/>
<aura:attribute name="columns"
type="List"/>
<aura:attribute name="record"
type="Object"/>
<!-- handlers-->
<aura:handler name="init" value="{!this}" action="{!c.init}"/>
<lightning:card variant="Narrow" title="Credit Card Charges" iconName="custom:custom62">
<aura:set attribute="actions">
<lightning:button label="New" title="New" onclick="{! c.handleNewButtonClick }"/>
</aura:set>
<p class="slds-p-horizontal_small">
All Credit Card Charges
</p>
<div style="height: 300px; margin: 10px;">
<lightning:datatable columns="{! v.columns }"
data="{! v.data }"
keyField="id"
onrowaction="{! c.handleRowAction }"
hideCheckboxColumn="true"/>
</div>
</lightning:card>
<div class="ccSetting slds-hide" aura:id="recordPopup" style="height: 340px; ">
<section role="dialog" tabindex="-1" class="slds-modal slds-fade-in-open">
<div class="slds-modal__container">
<header class="slds-modal__header">
<button class="slds-button slds-button_icon slds-modal__close slds-button_icon-inverse" onclick="{!c.handleCancelPopupClick }" title="Close">
<lightning:icon iconName="utility:close" alternativeText="Approved" />
</button>
<h2 class="slds-text-heading_medium slds-hyphenate">Credit Card Charges</h2>
</header>
<div class="slds-modal__content slds-p-around_medium">
<div class="slds-form slds-form_stacked">
<div class="slds-form-element">
<lightning:input name="cardType" label="Card Type" value="{!v.record.MasterLabel}"/>
</div>
<div class="slds-form-element">
<lightning:input type="number" name="ccCharges" step="0.01" label="Credit Card Charges" value="{!v.record.LightningApps__Credit_Card_Charge__c}"/>
</div>
<div class="slds-form-element__control" style="padding-top: 10px;">
<lightning:input type="checkbox" label="Active" name="active" checked="{!v.record.LightningApps__Active__c}"/>
</div>
</div>
</div>
<footer class="slds-modal__footer">
<lightning:button label="Cancel" title="Cancel" onclick="{! c.handleCancelPopupClick }"/>
<lightning:button variant="brand" label="Save" title="Save" onclick="{! c.handleSavePopupClick }" />
</footer>
</div>
</section>
<div class="slds-backdrop slds-backdrop_open"></div>
</div>
</aura:component>
.THIS .slds-scrollable_x {
overflow-y:visible!important;
overflow-x:visible!important;
}
.THIS .slds-scrollable_y {
overflow-y:visible!important;
overflow-x:visible!important;
}
public class CreditCardSettingsController {
// Method which will return a list of all the metadatata records
@AuraEnabled
public static List<Credit_Card_Charge_Setting__mdt> getAllRecords() {
return [ SELECT MasterLabel, Credit_Card_Charge__c, Active__c FROM Credit_Card_Charge_Setting__mdt];
}
@AuraEnabled
public static String saveRecord( Credit_Card_Charge_Setting__mdt metadataRecord ) {
try{
String nameSpacePrefix = '';
// A unique name for developer name
// Replace space with '_'
String recordDevName = metadataRecord.MasterLabel.replaceAll(' ', '_');
// Set up custom metadata to be created in the subscriber org.
Metadata.CustomMetadata customMetadata = new Metadata.CustomMetadata();
customMetadata.fullName = nameSpacePrefix + Credit_Card_Charge_Setting__mdt.' + recordDevName;
customMetadata.label = metadataRecord.MasterLabel;
// Add all the field values
Metadata.CustomMetadataValue customField = new Metadata.CustomMetadataValue();
customField.field = 'Credit_Card_Charge__c';
customField.value = metadataRecord.Credit_Card_Charge__c;
customMetadata.values.add(customField);
customField = new Metadata.CustomMetadataValue();
customField.field = 'Active__c';
customField.value = metadataRecord.Active__c;
customMetadata.values.add(customField);
System.debug( ' >>>> Created custom metadata object >>> ' + customMetadata );
Metadata.DeployContainer mdContainer = new Metadata.DeployContainer();
mdContainer.addMetadata(customMetadata);
// Setup deploy callback, MyDeployCallback implements
// the Metadata.DeployCallback interface
CustomMetadataCallback callback = new CustomMetadataCallback();
// Enqueue custom metadata deployment
// jobId is the deployment ID
Id jobId = Metadata.Operations.enqueueDeployment(mdContainer, callback);
return jobId;
}catch(Exception ex){
System.assert(false,ex.getMessage());
return 'Error while creating new button.';
}
}
}
({
init : function(component, event, helper) {
let rowActions = [{
'label': 'Edit',
'iconName': 'action:edit',
'name': 'edit_record'
}];
let columns = [
{ label: 'Name', fieldName: 'MasterLabel', type: 'text' },
{ label: 'Credit Card Charges', fieldName: 'Credit_Card_Charge__c', type: 'number', typeAttributes: { minimumFractionDigits: 2 } },
{ label: 'Active', fieldName: 'Active__c', type: 'text', cellAttributes: { iconName: { fieldName: 'Active__c' }, iconLabel: { fieldName: 'Active__c' }, iconPosition: 'right' } },
{ type: 'action', typeAttributes: { rowActions: rowActions } }
];
// set the column on component
component.set( "v.columns", columns );
// Get the data from server side action
helper.fetchData( component );
},
handleNewButtonClick: function( component, event, helper ){
// Initialize the record object
component.set( "v.record", {} );
let ele = component.find( "recordPopup" );
$A.util.removeClass( ele, "slds-hide" );
},
handleCancelPopupClick: function( component, event, helper ){
let ele = component.find( "recordPopup" );
$A.util.addClass( ele, "slds-hide" );
},
handleRowAction: function ( component, event, helper ) {
var action = event.getParam('action');
var row = event.getParam('row');
switch (action.name) {
case 'edit_record':
component.set( "v.record", row );
let ele = component.find( "recordPopup" );
$A.util.removeClass( ele, "slds-hide" );
break;
}
},
// For saving custom metadata record
handleSavePopupClick: function( component, event, helper ) {
let record = component.get( "v.record" );
if( record.MasterLabel != null && record.MasterLabel != '' )
helper.saveRecordAsync( component );
else
alert( "Please provided the card type." );
}
})
({
fetchData : function( component ) {
var action = component.get("c.getAllRecords");
action.setCallback( this, function( response ) {
var state = response.getState();
if( state === "SUCCESS") {
console.log( response.getReturnValue() );
component.set( "v.data", response.getReturnValue() );
}
else if (state === "INCOMPLETE") {
alert('Error in the response');
}
else if (state === "ERROR") {
var errors = response.getError();
if (errors) {
if (errors[0] && errors[0].message) {
console.log("Error message: " +
errors[0].message);
}
} else {
console.log("Unknown error");
}
}
});
$A.enqueueAction( action );
},
saveRecordAsync: function( component ) {
let action = component.get("c.saveRecord");
action.setParam( "metadataRecord", component.get("v.record") );
component.set( "v.record", {} );
let ele = component.find( "recordPopup" );
$A.util.addClass( ele, "slds-hide" );
action.setCallback( this, function( response ) {
var state = response.getState();
if( state === "SUCCESS") {
console.log( response.getReturnValue() );
var toastEvent = $A.get("e.force:showToast");
toastEvent.setParams({
mode: 'sticky',
message: 'This is a required message',
messageTemplate: 'Your request has been submitted. Click {0} to track the progress.',
messageTemplateData: [{
url: '/changemgmt/monitorDeploymentsDetails.apexp?asyncId=' + response.getReturnValue(),
label: 'Deployment Status',
}
]
});
toastEvent.fire();
}
else if (state === "INCOMPLETE") {
alert('Error in the response');
}
else if (state === "ERROR") {
var errors = response.getError();
if (errors) {
if (errors[0] && errors[0].message) {
console.log("Error message: " +
errors[0].message);
}
} else {
console.log("Unknown error");
}
}
});
$A.enqueueAction( action );
},
})
public class CustomMetadataCallback implements Metadata.DeployCallback {
public void handleResult(Metadata.DeployResult result,
Metadata.DeployCallbackContext context) {
if (result.status == Metadata.DeployStatus.Succeeded) {
System.debug('success: '+ result);
} else {
// Deployment was not successful
System.debug('fail: '+ result);
}
}
}
@NagaSwetha2
Copy link

I am getting "Unable to read sobject" error for saveRecordAsync while I am editing custom metadata records. serialize/deserialize and setting sobject type in lightning component workarounds did not work out. Do you have any suggestions for that error?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment