My use case is to have a button inside a Salesforce Napili Community, which updates the Case.Status field of the record displayed
The logic for the button should be quite simple:
- IF Case.IsClosed = 'True' – button text to read "Closed" – button disabled
- IF Case.Status = 'New' or 'Awaiting Customer' – button text to read "Submit" – on click updates Case.Status to 'Submitted'
- ELSE button text to read "Withdraw Case" – on click updates Case.Status to 'Withdrawn'
I have been struggling with creating this Lightning Component / Apex class with no luck, so thought I'd reach out to see if anyone can help at all? (Please)
Unfortunately I am not a developer so swimming in the deep end. My current code currently doesn't even let me put the button on the Community page as I get the error "Unable to parse JSON response" so it's very wrong.
Component
<aura:component controller="UpdateCaseStatusController_LC" implements="forceCommunity:availableForAllPageTypes" access="global" >
<aura:handler name="init" value="{!this}" action="{!c.init}"/>
<aura:attribute name="case" type="Case"/>
<aura:attribute name="recordId" type="String"/>
<ui:button aura:id="mybtn" class="slds-button slds-button--brand slds-size--1-of-1" label="{!v.case.Status}" press="{!c.onclick}" disabled="{!v.case.IsClosed == true ? 'true' : 'false'}"/>
</aura:component>
Controller:
({
init : function(component, event, helper) {
var action = component.get("c.getCase");
action.setParams({"recordId": component.get("v.recordId")});
action.setCallback(this, function(response) {
var state = response.getState();
if(component.isValid() && state == "SUCCESS"){
var c = response.getReturnValue();
component.set("v.case", c);
window.setTimeout(
$A.getCallback(function () {
var button = component.find("mybtn");
if(c.Status == "New" || c.Status == "Awaiting Customer"){
button.set("v.label","Submit");
}else if(c.Status == "Closed"){
button.set("v.label","Closed");
}else {
button.set("v.label","Withdraw Case");
}
})
);
} else {
console.log('There was a problem : '+response.getError());
}
});
$A.enqueueAction(action);
},
onclick : function(component, event, helper) {
var action = component.get("c.saveCase");
action.setParams({"recordId": component.get("v.recordId")});
if (callback) {
action.setCallback(this, callback);
}
$A.enqueueAction(action);
}
})
Apex:
public class UpdateCaseStatusController_LC {
@AuraEnabled
public static Case getCase(Id recordId){
Case caseRec = [SELECT Id, isClosed, Status FROM Case WHERE id=:recordId];
return caseRec;
}
@AuraEnabled
public static Case saveCase(Id recordId){
Case caseRec = [SELECT Id, Status FROM Case WHERE id=:recordId];
if (caseRec.Status == 'New' || caseRec.Status == 'Awaiting Customer') {
caseRec.Status = 'Submitted';
} else {
caseRec.Status = 'Withdrawn';
}
update caseRec;
return caseRec;
}}
Best Answer
A couple of things, Your getCase method returns an object of type "case", But, you are setting the object to a String in the init method of your js Controller.Additionally, as N.B pointed out, you seem to be passing 2 arguments when your apex method saveCase is expecting only one argument of type case.
Below is a refined version of your logic for your use-case. I have hard-coded "recordId" for demo purposes, do modify as required. And I notice that you have used individual aura:attributes for properties such as Status and Closed. Instead we ought to use compound attributes such as Object or Array of Objects for better logic.
Component:
We could have used aura:if for conditional rendering of status just like how we have used for "disabled" attribute. However extensive usage of aura:if is not recommended. Hence we will do our conditional checks in JS Controllers.
Apex Controller :
Controller.js :
We will require window.setTimeout to provide small delay during the aura render cycle. If not the updated values will not reflect in the DOM.
Results :
When Status is new, the button text is set to "Submit"
Status anything other than New or Awaiting Customer, the text is set to "Withdraw Case"
Status Changed to Closed
Button Disabled in the Community and Status changed to closed
Update :
Change the methods below as shown and your save method should work during onclick.
Apex Controller :
I have changed the parameter from RecordId to caseRec as to avoid an additional database query.
Controller.js :
The other components do not require any change. The status would display as expected.
Results :
When status is set to working
The status is set to Withdraw case in community :
When you click on withdraw case, the button text and case status change to "Withdrawn"